From 9158e17997db0a21a27774a66b944539f4ef441a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 15 Dec 2019 09:42:09 +0100 Subject: [PATCH 0001/1253] Document more use cases of dataflow --- src/librustc_mir/dataflow/mod.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index ad0f75d772548..af16adf9eb32f 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -650,6 +650,20 @@ pub trait BottomValue { const BOTTOM_VALUE: bool; /// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed. + /// + /// You usually don't need to override this, since it automatically applies + /// * `inout_set & in_set` if `BOTTOM_VALUE == true` + /// * `inout_set | in_set` if `BOTTOM_VALUE == false` + /// + /// This means that if a bit is not `BOTTOM_VALUE`, it is propagated into all target blocks. + /// For clarity, the above statement again from a different perspective: + /// A block's initial bit value is `!BOTTOM_VALUE` if *any* predecessor block's bit value is + /// `!BOTTOM_VALUE`. + /// There are situations where you want the opposite behaviour: propagate only if *all* + /// predecessor blocks's value is `!BOTTOM_VALUE`. In that case you need to + /// 1. Invert `BOTTOM_VALUE` + /// 2. Reset the `entry_set` in `start_block_effect` to `!BOTTOM_VALUE` + /// 3. Override `join` to do the opposite from what it's doing now. #[inline] fn join(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { if Self::BOTTOM_VALUE == false { @@ -667,7 +681,9 @@ pub trait BottomValue { /// for each block individually. The entry set for all other basic blocks is /// initialized to `Self::BOTTOM_VALUE`. The dataflow analysis then /// iteratively modifies the various entry sets (but leaves the the transfer -/// function unchanged). +/// function unchanged). `BottomValue::join` is used to merge the bitsets from +/// two blocks (e.g. when two blocks' terminator jumps to a single block, that +/// target block's state is the merged state of both incoming blocks). pub trait BitDenotation<'tcx>: BottomValue { /// Specifies what index type is used to access the bitvector. type Idx: Idx; From c842f02dee81e52f3b63a8b46021a8e18f143a7e Mon Sep 17 00:00:00 2001 From: cad97 Date: Sun, 15 Dec 2019 17:59:09 -0500 Subject: [PATCH 0002/1253] Use pointer offset instead of deref for A/Rc::into_raw --- src/liballoc/rc.rs | 9 +++++++-- src/liballoc/sync.rs | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1ff1c3c834f4e..0205c40829930 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -571,9 +571,14 @@ impl Rc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr: *const T = &*this; + let ptr: *mut RcBox = NonNull::as_ptr(this.ptr); + let fake_ptr = ptr as *mut T; mem::forget(this); - ptr + + unsafe { + let offset = data_offset(&(*ptr).value); + set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) + } } /// Constructs an `Rc` from a raw pointer. diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 19b0086fa333c..de56cb300d38c 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -551,9 +551,14 @@ impl Arc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr: *const T = &*this; + let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); + let fake_ptr = ptr as *mut T; mem::forget(this); - ptr + + unsafe { + let offset = data_offset(&(*ptr).data); + set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) + } } /// Constructs an `Arc` from a raw pointer. From eb77f7ec6e9460c1ca70fbb7bb655f1a0a1bacfc Mon Sep 17 00:00:00 2001 From: CAD97 Date: Tue, 17 Dec 2019 15:52:13 -0500 Subject: [PATCH 0003/1253] Add internal safety docs to (A)Rc::into_raw --- src/liballoc/rc.rs | 5 +++++ src/liballoc/sync.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0205c40829930..8c70b0a913a98 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -575,6 +575,11 @@ impl Rc { let fake_ptr = ptr as *mut T; mem::forget(this); + // SAFETY: This cannot go through Deref::deref. + // Instead, we manually offset the pointer rather than manifesting a reference. + // This is so that the returned pointer retains the same provenance as our pointer. + // This is required so that e.g. `get_mut` can write through the pointer + // after the Rc is recovered through `from_raw`. unsafe { let offset = data_offset(&(*ptr).value); set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index de56cb300d38c..5c1fa17a626d1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -555,6 +555,11 @@ impl Arc { let fake_ptr = ptr as *mut T; mem::forget(this); + // SAFETY: This cannot go through Deref::deref. + // Instead, we manually offset the pointer rather than manifesting a reference. + // This is so that the returned pointer retains the same provenance as our pointer. + // This is required so that e.g. `get_mut` can write through the pointer + // after the Arc is recovered through `from_raw`. unsafe { let offset = data_offset(&(*ptr).data); set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) From 5f08df104742ce400e966f6cd80c9029f0328922 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 20 Dec 2019 19:46:38 +0100 Subject: [PATCH 0004/1253] Address review comments --- src/librustc_mir/dataflow/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index af16adf9eb32f..3f810472c6465 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -651,16 +651,22 @@ pub trait BottomValue { /// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed. /// - /// You usually don't need to override this, since it automatically applies + /// It is almost certainly wrong to override this, since it automatically applies /// * `inout_set & in_set` if `BOTTOM_VALUE == true` /// * `inout_set | in_set` if `BOTTOM_VALUE == false` /// /// This means that if a bit is not `BOTTOM_VALUE`, it is propagated into all target blocks. /// For clarity, the above statement again from a different perspective: - /// A block's initial bit value is `!BOTTOM_VALUE` if *any* predecessor block's bit value is + /// A bit in the block's entry set is `!BOTTOM_VALUE` if *any* predecessor block's bit value is /// `!BOTTOM_VALUE`. + /// /// There are situations where you want the opposite behaviour: propagate only if *all* - /// predecessor blocks's value is `!BOTTOM_VALUE`. In that case you need to + /// predecessor blocks's value is `!BOTTOM_VALUE`. + /// E.g. if you want to know whether a bit is *definitely* set at a specific location. This + /// means that all code paths leading to the location must have set the bit, instead of any + /// code path leading there. + /// + /// If you want this kind of "definitely set" analysis, you need to /// 1. Invert `BOTTOM_VALUE` /// 2. Reset the `entry_set` in `start_block_effect` to `!BOTTOM_VALUE` /// 3. Override `join` to do the opposite from what it's doing now. From a20013b129c10907aee0bfb5bf1cac387e48eb51 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Sat, 2 Nov 2019 20:13:32 +0200 Subject: [PATCH 0005/1253] Add Result::unwrap_infallible Implementation of https://github.com/rust-lang/rfcs/pull/2799 --- src/libcore/result.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index fb4dc62d8c176..ed3b37ad2a57b 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1083,6 +1083,44 @@ impl Result { } } +#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")] +impl> Result { + /// Unwraps a result that can never be an [`Err`], yielding the content of the [`Ok`]. + /// + /// Unlike [`unwrap`], this method is known to never panic on the + /// result types it is implemented for. Therefore, it can be used + /// instead of `unwrap` as a maintainability safeguard that will fail + /// to compile if the error type of the `Result` is later changed + /// to an error that can actually occur. + /// + /// [`Ok`]: enum.Result.html#variant.Ok + /// [`Err`]: enum.Result.html#variant.Err + /// [`unwrap`]: enum.Result.html#method.unwrap + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(never_type)] + /// # #![feature(unwrap_infallible)] + /// + /// fn only_good_news() -> Result { + /// Ok("this is fine".into()) + /// } + /// + /// let s: String = only_good_news().unwrap_infallible(); + /// println!("{}", s); + /// ``` + #[inline] + pub fn unwrap_infallible(self) -> T { + match self { + Ok(x) => x, + Err(e) => e.into(), + } + } +} + #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E>`. From 9a99a2159bb57ee0f1a52bb3f989a903df2f8cb4 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Sat, 2 Nov 2019 22:12:51 +0200 Subject: [PATCH 0006/1253] libcore: test Result::unwrap_infallible --- src/libcore/tests/lib.rs | 2 ++ src/libcore/tests/result.rs | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1f20ebc01e993..4656024241804 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -39,6 +39,8 @@ #![feature(slice_from_raw_parts)] #![feature(const_slice_from_raw_parts)] #![feature(const_raw_ptr_deref)] +#![feature(never_type)] +#![feature(unwrap_infallible)] extern crate test; diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 163f8d0ab3797..8d17790af5620 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -197,6 +197,28 @@ pub fn test_unwrap_or_default() { assert_eq!(op2().unwrap_or_default(), 0); } +#[test] +pub fn test_unwrap_infallible() { + fn infallible_op() -> Result { + Ok(666) + } + + assert_eq!(infallible_op().unwrap_infallible(), 666); + + enum MyNeverToken {} + impl From for ! { + fn from(never: MyNeverToken) -> ! { + match never {} + } + } + + fn infallible_op2() -> Result { + Ok(667) + } + + assert_eq!(infallible_op2().unwrap_infallible(), 667); +} + #[test] fn test_try() { fn try_result_some() -> Option { From 6f0672c08b7609c7ed77245a3feea3040221b804 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Mon, 4 Nov 2019 14:05:15 +0200 Subject: [PATCH 0007/1253] Rename Result::unwrap_infallible to into_ok --- src/libcore/result.rs | 4 ++-- src/libcore/tests/result.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index ed3b37ad2a57b..ea2dd77f4efbb 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1109,11 +1109,11 @@ impl> Result { /// Ok("this is fine".into()) /// } /// - /// let s: String = only_good_news().unwrap_infallible(); + /// let s: String = only_good_news().into_ok(); /// println!("{}", s); /// ``` #[inline] - pub fn unwrap_infallible(self) -> T { + pub fn into_ok(self) -> T { match self { Ok(x) => x, Err(e) => e.into(), diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 8d17790af5620..cac15a6b32414 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -198,12 +198,12 @@ pub fn test_unwrap_or_default() { } #[test] -pub fn test_unwrap_infallible() { +pub fn test_into_ok() { fn infallible_op() -> Result { Ok(666) } - assert_eq!(infallible_op().unwrap_infallible(), 666); + assert_eq!(infallible_op().into_ok(), 666); enum MyNeverToken {} impl From for ! { @@ -216,7 +216,7 @@ pub fn test_unwrap_infallible() { Ok(667) } - assert_eq!(infallible_op2().unwrap_infallible(), 667); + assert_eq!(infallible_op2().into_ok(), 667); } #[test] From 293cdf7ac5d14811debdec3408afde104935caef Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Thu, 21 Nov 2019 22:09:10 -0500 Subject: [PATCH 0008/1253] Make RangeMut::next_unchecked() output a mutable key reference --- src/liballoc/collections/btree/map.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 7d0a862d79e48..e25a5e0773ec6 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1328,7 +1328,10 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { None } else { self.length -= 1; - unsafe { Some(self.range.next_unchecked()) } + unsafe { + let (k, v) = self.range.next_unchecked(); + Some((k, v)) // coerce k from `&mut K` to `&K` + } } } @@ -1707,7 +1710,14 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option<(&'a K, &'a mut V)> { - if self.front == self.back { None } else { unsafe { Some(self.next_unchecked()) } } + if self.front == self.back { + None + } else { + unsafe { + let (k, v) = self.next_unchecked(); + Some((k, v)) // coerce k from `&mut K` to `&K` + } + } } fn last(mut self) -> Option<(&'a K, &'a mut V)> { @@ -1716,7 +1726,7 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { } impl<'a, K, V> RangeMut<'a, K, V> { - unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) { + unsafe fn next_unchecked(&mut self) -> (&'a mut K, &'a mut V) { let handle = ptr::read(&self.front); let mut cur_handle = match handle.right_kv() { @@ -1724,8 +1734,7 @@ impl<'a, K, V> RangeMut<'a, K, V> { self.front = ptr::read(&kv).right_edge(); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. - let (k, v) = kv.into_kv_mut(); - return (k, v); // coerce k from `&mut K` to `&K` + return kv.into_kv_mut(); } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1739,8 +1748,7 @@ impl<'a, K, V> RangeMut<'a, K, V> { self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend()); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. - let (k, v) = kv.into_kv_mut(); - return (k, v); // coerce k from `&mut K` to `&K` + return kv.into_kv_mut(); } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); From f547978392872684085c96a3d5c1d00bad24b724 Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Fri, 22 Nov 2019 14:22:06 -0500 Subject: [PATCH 0009/1253] Implement clone_from for BTree collections --- src/liballoc/collections/btree/map.rs | 54 +++++++++++++++++++++++++++ src/liballoc/collections/btree/set.rs | 13 ++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index e25a5e0773ec6..12174ffcbfa42 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -207,6 +207,60 @@ impl Clone for BTreeMap { clone_subtree(self.root.as_ref()) } } + + fn clone_from(&mut self, other: &Self) { + BTreeClone::clone_from(self, other); + } +} + +trait BTreeClone { + fn clone_from(&mut self, other: &Self); +} + +impl BTreeClone for BTreeMap { + default fn clone_from(&mut self, other: &Self) { + *self = other.clone(); + } +} + +impl BTreeClone for BTreeMap { + fn clone_from(&mut self, other: &Self) { + // This truncates `self` to `other.len()` by calling `split_off` on + // the first key after `other.len()` elements if it exists + if let Some(key) = { + if self.len() > other.len() { + let diff = self.len() - other.len(); + if diff <= other.len() { + self.iter().nth_back(diff - 1).map(|pair| (*pair.0).clone()) + } else { + self.iter().nth(other.len()).map(|pair| (*pair.0).clone()) + } + } else { + None + } + } { + self.split_off(&key); + } + let mut siter = self.range_mut(..); + let mut oiter = other.iter(); + // After truncation, `self` is at most as long as `other` so this loop + // replaces every key-value pair in `self`. Since `oiter` is in sorted + // order and the structure of the `BTreeMap` stays the same, + // the BTree invariants are maintained at the end of the loop + while siter.front != siter.back { + if let Some((ok, ov)) = oiter.next() { + // This is safe because the `siter.front != siter.back` check + // ensures that `siter` is nonempty + let (sk, sv) = unsafe { siter.next_unchecked() }; + sk.clone_from(ok); + sv.clone_from(ov); + } else { + break; + } + } + // If `other` is longer than `self`, the remaining elements are inserted + self.extend(oiter.map(|(k, v)| ((*k).clone(), (*v).clone()))); + } } impl super::Recover for BTreeMap diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 282d163141bc8..5bdefe5cecf1b 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -56,12 +56,23 @@ use crate::collections::btree_map::{self, BTreeMap, Keys}; /// println!("{}", book); /// } /// ``` -#[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] +#[derive(Hash, PartialEq, Eq, Ord, PartialOrd)] #[stable(feature = "rust1", since = "1.0.0")] pub struct BTreeSet { map: BTreeMap, } +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for BTreeSet { + fn clone(&self) -> Self { + BTreeSet { map: self.map.clone() } + } + + fn clone_from(&mut self, other: &Self) { + self.map.clone_from(&other.map); + } +} + /// An iterator over the items of a `BTreeSet`. /// /// This `struct` is created by the [`iter`] method on [`BTreeSet`]. From 8651aa066fdbbcfaa082531969469c3fa289de9e Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Fri, 22 Nov 2019 14:22:45 -0500 Subject: [PATCH 0010/1253] Add test for BTreeMap::clone_from --- src/liballoc/tests/btree/map.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 3177f19927eda..65a3fbd66a4c2 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -554,6 +554,26 @@ fn test_clone() { } } +#[test] +fn test_clone_from() { + let mut map1 = BTreeMap::new(); + let size = 30; + + for i in 0..size { + map1.insert(i, 10 * i); + let mut map2 = BTreeMap::new(); + for j in 0..i { + map2.insert(100 * j + 1, 2 * j + 1); + let mut map1_copy = map2.clone(); + map1_copy.clone_from(&map1); + assert_eq!(map1_copy, map1); + let mut map2_copy = map1.clone(); + map2_copy.clone_from(&map2); + assert_eq!(map2_copy, map2); + } + } +} + #[test] #[allow(dead_code)] fn test_variance() { From 3b92689f3d0c3b90fa01d9873cdf01543d51c000 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 13:54:33 -0500 Subject: [PATCH 0011/1253] Relax bounds on HashMap to match hashbrown No functional changes are made, and all APIs are moved to strictly less restrictive bounds. These APIs changed from the old bound listed to no trait bounds: K: Hash + Eq * new * with_capacity K: Eq + Hash, S: BuildHasher * with_hasher * with_capacity_and_hasher * hasher K: Eq + Hash + Debug -> K: Debug S: BuildHasher -> S K: Eq + Hash -> K S: BuildHasher + Default -> S: Default --- src/libstd/collections/hash/map.rs | 126 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index a928867d9de93..84e1cee5d66b9 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -203,7 +203,7 @@ pub struct HashMap { base: base::HashMap, } -impl HashMap { +impl HashMap { /// Creates an empty `HashMap`. /// /// The hash map is initially created with a capacity of 0, so it will not allocate until it @@ -240,6 +240,59 @@ impl HashMap { } impl HashMap { + /// Creates an empty `HashMap` which will use the given hash builder to hash + /// keys. + /// + /// The created map has the default initial capacity. + /// + /// Warning: `hash_builder` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_hasher(s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_hasher(hash_builder: S) -> HashMap { + HashMap { base: base::HashMap::with_hasher(hash_builder) } + } + + /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` + /// to hash the keys. + /// + /// The hash map will be able to hold at least `capacity` elements without + /// reallocating. If `capacity` is 0, the hash map will not allocate. + /// + /// Warning: `hash_builder` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_capacity_and_hasher(10, s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap { + HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) } + } + /// Returns the number of elements the map can hold without reallocating. /// /// This number is a lower bound; the `HashMap` might be able to hold @@ -457,65 +510,6 @@ impl HashMap { pub fn clear(&mut self) { self.base.clear(); } -} - -impl HashMap -where - K: Eq + Hash, - S: BuildHasher, -{ - /// Creates an empty `HashMap` which will use the given hash builder to hash - /// keys. - /// - /// The created map has the default initial capacity. - /// - /// Warning: `hash_builder` is normally randomly generated, and - /// is designed to allow HashMaps to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// use std::collections::hash_map::RandomState; - /// - /// let s = RandomState::new(); - /// let mut map = HashMap::with_hasher(s); - /// map.insert(1, 2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_hasher(hash_builder: S) -> HashMap { - HashMap { base: base::HashMap::with_hasher(hash_builder) } - } - - /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` - /// to hash the keys. - /// - /// The hash map will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash map will not allocate. - /// - /// Warning: `hash_builder` is normally randomly generated, and - /// is designed to allow HashMaps to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// use std::collections::hash_map::RandomState; - /// - /// let s = RandomState::new(); - /// let mut map = HashMap::with_capacity_and_hasher(10, s); - /// map.insert(1, 2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap { - HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) } - } /// Returns a reference to the map's [`BuildHasher`]. /// @@ -536,7 +530,13 @@ where pub fn hasher(&self) -> &S { self.base.hasher() } +} +impl HashMap +where + K: Eq + Hash, + S: BuildHasher, +{ /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashMap`. The collection may reserve more space to avoid /// frequent reallocations. @@ -984,9 +984,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl Debug for HashMap where - K: Eq + Hash + Debug, + K: Debug, V: Debug, - S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() @@ -996,8 +995,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl Default for HashMap where - K: Eq + Hash, - S: BuildHasher + Default, + S: Default, { /// Creates an empty `HashMap`, with the `Default` value for the hasher. #[inline] From 207e60a364a23e15261f4fdd6471907d4fa906f4 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 5 Dec 2019 18:58:56 -0800 Subject: [PATCH 0012/1253] Stabilize Condvar::wait_until and wait_timeout_until --- src/libstd/sync/condvar.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 5a4cb14b72d62..62bf0125c3692 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -228,8 +228,6 @@ impl Condvar { /// # Examples /// /// ``` - /// #![feature(wait_until)] - /// /// use std::sync::{Arc, Mutex, Condvar}; /// use std::thread; /// @@ -249,7 +247,7 @@ impl Condvar { /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` - #[unstable(feature = "wait_until", issue = "47960")] + #[stable(feature = "wait_until", since = "1.42.0")] pub fn wait_until<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -433,8 +431,6 @@ impl Condvar { /// # Examples /// /// ``` - /// #![feature(wait_timeout_until)] - /// /// use std::sync::{Arc, Mutex, Condvar}; /// use std::thread; /// use std::time::Duration; @@ -462,7 +458,7 @@ impl Condvar { /// } /// // access the locked mutex via result.0 /// ``` - #[unstable(feature = "wait_timeout_until", issue = "47960")] + #[stable(feature = "wait_timeout_until", since = "1.42.0")] pub fn wait_timeout_until<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -613,7 +609,6 @@ impl Drop for Condvar { #[cfg(test)] mod tests { use crate::sync::atomic::{AtomicBool, Ordering}; - /// #![feature(wait_until)] use crate::sync::mpsc::channel; use crate::sync::{Arc, Condvar, Mutex}; use crate::thread; From 98d054af08017e4b7f68c4985b1ed821b845fc00 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 16 Dec 2019 13:55:08 -0800 Subject: [PATCH 0013/1253] Rename wait_until/wait_timeout_until to wait_while/white_timeout_while --- src/libstd/sync/condvar.rs | 68 ++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 62bf0125c3692..77e521eae9afe 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -204,9 +204,7 @@ impl Condvar { } /// Blocks the current thread until this condition variable receives a - /// notification and the required condition is met. Spurious wakeups are - /// ignored and this function will only return once the condition has been - /// met. + /// notification and the provided condition is false. /// /// This function will atomically unlock the mutex specified (represented by /// `guard`) and block the current thread. This means that any calls @@ -231,24 +229,24 @@ impl Condvar { /// use std::sync::{Arc, Mutex, Condvar}; /// use std::thread; /// - /// let pair = Arc::new((Mutex::new(false), Condvar::new())); + /// let pair = Arc::new((Mutex::new(true), Condvar::new())); /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { /// let (lock, cvar) = &*pair2; - /// let mut started = lock.lock().unwrap(); - /// *started = true; + /// let mut pending = lock.lock().unwrap(); + /// *pending = false; /// // We notify the condvar that the value has changed. /// cvar.notify_one(); /// }); /// /// // Wait for the thread to start up. /// let (lock, cvar) = &*pair; - /// // As long as the value inside the `Mutex` is `false`, we wait. - /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); + /// // As long as the value inside the `Mutex` is `true`, we wait. + /// let _guard = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap(); /// ``` #[stable(feature = "wait_until", since = "1.42.0")] - pub fn wait_until<'a, T, F>( + pub fn wait_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, mut condition: F, @@ -256,7 +254,7 @@ impl Condvar { where F: FnMut(&mut T) -> bool, { - while !condition(&mut *guard) { + while condition(&mut *guard) { guard = self.wait(guard)?; } Ok(guard) @@ -341,11 +339,10 @@ impl Condvar { /// Condition variables normally have a boolean predicate associated with /// them, and the predicate must always be checked each time this function /// returns to protect against spurious wakeups. Additionally, it is - /// typically desirable for the time-out to not exceed some duration in + /// typically desirable for the timeout to not exceed some duration in /// spite of spurious wakes, thus the sleep-duration is decremented by the - /// amount slept. Alternatively, use the `wait_timeout_until` method - /// to wait until a condition is met with a total time-out regardless - /// of spurious wakes. + /// amount slept. Alternatively, use the `wait_timeout_while` method + /// to wait with a timeout while a predicate is true. /// /// The returned [`WaitTimeoutResult`] value indicates if the timeout is /// known to have elapsed. @@ -354,7 +351,7 @@ impl Condvar { /// returns, regardless of whether the timeout elapsed or not. /// /// [`wait`]: #method.wait - /// [`wait_timeout_until`]: #method.wait_timeout_until + /// [`wait_timeout_while`]: #method.wait_timeout_while /// [`WaitTimeoutResult`]: struct.WaitTimeoutResult.html /// /// # Examples @@ -405,10 +402,9 @@ impl Condvar { } /// Waits on this condition variable for a notification, timing out after a - /// specified duration. Spurious wakes will not cause this function to - /// return. + /// specified duration. /// - /// The semantics of this function are equivalent to [`wait_until`] except + /// The semantics of this function are equivalent to [`wait_while`] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -421,10 +417,10 @@ impl Condvar { /// The returned [`WaitTimeoutResult`] value indicates if the timeout is /// known to have elapsed without the condition being met. /// - /// Like [`wait_until`], the lock specified will be re-acquired when this + /// Like [`wait_while`], the lock specified will be re-acquired when this /// function returns, regardless of whether the timeout elapsed or not. /// - /// [`wait_until`]: #method.wait_until + /// [`wait_while`]: #method.wait_while /// [`wait_timeout`]: #method.wait_timeout /// [`WaitTimeoutResult`]: struct.WaitTimeoutResult.html /// @@ -435,31 +431,31 @@ impl Condvar { /// use std::thread; /// use std::time::Duration; /// - /// let pair = Arc::new((Mutex::new(false), Condvar::new())); + /// let pair = Arc::new((Mutex::new(true), Condvar::new())); /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { /// let (lock, cvar) = &*pair2; - /// let mut started = lock.lock().unwrap(); - /// *started = true; + /// let mut pending = lock.lock().unwrap(); + /// *pending = false; /// // We notify the condvar that the value has changed. /// cvar.notify_one(); /// }); /// /// // wait for the thread to start up /// let (lock, cvar) = &*pair; - /// let result = cvar.wait_timeout_until( + /// let result = cvar.wait_timeout_while( /// lock.lock().unwrap(), /// Duration::from_millis(100), - /// |&mut started| started, + /// |&mut pending| pending, /// ).unwrap(); /// if result.1.timed_out() { - /// // timed-out without the condition ever evaluating to true. + /// // timed-out without the condition ever evaluating to false. /// } /// // access the locked mutex via result.0 /// ``` #[stable(feature = "wait_timeout_until", since = "1.42.0")] - pub fn wait_timeout_until<'a, T, F>( + pub fn wait_timeout_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, dur: Duration, @@ -470,7 +466,7 @@ impl Condvar { { let start = Instant::now(); loop { - if condition(&mut *guard) { + if !condition(&mut *guard) { return Ok((guard, WaitTimeoutResult(false))); } let timeout = match dur.checked_sub(start.elapsed()) { @@ -678,7 +674,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_until() { + fn wait_while() { let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair2 = pair.clone(); @@ -693,7 +689,7 @@ mod tests { // Wait for the thread to start up. let &(ref lock, ref cvar) = &*pair; - let guard = cvar.wait_until(lock.lock().unwrap(), |started| *started); + let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started); assert!(*guard.unwrap()); } @@ -720,24 +716,24 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn wait_timeout_until_wait() { + fn wait_timeout_while_wait() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); let g = m.lock().unwrap(); - let (_g, wait) = c.wait_timeout_until(g, Duration::from_millis(1), |_| false).unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap(); // no spurious wakeups. ensure it timed-out assert!(wait.timed_out()); } #[test] #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_until_instant_satisfy() { + fn wait_timeout_while_instant_satisfy() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); let g = m.lock().unwrap(); - let (_g, wait) = c.wait_timeout_until(g, Duration::from_millis(0), |_| true).unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap(); // ensure it didn't time-out even if we were not given any time. assert!(!wait.timed_out()); } @@ -745,7 +741,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn wait_timeout_until_wake() { + fn wait_timeout_while_wake() { let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair_copy = pair.clone(); @@ -759,7 +755,7 @@ mod tests { cvar.notify_one(); }); let (g2, wait) = c - .wait_timeout_until(g, Duration::from_millis(u64::MAX), |&mut notified| notified) + .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified) .unwrap(); // ensure it didn't time-out even if we were not given any time. assert!(!wait.timed_out()); From 48859db151b839518bdd9d44a2387c0f6b65d141 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 14:12:56 -0500 Subject: [PATCH 0014/1253] Relax bounds on HashSet to match hashbrown No functional changes are made, and all APIs are moved to strictly less restrictive bounds. These APIs changed from the old bound listed to the new bound: T: Hash + Eq -> T * new * with_capacity T: Eq + Hash, S: BuildHasher -> T * with_hasher * with_capacity_and_hasher * hasher T: Eq + Hash + Debug -> T: Debug S: BuildHasher -> S T: Eq + Hash -> T S: BuildHasher + Default -> S: Default --- src/libstd/collections/hash/set.rs | 20 +++++++++---------- .../core-traits-no-impls-length-33.rs | 1 - .../core-traits-no-impls-length-33.stderr | 19 +++++------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index fff64e9fc9008..f461f26572f01 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -110,7 +110,7 @@ pub struct HashSet { map: HashMap, } -impl HashSet { +impl HashSet { /// Creates an empty `HashSet`. /// /// The hash set is initially created with a capacity of 0, so it will not allocate until it @@ -261,13 +261,7 @@ impl HashSet { pub fn clear(&mut self) { self.map.clear() } -} -impl HashSet -where - T: Eq + Hash, - S: BuildHasher, -{ /// Creates a new empty hash set which will use the given hasher to hash /// keys. /// @@ -340,7 +334,13 @@ where pub fn hasher(&self) -> &S { self.map.hasher() } +} +impl HashSet +where + T: Eq + Hash, + S: BuildHasher, +{ /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashSet`. The collection may reserve more space to avoid /// frequent reallocations. @@ -896,8 +896,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for HashSet where - T: Eq + Hash + fmt::Debug, - S: BuildHasher, + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() @@ -945,8 +944,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl Default for HashSet where - T: Eq + Hash, - S: BuildHasher + Default, + S: Default, { /// Creates an empty `HashSet` with the `Default` value for the hasher. #[inline] diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs index 7fa059583f539..8397d204f35cf 100644 --- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs @@ -6,7 +6,6 @@ pub fn no_debug() { pub fn no_hash() { use std::collections::HashSet; let mut set = HashSet::new(); - //~^ ERROR arrays only have std trait implementations for lengths 0..=32 set.insert([0_usize; 33]); //~^ ERROR arrays only have std trait implementations for lengths 0..=32 } diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr index d885c98dcb287..594a0d4b5d844 100644 --- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr @@ -8,24 +8,15 @@ LL | println!("{:?}", [0_usize; 33]); = note: required by `std::fmt::Debug::fmt` error[E0277]: arrays only have std trait implementations for lengths 0..=32 - --> $DIR/core-traits-no-impls-length-33.rs:10:16 + --> $DIR/core-traits-no-impls-length-33.rs:9:16 | LL | set.insert([0_usize; 33]); | ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` | = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]` -error[E0277]: arrays only have std trait implementations for lengths 0..=32 - --> $DIR/core-traits-no-impls-length-33.rs:8:19 - | -LL | let mut set = HashSet::new(); - | ^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` - | - = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]` - = note: required by `std::collections::HashSet::::new` - error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]` - --> $DIR/core-traits-no-impls-length-33.rs:15:19 + --> $DIR/core-traits-no-impls-length-33.rs:14:19 | LL | [0_usize; 33] == [1_usize; 33] | ------------- ^^ ------------- [usize; 33] @@ -35,7 +26,7 @@ LL | [0_usize; 33] == [1_usize; 33] = note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]` error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]` - --> $DIR/core-traits-no-impls-length-33.rs:20:19 + --> $DIR/core-traits-no-impls-length-33.rs:19:19 | LL | [0_usize; 33] < [1_usize; 33] | ------------- ^ ------------- [usize; 33] @@ -45,7 +36,7 @@ LL | [0_usize; 33] < [1_usize; 33] = note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]` error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied - --> $DIR/core-traits-no-impls-length-33.rs:25:14 + --> $DIR/core-traits-no-impls-length-33.rs:24:14 | LL | for _ in &[0_usize; 33] { | ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]` @@ -57,7 +48,7 @@ LL | for _ in &[0_usize; 33] { <&'a mut [T] as std::iter::IntoIterator> = note: required by `std::iter::IntoIterator::into_iter` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0277, E0369. For more information about an error, try `rustc --explain E0277`. From 4843f227885bf23a34cc8485173c11601b00d977 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 30 Dec 2019 13:30:34 +0000 Subject: [PATCH 0015/1253] Handle recursive instantiation of drop shims --- src/librustc_mir/monomorphize/collector.rs | 4 ++-- src/test/ui/issues/issue-38591.rs | 10 ---------- .../issue-26548-recursion-via-normalize.rs} | 0 .../issue-26548-recursion-via-normalize.stderr} | 2 +- .../issue-38591-non-regular-dropck-recursion.rs | 17 +++++++++++++++++ ...ue-38591-non-regular-dropck-recursion.stderr | 4 ++++ 6 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 src/test/ui/issues/issue-38591.rs rename src/test/ui/{issues/issue-26548.rs => recursion/issue-26548-recursion-via-normalize.rs} (100%) rename src/test/ui/{issues/issue-26548.stderr => recursion/issue-26548-recursion-via-normalize.stderr} (88%) create mode 100644 src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs create mode 100644 src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 0a783337ad150..dfc3c4cd76947 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -423,7 +423,7 @@ fn check_recursion_limit<'tcx>( let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); debug!(" => recursion depth={}", recursion_depth); - let recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + let adjusted_recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { // HACK: drop_in_place creates tight monomorphization loops. Give // it more margin. recursion_depth / 4 @@ -434,7 +434,7 @@ fn check_recursion_limit<'tcx>( // Code that needs to instantiate the same function recursively // more than the recursion limit is assumed to be causing an // infinite expansion. - if recursion_depth > *tcx.sess.recursion_limit.get() { + if adjusted_recursion_depth > *tcx.sess.recursion_limit.get() { let error = format!("reached the recursion limit while instantiating `{}`", instance); if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { tcx.sess.span_fatal(tcx.hir().span(hir_id), &error); diff --git a/src/test/ui/issues/issue-38591.rs b/src/test/ui/issues/issue-38591.rs deleted file mode 100644 index 2f594b48e697f..0000000000000 --- a/src/test/ui/issues/issue-38591.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass - -struct S { - t : T, - s : Box> -} - -fn f(x : S) {} - -fn main () {} diff --git a/src/test/ui/issues/issue-26548.rs b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs similarity index 100% rename from src/test/ui/issues/issue-26548.rs rename to src/test/ui/recursion/issue-26548-recursion-via-normalize.rs diff --git a/src/test/ui/issues/issue-26548.stderr b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr similarity index 88% rename from src/test/ui/issues/issue-26548.stderr rename to src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr index 3c213674e4b70..6a83f91ce5b32 100644 --- a/src/test/ui/issues/issue-26548.stderr +++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr @@ -3,7 +3,7 @@ error[E0391]: cycle detected when computing layout of `std::option::Option` = note: ...which requires computing layout of `S`... = note: ...which again requires computing layout of `std::option::Option`, completing the cycle note: cycle used when processing `main` - --> $DIR/issue-26548.rs:11:1 + --> $DIR/issue-26548-recursion-via-normalize.rs:11:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs new file mode 100644 index 0000000000000..0fcf77d8722d6 --- /dev/null +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs @@ -0,0 +1,17 @@ +// Dropck shouldn't hit a recursion limit from checking `S` since it has +// no free regions or type parameters. +// Codegen however, has to error for the infinitely many `real_drop_in_place` +// functions it has been asked to create. +// build-fail + +struct S { + t: T, + s: Box>, +} + +fn f(x: S) {} + +fn main() { + // Force instantiation. + f as fn(_); +} diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr new file mode 100644 index 0000000000000..77309a82a0fa7 --- /dev/null +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -0,0 +1,4 @@ +error: reached the recursion limit while instantiating `std::ptr::real_drop_in_place::> - shim(Some(S))` + +error: aborting due to previous error + From 2ccf65c7eba519dcc407cb76f08d04ac00d05851 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Mon, 30 Dec 2019 14:25:53 +0000 Subject: [PATCH 0016/1253] Remove appendix from LICENCE-APACHE --- LICENSE-APACHE | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 16fe87b06e802..1b5ec8b78e237 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. From 0435c1b0a5fbc0cbaef8cb9f1711d3e30c944781 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 20 Dec 2019 20:34:24 -0500 Subject: [PATCH 0017/1253] When a codegen worker has a FatalError, propagate it instead of ICE'ing. --- src/librustc_codegen_ssa/back/write.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index a5a90980c3a23..9f577ba83d2b7 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -903,7 +903,7 @@ pub enum Message { worker_id: usize, }, Done { - result: Result, + result: Result>, worker_id: usize, }, CodegenDone { @@ -1476,9 +1476,12 @@ fn start_executing_work( main_thread_worker_state = MainThreadWorkerState::Idle; } // If the thread failed that means it panicked, so we abort immediately. - Message::Done { result: Err(()), worker_id: _ } => { + Message::Done { result: Err(None), worker_id: _ } => { bug!("worker thread panicked"); } + Message::Done { result: Err(Some(WorkerFatalError)), worker_id: _ } => { + return Err(()); + } Message::CodegenItem => bug!("the coordinator should not receive codegen requests"), } } @@ -1527,6 +1530,10 @@ fn start_executing_work( pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; +/// `FatalError` is explicitly not `Send`. +#[must_use] +pub struct WorkerFatalError; + fn spawn_work(cgcx: CodegenContext, work: WorkItem) { let depth = time_depth(); @@ -1537,23 +1544,26 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem // we exit. struct Bomb { coordinator_send: Sender>, - result: Option>, + result: Option, FatalError>>, worker_id: usize, } impl Drop for Bomb { fn drop(&mut self) { let worker_id = self.worker_id; let msg = match self.result.take() { - Some(WorkItemResult::Compiled(m)) => { + Some(Ok(WorkItemResult::Compiled(m))) => { Message::Done:: { result: Ok(m), worker_id } } - Some(WorkItemResult::NeedsFatLTO(m)) => { + Some(Ok(WorkItemResult::NeedsFatLTO(m))) => { Message::NeedsFatLTO:: { result: m, worker_id } } - Some(WorkItemResult::NeedsThinLTO(name, thin_buffer)) => { + Some(Ok(WorkItemResult::NeedsThinLTO(name, thin_buffer))) => { Message::NeedsThinLTO:: { name, thin_buffer, worker_id } } - None => Message::Done:: { result: Err(()), worker_id }, + Some(Err(FatalError)) => { + Message::Done:: { result: Err(Some(WorkerFatalError)), worker_id } + } + None => Message::Done:: { result: Err(None), worker_id }, }; drop(self.coordinator_send.send(Box::new(msg))); } @@ -1573,7 +1583,7 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem // surface that there was an error in this worker. bomb.result = { let _prof_timer = cgcx.prof.generic_activity(work.profiling_event_id()); - execute_work_item(&cgcx, work).ok() + Some(execute_work_item(&cgcx, work)) }; }); } From 7c5cff717ffb13c8d0b9eb4d287bd2c565a9d7f4 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 20 Dec 2019 20:55:12 -0500 Subject: [PATCH 0018/1253] regression test for 66530. it uses normalize-stderr-test because not all targets hit the same OS error number nor message ... ... and ignores tidy since I dont know how to make the normalize line shorter ... and has effectively a no-op for its error-pattern because the targets' error messages are so wildly different (and the error-pattern check occurs *before* stderr normalization.) --- .../ui/non-ice-error-on-worker-io-fail.rs | 36 +++++++++++++++++++ .../ui/non-ice-error-on-worker-io-fail.stderr | 6 ++++ 2 files changed, 42 insertions(+) create mode 100644 src/test/ui/non-ice-error-on-worker-io-fail.rs create mode 100644 src/test/ui/non-ice-error-on-worker-io-fail.stderr diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.rs b/src/test/ui/non-ice-error-on-worker-io-fail.rs new file mode 100644 index 0000000000000..deffb2969b60e --- /dev/null +++ b/src/test/ui/non-ice-error-on-worker-io-fail.rs @@ -0,0 +1,36 @@ +// Issue #66530: We would ICE if someone compiled with `-o /dev/null`, +// because we would try to generate auxiliary files in `/dev/` (which +// at least the OS X file system rejects). +// +// An attempt to `-o` into a directory we cannot write into should indeed +// be an error; but not an ICE. + +// compile-flags: -o /dev/null + +// The error-pattern check occurs *before* normalization, and the error patterns +// are wildly different between build environments. So this is a cop-out (and we +// rely on the checking of the normalized stderr output as our actual +// "verification" of the diagnostic). + +// error-pattern: error + +// On Mac OS X, we get an error like the below +// normalize-stderr-test "failed to write bytecode to /dev/null.non_ice_error_on_worker_io_fail.*" -> "io error modifying /dev/" + +// On Linux, we get an error like the below +// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /dev/" + +// ignore-tidy-linelength +// ignore-windows - this is a unix-specific test +// ignore-emscripten - the file-system issues do not replicate here +// ignore-wasm - the file-system issues do not replicate here + +#![crate_type="lib"] + +#![cfg_attr(not(feature = "std"), no_std)] +pub mod task { + pub mod __internal { + use crate::task::Waker; + } + pub use core::task::Waker; +} diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.stderr b/src/test/ui/non-ice-error-on-worker-io-fail.stderr new file mode 100644 index 0000000000000..f5601ad03d5d8 --- /dev/null +++ b/src/test/ui/non-ice-error-on-worker-io-fail.stderr @@ -0,0 +1,6 @@ +warning: ignoring --out-dir flag due to -o flag + +error: io error modifying /dev/ + +error: aborting due to previous error + From 8314b7fd27350681ecbe5d55f840ddc5873d222f Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 31 Dec 2019 14:09:06 +0100 Subject: [PATCH 0019/1253] More thorough testing of BTreeMap::range --- src/liballoc/tests/btree/map.rs | 181 ++++++++++++++++++++++++++------ 1 file changed, 150 insertions(+), 31 deletions(-) diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 35ce1354f52e0..f5be72c39b20c 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -4,6 +4,7 @@ use std::convert::TryFrom; use std::fmt::Debug; use std::iter::FromIterator; use std::ops::Bound::{self, Excluded, Included, Unbounded}; +use std::ops::RangeBounds; use std::rc::Rc; use super::DeterministicRng; @@ -68,6 +69,11 @@ fn test_basic_small() { assert_eq!(map.last_key_value(), None); assert_eq!(map.keys().count(), 0); assert_eq!(map.values().count(), 0); + assert_eq!(map.range(..).next(), None); + assert_eq!(map.range(..1).next(), None); + assert_eq!(map.range(1..).next(), None); + assert_eq!(map.range(1..=1).next(), None); + assert_eq!(map.range(1..2).next(), None); assert_eq!(map.insert(1, 1), None); // 1 key-value pair: @@ -118,6 +124,11 @@ fn test_basic_small() { assert_eq!(map.last_key_value(), None); assert_eq!(map.keys().count(), 0); assert_eq!(map.values().count(), 0); + assert_eq!(map.range(..).next(), None); + assert_eq!(map.range(..1).next(), None); + assert_eq!(map.range(1..).next(), None); + assert_eq!(map.range(1..=1).next(), None); + assert_eq!(map.range(1..2).next(), None); assert_eq!(map.remove(&1), None); } @@ -128,7 +139,6 @@ fn test_iter() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -154,7 +164,6 @@ fn test_iter_rev() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -275,7 +284,6 @@ fn test_iter_mixed() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -299,27 +307,147 @@ fn test_iter_mixed() { test(size, map.into_iter()); } -#[test] -fn test_range_small() { - let size = 5; - - // Forwards - let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); - - let mut j = 0; - for ((&k, &v), i) in map.range(2..).zip(2..size) { - assert_eq!(k, i); - assert_eq!(v, i); - j += 1; - } - assert_eq!(j, size - 2); +fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { + map.range(range) + .map(|(&k, &v)| { + assert_eq!(k, v); + k + }) + .collect() } #[test] -fn test_range_inclusive() { - let size = 500; +fn test_range_small() { + let size = 4; + + let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect(); + let all: Vec<_> = (1..=size).collect(); + let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all); + assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size))), all); + assert_eq!(range_keys(&map, (Included(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size))), all); + assert_eq!(range_keys(&map, (Included(1), Unbounded)), all); + assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size))), all); + assert_eq!(range_keys(&map, ..), all); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(1), Included(1))), first); + assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first); + assert_eq!(range_keys(&map, (Unbounded, Included(1))), first); + assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last); + assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size))), last); + assert_eq!(range_keys(&map, (Included(size), Unbounded)), last); + assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]); + + assert_eq!(range_keys(&map, ..3), vec![1, 2]); + assert_eq!(range_keys(&map, 3..), vec![3, 4]); + assert_eq!(range_keys(&map, 2..=3), vec![2, 3]); +} + +#[test] +fn test_range_depth_2() { + // Assuming that node.CAPACITY is 11, having 12 pairs implies a depth 2 tree + // with 2 leaves. Depending on details we don't want or need to rely upon, + // the single key at the root will be 6 or 7. + + let map: BTreeMap<_, _> = (1..=12).map(|i| (i, i)).collect(); + for &root in &[6, 7] { + assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(root), Included(root + 1))), vec![root + 1]); + assert_eq!(range_keys(&map, (Included(root), Excluded(root + 1))), vec![root]); + assert_eq!(range_keys(&map, (Included(root), Included(root + 1))), vec![root, root + 1]); + + assert_eq!(range_keys(&map, (Excluded(root - 1), Excluded(root))), vec![]); + assert_eq!(range_keys(&map, (Included(root - 1), Excluded(root))), vec![root - 1]); + assert_eq!(range_keys(&map, (Excluded(root - 1), Included(root))), vec![root]); + assert_eq!(range_keys(&map, (Included(root - 1), Included(root))), vec![root - 1, root]); + } +} + +#[test] +fn test_range_large() { + let size = 200; - let map: BTreeMap<_, _> = (0..=size).map(|i| (i, i)).collect(); + let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect(); + let all: Vec<_> = (1..=size).collect(); + let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all); + assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size))), all); + assert_eq!(range_keys(&map, (Included(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size))), all); + assert_eq!(range_keys(&map, (Included(1), Unbounded)), all); + assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size))), all); + assert_eq!(range_keys(&map, ..), all); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(1), Included(1))), first); + assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first); + assert_eq!(range_keys(&map, (Unbounded, Included(1))), first); + assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last); + assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size))), last); + assert_eq!(range_keys(&map, (Included(size), Unbounded)), last); + assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]); fn check<'a, L, R>(lhs: L, rhs: R) where @@ -331,18 +459,9 @@ fn test_range_inclusive() { assert_eq!(lhs, rhs); } - check(map.range(size + 1..=size + 1), vec![]); - check(map.range(size..=size), vec![(&size, &size)]); - check(map.range(size..=size + 1), vec![(&size, &size)]); - check(map.range(0..=0), vec![(&0, &0)]); - check(map.range(0..=size - 1), map.range(..size)); - check(map.range(-1..=-1), vec![]); - check(map.range(-1..=size), map.range(..)); - check(map.range(..=size), map.range(..)); - check(map.range(..=200), map.range(..201)); + check(map.range(..=100), map.range(..101)); check(map.range(5..=8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]); - check(map.range(-1..=0), vec![(&0, &0)]); - check(map.range(-1..=2), vec![(&0, &0), (&1, &1), (&2, &2)]); + check(map.range(-1..=2), vec![(&1, &1), (&2, &2)]); } #[test] From 73996df6291001f0742b6409249329301aa77a23 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 Jan 2020 14:43:24 -0500 Subject: [PATCH 0020/1253] Reset Formatter flags on exit from pad_integral This fixes a bug where after calling pad_integral with appropriate flags, the fill and alignment flags would be set to '0' and 'Right' and left as such even after exiting pad_integral, which meant that future calls on the same Formatter would get incorrect flags reported. This is quite difficult to observe in practice, as almost all formatting implementations in practice don't call `Display::fmt` directly, but rather use `write!` or a similar macro, which means that they cannot observe the effects of the wrong flags (as `write!` creates a fresh Formatter instance). However, we include a test case. --- src/libcore/fmt/mod.rs | 9 ++++++--- src/libcore/tests/fmt/mod.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6c8d1626b09b6..e68f3c58a3e07 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1244,12 +1244,15 @@ impl<'a> Formatter<'a> { // The sign and prefix goes before the padding if the fill character // is zero Some(min) if self.sign_aware_zero_pad() => { - self.fill = '0'; - self.align = rt::v1::Alignment::Right; + let old_fill = crate::mem::replace(&mut self.fill, '0'); + let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right); write_prefix(self, sign, prefix)?; let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; self.buf.write_str(buf)?; - post_padding.write(self.buf) + post_padding.write(self.buf)?; + self.fill = old_fill; + self.align = old_align; + Ok(()) } // Otherwise, the sign and prefix goes after the padding Some(min) => { diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index d86e21cf40b6e..7b281ce48e6aa 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -28,3 +28,18 @@ fn test_estimated_capacity() { assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0); assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32); } + +#[test] +fn pad_integral_resets() { + struct Bar; + + impl core::fmt::Display for Bar { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + "1".fmt(f)?; + f.pad_integral(true, "", "5")?; + "1".fmt(f) + } + } + + assert_eq!(format!("{:<03}", Bar), "1 0051 "); +} From 66207ae7f8e793c58bccca6464feb9deeed24adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 3 Jan 2020 12:35:55 +0100 Subject: [PATCH 0021/1253] ci: bump ubuntu 19.04 images to 19.10 Ubuntu 19.04 goes EOL this month. --- src/ci/docker/x86_64-gnu-debug/Dockerfile | 2 +- src/ci/docker/x86_64-gnu/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index b2748d9c2ab79..890e13232c3fd 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:19.04 +FROM ubuntu:19.10 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ diff --git a/src/ci/docker/x86_64-gnu/Dockerfile b/src/ci/docker/x86_64-gnu/Dockerfile index 4ec4364721393..b864c09ea8c45 100644 --- a/src/ci/docker/x86_64-gnu/Dockerfile +++ b/src/ci/docker/x86_64-gnu/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:19.04 +FROM ubuntu:19.10 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ From 5e92625004546005c3bc59351dd6c5132312f0f7 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 4 Jan 2020 13:08:17 +0000 Subject: [PATCH 0022/1253] Correctly check for opaque types in `assoc_ty_def` --- src/librustc/traits/project.rs | 2 +- .../incoherent-assoc-imp-trait.rs | 16 +++++++++++++ .../incoherent-assoc-imp-trait.stderr | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs create mode 100644 src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index c604bf59cbd79..5ac31fafd9f34 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1461,7 +1461,7 @@ fn assoc_ty_def( // cycle error if the specialization graph is currently being built. let impl_node = specialization_graph::Node::Impl(impl_def_id); for item in impl_node.items(tcx) { - if item.kind == ty::AssocKind::Type + if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy) && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) { return specialization_graph::NodeItem { diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs new file mode 100644 index 0000000000000..c46c4715924e5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs @@ -0,0 +1,16 @@ +// Regression test for issue 67856 + +#![feature(unboxed_closures)] +#![feature(type_alias_impl_trait)] +#![feature(fn_traits)] + +trait MyTrait {} +impl MyTrait for () {} + +impl FnOnce<()> for &F { + //~^ ERROR conflicting implementations + //~| ERROR type parameter `F` must be used + type Output = impl MyTrait; + extern "rust-call" fn call_once(self, _: ()) -> Self::Output {} +} +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr new file mode 100644 index 0000000000000..f8e1e55f23f9a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr @@ -0,0 +1,23 @@ +error[E0119]: conflicting implementations of trait `std::ops::FnOnce<()>` for type `&_`: + --> $DIR/incoherent-assoc-imp-trait.rs:10:1 + | +LL | impl FnOnce<()> for &F { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl std::ops::FnOnce for &F + where F: std::ops::Fn, F: ?Sized; + +error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/incoherent-assoc-imp-trait.rs:10:6 + | +LL | impl FnOnce<()> for &F { + | ^ type parameter `F` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0210. +For more information about an error, try `rustc --explain E0119`. From 9876f6bd9c2927633e6df21889a585469dc5fce6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Jan 2020 00:28:15 +0100 Subject: [PATCH 0023/1253] Fix error code failure check in rustdoc test --- src/librustdoc/test.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index db66b7530b29d..ca5c09edfbb28 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -299,7 +299,6 @@ fn run_test( eprint!("{}", self.0); } } - let out = str::from_utf8(&output.stderr).unwrap(); let _bomb = Bomb(&out); match (output.status.success(), compile_fail) { @@ -309,7 +308,7 @@ fn run_test( (true, false) => {} (false, true) => { if !error_codes.is_empty() { - error_codes.retain(|err| !out.contains(err)); + error_codes.retain(|err| !out.contains(&format!("error[{}]: ", err))); if !error_codes.is_empty() { return Err(TestFailure::MissingErrorCodes(error_codes)); From d288c28ff323445e6157b95893072a571009a434 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Mon, 6 Jan 2020 15:41:09 +0100 Subject: [PATCH 0024/1253] Relax the Sized bounds on Pin::map_unchecked(_mut) --- src/libcore/pin.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index aca6fb2013881..676d2c784acee 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -672,6 +672,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { #[stable(feature = "pin", since = "1.33.0")] pub unsafe fn map_unchecked(self, func: F) -> Pin<&'a U> where + U: ?Sized, F: FnOnce(&T) -> &U, { let pointer = &*self.pointer; @@ -763,6 +764,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[stable(feature = "pin", since = "1.33.0")] pub unsafe fn map_unchecked_mut(self, func: F) -> Pin<&'a mut U> where + U: ?Sized, F: FnOnce(&mut T) -> &mut U, { let pointer = Pin::get_unchecked_mut(self); From 3ab95ceb12b60c1564d037e8d8d6e2406fad44b3 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 7 Jan 2020 00:00:16 +0000 Subject: [PATCH 0025/1253] Detail transitive containment in E0588 diagnostic --- src/librustc_typeck/check/mod.rs | 87 ++++++++++---- .../ui/repr/repr-packed-contains-align.rs | 16 +-- .../ui/repr/repr-packed-contains-align.stderr | 112 ++++++++++++++++-- 3 files changed, 174 insertions(+), 41 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eacd94f7da7f7..6b9b28a0fa622 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -118,7 +118,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath}; +use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath}; use rustc_index::vec::Idx; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{original_sp, DUMMY_SP}; @@ -2295,44 +2295,81 @@ fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { "type has conflicting packed and align representation hints" ) .emit(); - } else if check_packed_inner(tcx, def_id, &mut Vec::new()) { - struct_span_err!( - tcx.sess, - sp, - E0588, - "packed type cannot transitively contain a `[repr(align)]` type" - ) - .emit(); + } else { + if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) { + let mut err = struct_span_err!( + tcx.sess, + sp, + E0588, + "packed type cannot transitively contain a `#[repr(align)]` type" + ); + + let hir = tcx.hir(); + if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) { + if let Node::Item(Item { ident, .. }) = hir.get(hir_id) { + err.span_note( + tcx.def_span(def_spans[0].0), + &format!("`{}` has a `#[repr(align)]` attribute", ident), + ); + } + } + + if def_spans.len() > 2 { + let mut first = true; + for (adt_def, span) in def_spans.iter().skip(1).rev() { + if let Some(hir_id) = hir.as_local_hir_id(*adt_def) { + if let Node::Item(Item { ident, .. }) = hir.get(hir_id) { + err.span_note( + *span, + &if first { + format!( + "`{}` contains a field of type `{}`", + tcx.type_of(def_id), + ident + ) + } else { + format!("...which contains a field of type `{}`", ident) + }, + ); + first = false; + } + } + } + } + + err.emit(); + } } } } -fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec) -> bool { - let t = tcx.type_of(def_id); - if stack.contains(&def_id) { - debug!("check_packed_inner: {:?} is recursive", t); - return false; - } - if let ty::Adt(def, substs) = t.kind { +fn check_packed_inner( + tcx: TyCtxt<'_>, + def_id: DefId, + stack: &mut Vec, +) -> Option> { + if let ty::Adt(def, substs) = tcx.type_of(def_id).kind { if def.is_struct() || def.is_union() { - if tcx.adt_def(def.did).repr.align.is_some() { - return true; + if def.repr.align.is_some() { + return Some(vec![(def.did, DUMMY_SP)]); } - // push struct def_id before checking fields + stack.push(def_id); for field in &def.non_enum_variant().fields { - let f = field.ty(tcx, substs); - if let ty::Adt(def, _) = f.kind { - if check_packed_inner(tcx, def.did, stack) { - return true; + if let ty::Adt(def, _) = field.ty(tcx, substs).kind { + if !stack.contains(&def.did) { + if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) { + defs.push((def.did, field.ident.span)); + return Some(defs); + } } } } - // only need to pop if not early out stack.pop(); } } - false + + None } /// Emit an error when encountering more or less than one variant in a transparent enum. diff --git a/src/test/ui/repr/repr-packed-contains-align.rs b/src/test/ui/repr/repr-packed-contains-align.rs index a3610345173a7..67d87eb5cd520 100644 --- a/src/test/ui/repr/repr-packed-contains-align.rs +++ b/src/test/ui/repr/repr-packed-contains-align.rs @@ -16,34 +16,34 @@ union UB { } #[repr(packed)] -struct SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SC(SA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SD(SB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SD(SB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SE(UA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SE(UA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SF(UB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SF(UB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -union UC { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UC { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type a: UA } #[repr(packed)] -union UD { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UD { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type n: UB } #[repr(packed)] -union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UE { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type a: SA } #[repr(packed)] -union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UF { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type n: SB } diff --git a/src/test/ui/repr/repr-packed-contains-align.stderr b/src/test/ui/repr/repr-packed-contains-align.stderr index df001d6b5f2a4..32f9bb8bf33d9 100644 --- a/src/test/ui/repr/repr-packed-contains-align.stderr +++ b/src/test/ui/repr/repr-packed-contains-align.stderr @@ -1,58 +1,154 @@ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:19:1 | LL | struct SC(SA); | ^^^^^^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:22:1 | LL | struct SD(SB); | ^^^^^^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ +note: `SD` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:22:11 + | +LL | struct SD(SB); + | ^^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:7:11 + | +LL | struct SB(SA); + | ^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:25:1 | LL | struct SE(UA); | ^^^^^^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:28:1 | LL | struct SF(UB); | ^^^^^^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ +note: `SF` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:28:11 + | +LL | struct SF(UB); + | ^^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:15:5 + | +LL | a: UA + | ^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:31:1 | LL | / union UC { LL | | a: UA +LL | | } + | |_^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 LL | | } | |_^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:36:1 | LL | / union UD { LL | | n: UB LL | | } | |_^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ +note: `UD` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:37:5 + | +LL | n: UB + | ^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:15:5 + | +LL | a: UA + | ^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:41:1 | LL | / union UE { LL | | a: SA LL | | } | |_^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:46:1 | LL | / union UF { LL | | n: SB LL | | } | |_^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ +note: `UF` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:47:5 + | +LL | n: SB + | ^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:7:11 + | +LL | struct SB(SA); + | ^^ error: aborting due to 8 previous errors From eb4fc2d4fefe2638f986aeb0fa2368ff88c584d5 Mon Sep 17 00:00:00 2001 From: maik Date: Tue, 7 Jan 2020 15:33:33 +0100 Subject: [PATCH 0026/1253] Export scalar statics in wasm --- src/librustc_codegen_ssa/back/symbol_export.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index edd0fa5042707..9cf0f0a801e1a 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -349,7 +349,12 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = tcx.hir().get_if_local(sym_def_id) { - return SymbolExportLevel::Rust; + let export_level = if tcx.type_of(sym_def_id).is_scalar() { + SymbolExportLevel::C + } else { + SymbolExportLevel::Rust + }; + return export_level; } } From cc0fbdffe7db21649f45b3407ff9766636727690 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 21 Dec 2019 23:55:34 +0100 Subject: [PATCH 0027/1253] Automatically prefer integer addresses for zst MPlace --- src/librustc_mir/const_eval/eval_queries.rs | 4 +-- src/librustc_mir/interpret/operand.rs | 30 ++++----------------- src/librustc_mir/interpret/place.rs | 19 ++++++------- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/interpret/validity.rs | 11 +++----- src/librustc_mir/interpret/visitor.rs | 10 ++----- src/librustc_mir/transform/const_prop.rs | 3 ++- 7 files changed, 26 insertions(+), 53 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index dbeb75b60c290..8c41f7d1e61f6 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -115,7 +115,7 @@ pub(super) fn op_to_const<'tcx>( // by-val is if we are in const_field, i.e., if this is (a field of) something that we // "tried to make immediate" before. We wouldn't do that for non-slice scalar pairs or // structs containing such. - op.try_as_mplace() + op.try_as_mplace(ecx) }; let val = match immediate { Ok(mplace) => { @@ -132,7 +132,7 @@ pub(super) fn op_to_const<'tcx>( // `Immediate` is when we are called from `const_field`, and that `Immediate` // comes from a constant so it can happen have `Undef`, because the indirect // memory that was read had undefined bytes. - let mplace = op.assert_mem_place(); + let mplace = op.assert_mem_place(ecx); let ptr = mplace.ptr.assert_ptr(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); ConstValue::ByRef { alloc, offset: ptr.offset } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index def979b63b52a..00aecf74c7d3d 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -267,7 +267,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - match op.try_as_mplace() { + match op.try_as_mplace(self) { Ok(mplace) => Ok(self.force_mplace_ptr(mplace)?.into()), Err(imm) => Ok(imm.into()), // Nothing to cast/force } @@ -335,7 +335,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, src: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, Result, MPlaceTy<'tcx, M::PointerTag>>> { - Ok(match src.try_as_mplace() { + Ok(match src.try_as_mplace(self) { Ok(mplace) => { if let Some(val) = self.try_read_immediate_from_mplace(mplace)? { Ok(val) @@ -383,7 +383,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { op: OpTy<'tcx, M::PointerTag>, field: u64, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let base = match op.try_as_mplace() { + let base = match op.try_as_mplace(self) { Ok(mplace) => { // The easy case let field = self.mplace_field(mplace, field)?; @@ -420,7 +420,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { variant: VariantIdx, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { // Downcasts only change the layout - Ok(match op.try_as_mplace() { + Ok(match op.try_as_mplace(self) { Ok(mplace) => self.mplace_downcast(mplace, variant)?.into(), Err(..) => { let layout = op.layout.for_variant(self, variant); @@ -439,30 +439,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Field(field, _) => self.operand_field(base, field.index() as u64)?, Downcast(_, variant) => self.operand_downcast(base, variant)?, Deref => self.deref_operand(base)?.into(), - ConstantIndex { .. } | Index(_) if base.layout.is_zst() => { - OpTy { - op: Operand::Immediate(Scalar::zst().into()), - // the actual index doesn't matter, so we just pick a convenient one like 0 - layout: base.layout.field(self, 0)?, - } - } - Subslice { from, to, from_end } if base.layout.is_zst() => { - let elem_ty = if let ty::Array(elem_ty, _) = base.layout.ty.kind { - elem_ty - } else { - bug!("slices shouldn't be zero-sized"); - }; - assert!(!from_end, "arrays shouldn't be subsliced from the end"); - - OpTy { - op: Operand::Immediate(Scalar::zst().into()), - layout: self.layout_of(self.tcx.mk_array(elem_ty, (to - from) as u64))?, - } - } Subslice { .. } | ConstantIndex { .. } | Index(_) => { // The rest should only occur as mplace, we do not use Immediates for types // allowing such operations. This matches place_projection forcing an allocation. - let mplace = base.assert_mem_place(); + let mplace = base.assert_mem_place(self); self.mplace_projection(mplace, proj_elem)?.into() } }) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index f4ac7de852af0..7fbe691f183cc 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -200,16 +200,17 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { // These are defined here because they produce a place. impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { #[inline(always)] - pub fn try_as_mplace(self) -> Result, ImmTy<'tcx, Tag>> { + pub fn try_as_mplace(self, cx: &impl HasDataLayout) -> Result, ImmTy<'tcx, Tag>> { match *self { Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }), + Operand::Immediate(_) if self.layout.is_zst() => Ok(MPlaceTy::dangling(self.layout, cx)), Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }), } } #[inline(always)] - pub fn assert_mem_place(self) -> MPlaceTy<'tcx, Tag> { - self.try_as_mplace().unwrap() + pub fn assert_mem_place(self, cx: &impl HasDataLayout) -> MPlaceTy<'tcx, Tag> { + self.try_as_mplace(cx).unwrap() } } @@ -305,7 +306,7 @@ where /// On success, returns `None` for zero-sized accesses (where nothing else is /// left to do) and a `Pointer` to use for the actual access otherwise. #[inline] - pub fn check_mplace_access( + pub(super) fn check_mplace_access( &self, place: MPlaceTy<'tcx, M::PointerTag>, size: Option, @@ -338,7 +339,7 @@ where /// Force `place.ptr` to a `Pointer`. /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot. - pub fn force_mplace_ptr( + pub(super) fn force_mplace_ptr( &self, mut place: MPlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { @@ -415,7 +416,7 @@ where // Iterates over all fields of an array. Much more efficient than doing the // same by repeatedly calling `mplace_array`. - pub fn mplace_array_fields( + pub(super) fn mplace_array_fields( &self, base: MPlaceTy<'tcx, Tag>, ) -> InterpResult<'tcx, impl Iterator>> + 'tcx> @@ -430,7 +431,7 @@ where Ok((0..len).map(move |i| base.offset(i * stride, None, layout, dl))) } - pub fn mplace_subslice( + fn mplace_subslice( &self, base: MPlaceTy<'tcx, M::PointerTag>, from: u64, @@ -471,7 +472,7 @@ where base.offset(from_offset, meta, layout, self) } - pub fn mplace_downcast( + pub(super) fn mplace_downcast( &self, base: MPlaceTy<'tcx, M::PointerTag>, variant: VariantIdx, @@ -482,7 +483,7 @@ where } /// Project into an mplace - pub fn mplace_projection( + pub(super) fn mplace_projection( &self, base: MPlaceTy<'tcx, M::PointerTag>, proj_elem: &mir::PlaceElem<'tcx>, diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index a28bb539fd070..37dcab512b991 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -378,7 +378,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } None => { // Unsized self. - args[0].assert_mem_place() + args[0].assert_mem_place(self) } }; // Find and consult vtable diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 7b82bed2e7a61..73f479ede769d 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -571,12 +571,9 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ) -> InterpResult<'tcx> { match op.layout.ty.kind { ty::Str => { - let mplace = op.assert_mem_place(); // strings are never immediate - try_validation!( - self.ecx.read_str(mplace), - "uninitialized or non-UTF-8 data in str", - self.path - ); + let mplace = op.assert_mem_place(self.ecx); // strings are never immediate + try_validation!(self.ecx.read_str(mplace), + "uninitialized or non-UTF-8 data in str", self.path); } ty::Array(tys, ..) | ty::Slice(tys) if { @@ -604,7 +601,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); } // non-ZST array cannot be immediate, slices are never immediate - let mplace = op.assert_mem_place(); + let mplace = op.assert_mem_place(self.ecx); // This is the length of the array/slice. let len = mplace.len(self.ecx)?; // zero length slices have nothing to be checked diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 2cfcf0ff06d0f..d2594e8707104 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -223,7 +223,7 @@ macro_rules! make_value_visitor { match v.layout().ty.kind { ty::Dynamic(..) => { // immediate trait objects are not a thing - let dest = v.to_op(self.ecx())?.assert_mem_place(); + let dest = v.to_op(self.ecx())?.assert_mem_place(self.ecx()); let inner = self.ecx().unpack_dyn_trait(dest)?.1; trace!("walk_value: dyn object layout: {:#?}", inner.layout); // recurse with the inner type @@ -292,13 +292,7 @@ macro_rules! make_value_visitor { }, layout::FieldPlacement::Array { .. } => { // Let's get an mplace first. - let mplace = if v.layout().is_zst() { - // it's a ZST, the memory content cannot matter - MPlaceTy::dangling(v.layout(), self.ecx()) - } else { - // non-ZST array/slice/str cannot be immediate - v.to_op(self.ecx())?.assert_mem_place() - }; + let mplace = v.to_op(self.ecx())?.assert_mem_place(self.ecx()); // Now we can go over all the fields. let iter = self.ecx().mplace_array_fields(mplace)? .map(|f| f.and_then(|f| { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 6b0f7be86841e..d5d56b36cf4c3 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -707,7 +707,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ScalarMaybeUndef::Scalar(r), )) => l.is_bits() && r.is_bits(), interpret::Operand::Indirect(_) if mir_opt_level >= 2 => { - intern_const_alloc_recursive(&mut self.ecx, None, op.assert_mem_place()) + let mplace = op.assert_mem_place(&self.ecx); + intern_const_alloc_recursive(&mut self.ecx, None, mplace) .expect("failed to intern alloc"); true } From 5b770b080fab5a64875ffb10deff9e6d14950fc0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 22 Dec 2019 00:33:15 +0100 Subject: [PATCH 0028/1253] Remove a ZST special casing that is not necessary anymore --- src/librustc_mir/interpret/validity.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 73f479ede769d..786909731531f 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -596,15 +596,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> { // Optimized handling for arrays of integer/float type. - // bailing out for zsts is ok, since the array element type can only be int/float - if op.layout.is_zst() { - return Ok(()); - } - // non-ZST array cannot be immediate, slices are never immediate + // Arrays cannot be immediate, slices are never immediate. let mplace = op.assert_mem_place(self.ecx); // This is the length of the array/slice. let len = mplace.len(self.ecx)?; - // zero length slices have nothing to be checked + // Zero length slices have nothing to be checked. if len == 0 { return Ok(()); } From 4a5c35bc4490ecf5b06d311917ac64be63673d3c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 22 Dec 2019 00:35:56 +0100 Subject: [PATCH 0029/1253] Fix an ICE happening due code assuming that `MPlaceTy` cannot have integer addresses --- src/librustc_mir/const_eval/eval_queries.rs | 18 ++------------ src/librustc_mir/interpret/place.rs | 26 ++++++++++++++++++--- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 8c41f7d1e61f6..f28517c667265 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -118,25 +118,11 @@ pub(super) fn op_to_const<'tcx>( op.try_as_mplace(ecx) }; let val = match immediate { - Ok(mplace) => { - let ptr = mplace.ptr.assert_ptr(); - let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef { alloc, offset: ptr.offset } - } + Ok(mplace) => mplace.to_const_value(ecx.tcx.tcx), // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s), - ScalarMaybeUndef::Undef => { - // When coming out of "normal CTFE", we'll always have an `Indirect` operand as - // argument and we will not need this. The only way we can already have an - // `Immediate` is when we are called from `const_field`, and that `Immediate` - // comes from a constant so it can happen have `Undef`, because the indirect - // memory that was read had undefined bytes. - let mplace = op.assert_mem_place(ecx); - let ptr = mplace.ptr.assert_ptr(); - let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef { alloc, offset: ptr.offset } - } + ScalarMaybeUndef::Undef => op.assert_mem_place(ecx).to_const_value(ecx.tcx.tcx), }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { let (data, start) = match a.not_undef().unwrap() { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 7fbe691f183cc..54a692c66e3bc 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -6,12 +6,13 @@ use std::convert::TryFrom; use std::hash::Hash; use rustc::mir; -use rustc::mir::interpret::truncate; +use rustc::mir::interpret::{truncate, ConstValue}; use rustc::ty::layout::{ self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, }; use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_macros::HashStable; use super::{ @@ -195,15 +196,34 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { _ => bug!("vtable not supported on type {:?}", self.layout.ty), } } + + #[inline(always)] + pub fn to_const_value(self, tcx: TyCtxt<'tcx>) -> ConstValue<'tcx> { + match self.mplace.ptr { + Scalar::Ptr(ptr) => { + let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); + ConstValue::ByRef { alloc, offset: ptr.offset } + } + Scalar::Raw { data, .. } => { + assert_eq!(data, self.layout.align.abi.bytes().into()); + ConstValue::Scalar(Scalar::zst()) + } + } + } } // These are defined here because they produce a place. impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { #[inline(always)] - pub fn try_as_mplace(self, cx: &impl HasDataLayout) -> Result, ImmTy<'tcx, Tag>> { + pub fn try_as_mplace( + self, + cx: &impl HasDataLayout, + ) -> Result, ImmTy<'tcx, Tag>> { match *self { Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }), - Operand::Immediate(_) if self.layout.is_zst() => Ok(MPlaceTy::dangling(self.layout, cx)), + Operand::Immediate(_) if self.layout.is_zst() => { + Ok(MPlaceTy::dangling(self.layout, cx)) + } Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }), } } From cac6f4c12db5fadff650267a8456d5835d19b136 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 26 Dec 2019 23:32:34 +0100 Subject: [PATCH 0030/1253] Move `to_const_value` from `MPlaceTy` to its only use site --- src/librustc_mir/const_eval/eval_queries.rs | 15 +++++++++++++-- src/librustc_mir/interpret/place.rs | 17 +---------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index f28517c667265..b0add10dcac43 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -117,12 +117,23 @@ pub(super) fn op_to_const<'tcx>( // structs containing such. op.try_as_mplace(ecx) }; + + let to_const_value = |mplace: MPlaceTy<'_>| match mplace.ptr { + Scalar::Ptr(ptr) => { + let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); + ConstValue::ByRef { alloc, offset: ptr.offset } + } + Scalar::Raw { data, .. } => { + assert_eq!(data, mplace.layout.align.abi.bytes().into()); + ConstValue::Scalar(Scalar::zst()) + } + }; let val = match immediate { - Ok(mplace) => mplace.to_const_value(ecx.tcx.tcx), + Ok(mplace) => to_const_value(mplace), // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s), - ScalarMaybeUndef::Undef => op.assert_mem_place(ecx).to_const_value(ecx.tcx.tcx), + ScalarMaybeUndef::Undef => to_const_value(op.assert_mem_place(ecx)), }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { let (data, start) = match a.not_undef().unwrap() { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 54a692c66e3bc..c8499d845dd13 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -6,13 +6,12 @@ use std::convert::TryFrom; use std::hash::Hash; use rustc::mir; -use rustc::mir::interpret::{truncate, ConstValue}; +use rustc::mir::interpret::truncate; use rustc::ty::layout::{ self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, }; use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty}; -use rustc::ty::{self, Ty, TyCtxt}; use rustc_macros::HashStable; use super::{ @@ -196,20 +195,6 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { _ => bug!("vtable not supported on type {:?}", self.layout.ty), } } - - #[inline(always)] - pub fn to_const_value(self, tcx: TyCtxt<'tcx>) -> ConstValue<'tcx> { - match self.mplace.ptr { - Scalar::Ptr(ptr) => { - let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef { alloc, offset: ptr.offset } - } - Scalar::Raw { data, .. } => { - assert_eq!(data, self.layout.align.abi.bytes().into()); - ConstValue::Scalar(Scalar::zst()) - } - } - } } // These are defined here because they produce a place. From 4fbe434c5c10d9a0550db4ae93aaac3a0ed9816e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 27 Dec 2019 00:38:10 +0100 Subject: [PATCH 0031/1253] Poison any `MemPlace` created from a zst Operand (or otherwise via `MPlaceTy::dangling`) so you can't get the address back out. --- src/librustc_mir/interpret/eval_context.rs | 13 ++- src/librustc_mir/interpret/intern.rs | 5 +- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/interpret/place.rs | 98 ++++++++++++++++------ src/librustc_mir/interpret/snapshot.rs | 12 ++- src/librustc_mir/interpret/validity.rs | 15 ++-- 6 files changed, 102 insertions(+), 43 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 551e3e837c988..c5c2a6769e44a 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -20,7 +20,7 @@ use rustc_macros::HashStable; use rustc_span::source_map::{self, Span, DUMMY_SP}; use super::{ - Immediate, MPlaceTy, Machine, MemPlace, Memory, OpTy, Operand, Place, PlaceTy, + Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy, ScalarMaybeUndef, StackPopInfo, }; @@ -393,7 +393,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// This can fail to provide an answer for extern types. pub(super) fn size_and_align_of( &self, - metadata: Option>, + metadata: MemPlaceMeta, layout: TyLayout<'tcx>, ) -> InterpResult<'tcx, Option<(Size, Align)>> { if !layout.is_unsized() { @@ -465,14 +465,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Some((size, align))) } ty::Dynamic(..) => { - let vtable = metadata.expect("dyn trait fat ptr must have vtable"); + let vtable = metadata.unwrap_unsized(); // Read size and align from vtable (already checks size). Ok(Some(self.read_size_and_align_from_vtable(vtable)?)) } ty::Slice(_) | ty::Str => { - let len = - metadata.expect("slice fat ptr must have length").to_machine_usize(self)?; + let len = metadata.unwrap_unsized().to_machine_usize(self)?; let elem = layout.field(self, 0)?; // Make sure the slice is not too big. @@ -818,8 +817,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { " by align({}){} ref:", mplace.align.bytes(), match mplace.meta { - Some(meta) => format!(" meta({:?})", meta), - None => String::new(), + MemPlaceMeta::Unsized(meta) => format!(" meta({:?})", meta), + MemPlaceMeta::Poison | MemPlaceMeta::None => String::new(), } ) .unwrap(); diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 7c6129ef30ffd..56e489d0bd590 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -193,7 +193,7 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx { // Validation has already errored on an invalid vtable pointer so we can safely not // do anything if this is not a real pointer. - if let Scalar::Ptr(vtable) = mplace.meta.unwrap() { + if let Scalar::Ptr(vtable) = mplace.meta.unwrap_unsized() { // Explicitly choose `Immutable` here, since vtables are immutable, even // if the reference of the fat pointer is mutable. self.intern_shallow(vtable.alloc_id, Mutability::Not, None)?; @@ -226,7 +226,8 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx | (InternMode::Const, hir::Mutability::Mut) => match referenced_ty.kind { ty::Array(_, n) if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {} - ty::Slice(_) if mplace.meta.unwrap().to_machine_usize(self.ecx)? == 0 => {} + ty::Slice(_) + if mplace.meta.unwrap_unsized().to_machine_usize(self.ecx)? == 0 => {} _ => bug!("const qualif failed to prevent mutable references"), }, } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 0d35eae6ed08d..2e8fbb95ca2e5 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -20,7 +20,7 @@ pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one pla pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup}; -pub use self::place::{MPlaceTy, MemPlace, Place, PlaceTy}; +pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind}; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index c8499d845dd13..6d848092defe5 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -20,6 +20,45 @@ use super::{ RawConst, Scalar, ScalarMaybeUndef, }; +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] +pub enum MemPlaceMeta { + Unsized(Scalar), + /// `Sized` types or unsized `extern type` + None, + /// The address of this place may not be taken. This protects the `MemPlace` from coming from + /// a ZST Operand with a backing allocation and being converted to an integer address. This + /// should be impossible, because you can't take the address of an operand, but this is a second + /// protection layer ensuring that we don't mess up. + Poison, +} + +impl MemPlaceMeta { + pub fn unwrap_unsized(self) -> Scalar { + match self { + Self::Unsized(s) => s, + Self::None | Self::Poison => { + bug!("expected wide pointer extra data (e.g. slice length or trait object vtable)") + } + } + } + fn is_unsized(self) -> bool { + match self { + Self::Unsized(_) => true, + Self::None | Self::Poison => false, + } + } +} + +impl MemPlaceMeta { + pub fn erase_tag(self) -> MemPlaceMeta<()> { + match self { + Self::Unsized(s) => MemPlaceMeta::Unsized(s.erase_tag()), + Self::None => MemPlaceMeta::None, + Self::Poison => MemPlaceMeta::Poison, + } + } +} + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] pub struct MemPlace { /// A place may have an integral pointer for ZSTs, and since it might @@ -30,7 +69,7 @@ pub struct MemPlace { /// Metadata for unsized places. Interpretation is up to the type. /// Must not be present for sized types, but can be missing for unsized types /// (e.g., `extern type`). - pub meta: Option>, + pub meta: MemPlaceMeta, } #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -88,16 +127,12 @@ impl MemPlace { #[inline] pub fn erase_tag(self) -> MemPlace { - MemPlace { - ptr: self.ptr.erase_tag(), - align: self.align, - meta: self.meta.map(Scalar::erase_tag), - } + MemPlace { ptr: self.ptr.erase_tag(), align: self.align, meta: self.meta.erase_tag() } } #[inline(always)] pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { - MemPlace { ptr, align, meta: None } + MemPlace { ptr, align, meta: MemPlaceMeta::None } } /// Produces a Place that will error if attempted to be read from or written to @@ -116,15 +151,19 @@ impl MemPlace { #[inline(always)] pub fn to_ref(self) -> Immediate { match self.meta { - None => Immediate::Scalar(self.ptr.into()), - Some(meta) => Immediate::ScalarPair(self.ptr.into(), meta.into()), + MemPlaceMeta::None => Immediate::Scalar(self.ptr.into()), + MemPlaceMeta::Unsized(meta) => Immediate::ScalarPair(self.ptr.into(), meta.into()), + MemPlaceMeta::Poison => bug!( + "MPlaceTy::dangling may never be used to produce a \ + place that will have the address of its pointee taken" + ), } } pub fn offset( self, offset: Size, - meta: Option>, + meta: MemPlaceMeta, cx: &impl HasDataLayout, ) -> InterpResult<'tcx, Self> { Ok(MemPlace { @@ -158,7 +197,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { pub fn offset( self, offset: Size, - meta: Option>, + meta: MemPlaceMeta, layout: TyLayout<'tcx>, cx: &impl HasDataLayout, ) -> InterpResult<'tcx, Self> { @@ -175,7 +214,9 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { if self.layout.is_unsized() { // We need to consult `meta` metadata match self.layout.ty.kind { - ty::Slice(..) | ty::Str => return self.mplace.meta.unwrap().to_machine_usize(cx), + ty::Slice(..) | ty::Str => { + return self.mplace.meta.unwrap_unsized().to_machine_usize(cx); + } _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } } else { @@ -191,7 +232,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { #[inline] pub(super) fn vtable(self) -> Scalar { match self.layout.ty.kind { - ty::Dynamic(..) => self.mplace.meta.unwrap(), + ty::Dynamic(..) => self.mplace.meta.unwrap_unsized(), _ => bug!("vtable not supported on type {:?}", self.layout.ty), } } @@ -276,8 +317,10 @@ where val.layout.ty.builtin_deref(true).expect("`ref_to_mplace` called on non-ptr type").ty; let layout = self.layout_of(pointee_type)?; let (ptr, meta) = match *val { - Immediate::Scalar(ptr) => (ptr.not_undef()?, None), - Immediate::ScalarPair(ptr, meta) => (ptr.not_undef()?, Some(meta.not_undef()?)), + Immediate::Scalar(ptr) => (ptr.not_undef()?, MemPlaceMeta::None), + Immediate::ScalarPair(ptr, meta) => { + (ptr.not_undef()?, MemPlaceMeta::Unsized(meta.not_undef()?)) + } }; let mplace = MemPlace { @@ -318,7 +361,7 @@ where ) -> InterpResult<'tcx, Option>> { let size = size.unwrap_or_else(|| { assert!(!place.layout.is_unsized()); - assert!(place.meta.is_none()); + assert!(!place.meta.is_unsized()); place.layout.size }); self.memory.check_ptr_access(place.ptr, size, place.align) @@ -411,7 +454,7 @@ where } else { // base.meta could be present; we might be accessing a sized field of an unsized // struct. - (None, offset) + (MemPlaceMeta::None, offset) }; // We do not look at `base.layout.align` nor `field_layout.align`, unlike @@ -433,7 +476,7 @@ where }; let layout = base.layout.field(self, 0)?; let dl = &self.tcx.data_layout; - Ok((0..len).map(move |i| base.offset(i * stride, None, layout, dl))) + Ok((0..len).map(move |i| base.offset(i * stride, MemPlaceMeta::None, layout, dl))) } fn mplace_subslice( @@ -466,10 +509,10 @@ where let (meta, ty) = match base.layout.ty.kind { // It is not nice to match on the type, but that seems to be the only way to // implement this. - ty::Array(inner, _) => (None, self.tcx.mk_array(inner, inner_len)), + ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(inner, inner_len)), ty::Slice(..) => { let len = Scalar::from_uint(inner_len, self.pointer_size()); - (Some(len), base.layout.ty) + (MemPlaceMeta::Unsized(len), base.layout.ty) } _ => bug!("cannot subslice non-array type: `{:?}`", base.layout.ty), }; @@ -483,7 +526,7 @@ where variant: VariantIdx, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { // Downcasts only change the layout - assert!(base.meta.is_none()); + assert!(!base.meta.is_unsized()); Ok(MPlaceTy { layout: base.layout.for_variant(self, variant), ..base }) } @@ -977,7 +1020,7 @@ where pub fn force_allocation_maybe_sized( &mut self, place: PlaceTy<'tcx, M::PointerTag>, - meta: Option>, + meta: MemPlaceMeta, ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option)> { let (mplace, size) = match place.place { Place::Local { frame, local } => { @@ -1022,7 +1065,7 @@ where &mut self, place: PlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { - Ok(self.force_allocation_maybe_sized(place, None)?.0) + Ok(self.force_allocation_maybe_sized(place, MemPlaceMeta::None)?.0) } pub fn allocate( @@ -1042,8 +1085,11 @@ where ) -> MPlaceTy<'tcx, M::PointerTag> { let ptr = self.memory.allocate_static_bytes(str.as_bytes(), kind); let meta = Scalar::from_uint(str.len() as u128, self.pointer_size()); - let mplace = - MemPlace { ptr: ptr.into(), align: Align::from_bytes(1).unwrap(), meta: Some(meta) }; + let mplace = MemPlace { + ptr: ptr.into(), + align: Align::from_bytes(1).unwrap(), + meta: MemPlaceMeta::Unsized(meta), + }; let layout = self.layout_of(self.tcx.mk_static_str()).unwrap(); MPlaceTy { mplace, layout } @@ -1151,7 +1197,7 @@ where assert_eq!(align, layout.align.abi); } - let mplace = MPlaceTy { mplace: MemPlace { meta: None, ..*mplace }, layout }; + let mplace = MPlaceTy { mplace: MemPlace { meta: MemPlaceMeta::None, ..*mplace }, layout }; Ok((instance, mplace)) } } diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 6790baf31ccb2..120baaf3be68a 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -23,7 +23,9 @@ use rustc_span::source_map::Span; use syntax::ast::Mutability; use super::eval_context::{LocalState, StackPopCleanup}; -use super::{Frame, Immediate, LocalValue, MemPlace, Memory, Operand, Place, ScalarMaybeUndef}; +use super::{ + Frame, Immediate, LocalValue, MemPlace, MemPlaceMeta, Memory, Operand, Place, ScalarMaybeUndef, +}; use crate::const_eval::CompileTimeInterpreter; #[derive(Default)] @@ -205,6 +207,14 @@ impl_snapshot_for!( } ); +impl_snapshot_for!( + enum MemPlaceMeta { + Unsized(s), + None, + Poison, + } +); + impl_snapshot_for!(struct MemPlace { ptr, meta, diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 786909731531f..7a7f431402075 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -16,7 +16,7 @@ use rustc_span::symbol::{sym, Symbol}; use std::hash::Hash; use super::{ - CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Scalar, + CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, ValueVisitor, }; @@ -246,13 +246,13 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M fn check_wide_ptr_meta( &mut self, - meta: Option>, + meta: MemPlaceMeta, pointee: TyLayout<'tcx>, ) -> InterpResult<'tcx> { let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env); match tail.kind { ty::Dynamic(..) => { - let vtable = meta.unwrap(); + let vtable = meta.unwrap_unsized(); try_validation!( self.ecx.memory.check_ptr_access( vtable, @@ -276,7 +276,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M } ty::Slice(..) | ty::Str => { let _len = try_validation!( - meta.unwrap().to_machine_usize(self.ecx), + meta.unwrap_unsized().to_machine_usize(self.ecx), "non-integer slice length in wide pointer", self.path ); @@ -572,8 +572,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> match op.layout.ty.kind { ty::Str => { let mplace = op.assert_mem_place(self.ecx); // strings are never immediate - try_validation!(self.ecx.read_str(mplace), - "uninitialized or non-UTF-8 data in str", self.path); + try_validation!( + self.ecx.read_str(mplace), + "uninitialized or non-UTF-8 data in str", + self.path + ); } ty::Array(tys, ..) | ty::Slice(tys) if { From 23b0c470244e612206486bb51f687ef4f6b6e117 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 27 Dec 2019 00:52:12 +0100 Subject: [PATCH 0032/1253] Ensure we don't accidentally turn non-zsts into zsts --- src/librustc_mir/const_eval/eval_queries.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index b0add10dcac43..9fbb6e1a39d90 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -125,6 +125,7 @@ pub(super) fn op_to_const<'tcx>( } Scalar::Raw { data, .. } => { assert_eq!(data, mplace.layout.align.abi.bytes().into()); + assert!(mplace.layout.is_zst()); ConstValue::Scalar(Scalar::zst()) } }; From a1990db7c68ead195d1ddf4b245e3c0e6f721fbc Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 27 Dec 2019 00:58:48 +0100 Subject: [PATCH 0033/1253] Remove a bunch of dead functions and make some functions private --- src/librustc_mir/interpret/operand.rs | 24 ------------------------ src/librustc_mir/interpret/place.rs | 16 +++------------- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 00aecf74c7d3d..ddd9776e89383 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -153,30 +153,6 @@ pub enum Operand { Indirect(MemPlace), } -impl Operand { - #[inline] - pub fn assert_mem_place(self) -> MemPlace - where - Tag: ::std::fmt::Debug, - { - match self { - Operand::Indirect(mplace) => mplace, - _ => bug!("assert_mem_place: expected Operand::Indirect, got {:?}", self), - } - } - - #[inline] - pub fn assert_immediate(self) -> Immediate - where - Tag: ::std::fmt::Debug, - { - match self { - Operand::Immediate(imm) => imm, - _ => bug!("assert_immediate: expected Operand::Immediate, got {:?}", self), - } - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct OpTy<'tcx, Tag = ()> { op: Operand, // Keep this private; it helps enforce invariants. diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 6d848092defe5..f5e8d052b21f1 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -131,13 +131,13 @@ impl MemPlace { } #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { + fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { MemPlace { ptr, align, meta: MemPlaceMeta::None } } /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] - pub fn null(cx: &impl HasDataLayout) -> Self { + fn null(cx: &impl HasDataLayout) -> Self { Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1).unwrap()) } @@ -263,20 +263,10 @@ impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { impl Place { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] - pub fn null(cx: &impl HasDataLayout) -> Self { + fn null(cx: &impl HasDataLayout) -> Self { Place::Ptr(MemPlace::null(cx)) } - #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { - Place::Ptr(MemPlace::from_scalar_ptr(ptr, align)) - } - - #[inline(always)] - pub fn from_ptr(ptr: Pointer, align: Align) -> Self { - Place::Ptr(MemPlace::from_ptr(ptr, align)) - } - #[inline] pub fn assert_mem_place(self) -> MemPlace { match self { From f7f59522b6354d66cf1f08ff0b665d3699acd98c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 27 Dec 2019 01:00:05 +0100 Subject: [PATCH 0034/1253] Add warning label to `try_as_mplace` --- src/librustc_mir/interpret/place.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index f5e8d052b21f1..1f7db45ccff56 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -241,6 +241,8 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { // These are defined here because they produce a place. impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { #[inline(always)] + /// Note: do not call `as_ref` on the resulting place. This function should only be used to + /// read from the resulting mplace, not to get its address back. pub fn try_as_mplace( self, cx: &impl HasDataLayout, @@ -255,6 +257,8 @@ impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { } #[inline(always)] + /// Note: do not call `as_ref` on the resulting place. This function should only be used to + /// read from the resulting mplace, not to get its address back. pub fn assert_mem_place(self, cx: &impl HasDataLayout) -> MPlaceTy<'tcx, Tag> { self.try_as_mplace(cx).unwrap() } From 29c372bf8b612dd9e23eb2503a1f1167e2f2f47c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 7 Jan 2020 15:51:43 +0100 Subject: [PATCH 0035/1253] Add more documentation --- src/librustc_mir/const_eval/eval_queries.rs | 7 ++++++- src/librustc_mir/interpret/place.rs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 9fbb6e1a39d90..d2a0798249ad9 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -124,7 +124,12 @@ pub(super) fn op_to_const<'tcx>( ConstValue::ByRef { alloc, offset: ptr.offset } } Scalar::Raw { data, .. } => { - assert_eq!(data, mplace.layout.align.abi.bytes().into()); + assert_eq!( + data, + mplace.layout.align.abi.bytes().into(), + "this MPlaceTy must come from `try_as_mplace` being used on a zst, so we know what + value this integer address must have", + ); assert!(mplace.layout.is_zst()); ConstValue::Scalar(Scalar::zst()) } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 1f7db45ccff56..69563c5a08de1 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -21,7 +21,9 @@ use super::{ }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] +/// Information required for the sound usage of a `MemPlace`. pub enum MemPlaceMeta { + /// The unsized payload (e.g. length for slices or vtable pointer for trait objects). Unsized(Scalar), /// `Sized` types or unsized `extern type` None, From d0b24e5ee292cc785401c880f21b690f5f3fa1d6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 7 Jan 2020 15:59:14 +0100 Subject: [PATCH 0036/1253] Actually use the poison value --- src/librustc_mir/interpret/place.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 69563c5a08de1..6428caa8fb0ed 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -180,13 +180,9 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { /// Produces a MemPlace that works for ZST but nothing else #[inline] pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { - MPlaceTy { - mplace: MemPlace::from_scalar_ptr( - Scalar::from_uint(layout.align.abi.bytes(), cx.pointer_size()), - layout.align.abi, - ), - layout, - } + let align = layout.align.abi; + let ptr = Scalar::from_uint(align.bytes(), cx.pointer_size()); + MPlaceTy { mplace: MemPlace { ptr, align, meta: MemPlaceMeta::Poison }, layout } } /// Replace ptr tag, maintain vtable tag (if any) From 093fb856a32c93941db9297cc452444d9c628ce4 Mon Sep 17 00:00:00 2001 From: maik Date: Tue, 7 Jan 2020 16:20:58 +0100 Subject: [PATCH 0037/1253] Always export static variables as SymbolExportLevel::C in wasm --- src/librustc_codegen_ssa/back/symbol_export.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 9cf0f0a801e1a..a406b5f103b9d 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -345,16 +345,11 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel if is_extern && !std_internal { let target = &tcx.sess.target.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level - if target.contains("wasm32") || target.contains("emscripten") { + if target.contains("emscripten") { if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = tcx.hir().get_if_local(sym_def_id) { - let export_level = if tcx.type_of(sym_def_id).is_scalar() { - SymbolExportLevel::C - } else { - SymbolExportLevel::Rust - }; - return export_level; + return SymbolExportLevel::Rust; } } From a526c8d7fd3740723b35b708eaa3c1bc7be3f928 Mon Sep 17 00:00:00 2001 From: Maik Klein Date: Tue, 7 Jan 2020 19:37:24 +0100 Subject: [PATCH 0038/1253] Add tests for static variables --- .../run-make/wasm-export-all-symbols/bar.rs | 3 +++ .../wasm-export-all-symbols/verify.js | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/test/run-make/wasm-export-all-symbols/bar.rs b/src/test/run-make/wasm-export-all-symbols/bar.rs index c5de87e8e7230..ac9c20a57e5a4 100644 --- a/src/test/run-make/wasm-export-all-symbols/bar.rs +++ b/src/test/run-make/wasm-export-all-symbols/bar.rs @@ -2,3 +2,6 @@ #[no_mangle] pub extern fn foo() {} + +#[no_mangle] +pub static FOO: u64 = 42; diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js index 7b6fc7a45682b..589796206132d 100644 --- a/src/test/run-make/wasm-export-all-symbols/verify.js +++ b/src/test/run-make/wasm-export-all-symbols/verify.js @@ -8,21 +8,31 @@ let list = WebAssembly.Module.exports(m); console.log('exports', list); const my_exports = {}; -let nexports = 0; +let nexports_fn = 0; +let nexports_global = 0; for (const entry of list) { - if (entry.kind !== 'function') - continue; - my_exports[entry.name] = true; - nexports += 1; + if (entry.kind == 'function'){ + nexports_fn += 1; + } + if (entry.kind == 'global'){ + nexports_global += 1; + } + my_exports[entry.name] = true; } if (my_exports.foo === undefined) throw new Error("`foo` wasn't defined"); +if (my_exports.FOO === undefined) + throw new Error("`FOO` wasn't defined"); + if (my_exports.main === undefined) { - if (nexports != 1) + if (nexports_fn != 1) throw new Error("should only have one function export"); } else { - if (nexports != 2) + if (nexports_fn != 2) throw new Error("should only have two function exports"); } + +if (nexports_global != 1) + throw new Error("should only have one static export"); From eddb3f0668398a6a9cdd90fa111f5ea569b395de Mon Sep 17 00:00:00 2001 From: Maik Klein Date: Tue, 7 Jan 2020 19:41:59 +0100 Subject: [PATCH 0039/1253] Fix indentation --- src/test/run-make/wasm-export-all-symbols/verify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js index 589796206132d..cfb7817c5404a 100644 --- a/src/test/run-make/wasm-export-all-symbols/verify.js +++ b/src/test/run-make/wasm-export-all-symbols/verify.js @@ -17,7 +17,7 @@ for (const entry of list) { if (entry.kind == 'global'){ nexports_global += 1; } - my_exports[entry.name] = true; + my_exports[entry.name] = true; } if (my_exports.foo === undefined) From 2fd4e76d88373b5ea3c3a96345c69cbcc8f56deb Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:02:22 +0100 Subject: [PATCH 0040/1253] Explicitly include InitializePasses.h --- src/rustllvm/PassWrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 6698e5d58be2f..c7c468c2c77c2 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -8,6 +8,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/InitializePasses.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/IntrinsicInst.h" From 3ec3aa72d4ce2914d04f9dca401f38284be2c2c7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:05:34 +0100 Subject: [PATCH 0041/1253] CodeGenFileType moved outside TargetMachine --- src/rustllvm/PassWrapper.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index c7c468c2c77c2..4491bb5fcce50 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -533,6 +533,18 @@ enum class LLVMRustFileType { ObjectFile, }; +#if LLVM_VERSION_GE(10, 0) +static CodeGenFileType fromRust(LLVMRustFileType Type) { + switch (Type) { + case LLVMRustFileType::AssemblyFile: + return CGFT_AssemblyFile; + case LLVMRustFileType::ObjectFile: + return CGFT_ObjectFile; + default: + report_fatal_error("Bad FileType."); + } +} +#else static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) { switch (Type) { case LLVMRustFileType::AssemblyFile: @@ -543,6 +555,7 @@ static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) { report_fatal_error("Bad FileType."); } } +#endif extern "C" LLVMRustResult LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR, From 30ec68a545ebc128ea8009186249b5b3616c3586 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:08:25 +0100 Subject: [PATCH 0042/1253] Handle removal of llvm::make_unique() --- src/rustllvm/ArchiveWrapper.cpp | 4 ++++ src/rustllvm/Linker.cpp | 3 +-- src/rustllvm/PassWrapper.cpp | 8 ++++++++ src/rustllvm/RustWrapper.cpp | 4 ++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index dd0111d3f2c83..678d787571ed7 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -89,7 +89,11 @@ extern "C" void LLVMRustDestroyArchive(LLVMRustArchiveRef RustArchive) { extern "C" LLVMRustArchiveIteratorRef LLVMRustArchiveIteratorNew(LLVMRustArchiveRef RustArchive) { Archive *Archive = RustArchive->getBinary(); +#if LLVM_VERSION_GE(10, 0) + std::unique_ptr Err = std::make_unique(Error::success()); +#else std::unique_ptr Err = llvm::make_unique(Error::success()); +#endif auto Cur = Archive->child_begin(*Err); if (*Err) { LLVMRustSetLastError(toString(std::move(*Err)).c_str()); diff --git a/src/rustllvm/Linker.cpp b/src/rustllvm/Linker.cpp index 7916721943a5f..69176f9cb1f6d 100644 --- a/src/rustllvm/Linker.cpp +++ b/src/rustllvm/Linker.cpp @@ -18,8 +18,7 @@ extern "C" RustLinker* LLVMRustLinkerNew(LLVMModuleRef DstRef) { Module *Dst = unwrap(DstRef); - auto Ret = llvm::make_unique(*Dst); - return Ret.release(); + return new RustLinker(*Dst); } extern "C" void diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 4491bb5fcce50..162193c0db79f 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -863,7 +863,11 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules, const char **preserved_symbols, int num_symbols) { +#if LLVM_VERSION_GE(10, 0) + auto Ret = std::make_unique(); +#else auto Ret = llvm::make_unique(); +#endif // Load each module's summary and merge it into one combined index for (int i = 0; i < num_modules; i++) { @@ -1095,7 +1099,11 @@ struct LLVMRustThinLTOBuffer { extern "C" LLVMRustThinLTOBuffer* LLVMRustThinLTOBufferCreate(LLVMModuleRef M) { +#if LLVM_VERSION_GE(10, 0) + auto Ret = std::make_unique(); +#else auto Ret = llvm::make_unique(); +#endif { raw_string_ostream OS(Ret->data); { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 720928e48e382..224197a905ece 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1450,7 +1450,11 @@ struct LLVMRustModuleBuffer { extern "C" LLVMRustModuleBuffer* LLVMRustModuleBufferCreate(LLVMModuleRef M) { +#if LLVM_VERSION_GE(10, 0) + auto Ret = std::make_unique(); +#else auto Ret = llvm::make_unique(); +#endif { raw_string_ostream OS(Ret->data); { From 8010f4037a3f8a875d121224f2e02914e941c257 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:14:31 +0100 Subject: [PATCH 0043/1253] Update thinLTOInternalizeAndPromoteInIndex() usage --- src/rustllvm/PassWrapper.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 162193c0db79f..eaa845a279fe8 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -962,6 +962,15 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, ExportedGUIDs.insert(GUID); } } +#if LLVM_VERSION_GE(10, 0) + auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) { + const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier); + return (ExportList != Ret->ExportLists.end() && + ExportList->second.count(VI)) || + ExportedGUIDs.count(VI.getGUID()); + }; + thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing); +#else auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier); return (ExportList != Ret->ExportLists.end() && @@ -969,6 +978,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, ExportedGUIDs.count(GUID); }; thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported); +#endif return Ret.release(); } From f77f338151692e218c9e180e6518c64f6e7cc75a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:17:11 +0100 Subject: [PATCH 0044/1253] Don't handle removed FlagBlockByrefStruct --- src/rustllvm/RustWrapper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 224197a905ece..dfd5da2335dbc 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -496,9 +496,11 @@ static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) { Result |= DINode::DIFlags::FlagAppleBlock; } +#if LLVM_VERSION_LT(10, 0) if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) { Result |= DINode::DIFlags::FlagBlockByrefStruct; } +#endif if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) { Result |= DINode::DIFlags::FlagVirtual; } From aa9d02ea539ceb0bcb225d8462316bf22b6bffd8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:23:53 +0100 Subject: [PATCH 0045/1253] Pass isDefined parameter to createGlobalVariableExpression() --- src/rustllvm/RustWrapper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index dfd5da2335dbc..78feb9194d76c 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -827,6 +827,9 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression( unwrapDI(Context), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, +#if LLVM_VERSION_GE(10, 0) + /* isDefined */ true, +#endif InitExpr, unwrapDIPtr(Decl), #if LLVM_VERSION_GE(8, 0) /* templateParams */ nullptr, From 6d59017132d32c000b707d5ba51f785a78d49b02 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:28:56 +0100 Subject: [PATCH 0046/1253] Handle switch to Expected for section name --- src/rustllvm/RustWrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 78feb9194d76c..5daca9729bf2e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1003,11 +1003,19 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **Ptr) { +#if LLVM_VERSION_GE(10, 0) + auto NameOrErr = (*unwrap(SI))->getName(); + if (!NameOrErr) + report_fatal_error(NameOrErr.takeError()); + *Ptr = NameOrErr->data(); + return NameOrErr->size(); +#else StringRef Ret; if (std::error_code EC = (*unwrap(SI))->getName(Ret)) report_fatal_error(EC.message()); *Ptr = Ret.data(); return Ret.size(); +#endif } // LLVMArrayType function does not support 64-bit ElementCount From c3ab84bb4f26d813c53336014ef08573a9d3018a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 14:32:01 +0100 Subject: [PATCH 0047/1253] Switch to using MaybeAlign APIs The integer versions are deprecated --- src/rustllvm/RustWrapper.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 5daca9729bf2e..46e467011b91a 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1266,20 +1266,34 @@ extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool IsVolatile) { +#if LLVM_VERSION_GE(10, 0) + return wrap(unwrap(B)->CreateMemCpy( + unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), + unwrap(Size), IsVolatile)); +#else return wrap(unwrap(B)->CreateMemCpy( unwrap(Dst), DstAlign, unwrap(Src), SrcAlign, unwrap(Size), IsVolatile)); +#endif } extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool IsVolatile) { +#if LLVM_VERSION_GE(10, 0) + return wrap(unwrap(B)->CreateMemMove( + unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), + unwrap(Size), IsVolatile)); +#else return wrap(unwrap(B)->CreateMemMove( unwrap(Dst), DstAlign, unwrap(Src), SrcAlign, unwrap(Size), IsVolatile)); +#endif } extern "C" LLVMValueRef From 31aecccbcd8c043bfe249cfae9e7c6ef6ffd46fd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 15:18:53 +0100 Subject: [PATCH 0048/1253] Auto-upgrade data layouts for X86 address spaces This is similar to the autoupdate LLVM performs internally. --- src/librustc_codegen_llvm/context.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index f07601ed383fe..ad8aac3ea7f16 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -143,6 +143,22 @@ fn strip_function_ptr_alignment(data_layout: String) -> String { data_layout.replace("-Fi8-", "-") } +fn strip_x86_address_spaces(data_layout: String) -> String { + data_layout.replace("-p270:32:32-p271:32:32-p272:64:64-", "-") +} + +fn add_x86_address_spaces(mut data_layout: String) -> String { + let address_spaces = "-p270:32:32-p271:32:32-p272:64:64"; + if !data_layout.contains(address_spaces) && data_layout.starts_with("e-m:") { + let mut insert_pos = "e-m:?".len(); + if data_layout[insert_pos..].starts_with("-p:32:32") { + insert_pos += "-p:32:32".len(); + } + data_layout.insert_str(insert_pos, address_spaces); + } + data_layout +} + pub unsafe fn create_module( tcx: TyCtxt<'_>, llcx: &'ll llvm::Context, @@ -156,6 +172,13 @@ pub unsafe fn create_module( if llvm_util::get_major_version() < 9 { target_data_layout = strip_function_ptr_alignment(target_data_layout); } + if sess.target.target.arch == "x86" || sess.target.target.arch == "x86_64" { + if llvm_util::get_major_version() < 10 { + target_data_layout = strip_x86_address_spaces(target_data_layout); + } else { + target_data_layout = add_x86_address_spaces(target_data_layout); + } + } // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { From 3d8f454cd00c79f8c3c65dbd4252a6c711bd73f9 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 15:52:17 +0100 Subject: [PATCH 0049/1253] Update bool-cmp.rs codegen --- src/test/codegen/bool-cmp.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/bool-cmp.rs b/src/test/codegen/bool-cmp.rs index 8769a4cb5e189..5090f7c378c36 100644 --- a/src/test/codegen/bool-cmp.rs +++ b/src/test/codegen/bool-cmp.rs @@ -10,8 +10,9 @@ use std::cmp::Ordering; // CHECK-LABEL: @cmp_bool #[no_mangle] pub fn cmp_bool(a: bool, b: bool) -> Ordering { +// LLVM 10 produces (zext a) + (sext b), but the final lowering is (zext a) - (zext b). // CHECK: zext i1 -// CHECK: zext i1 -// CHECK: sub nsw +// CHECK: {{z|s}}ext i1 +// CHECK: {{sub|add}} nsw a.cmp(&b) } From e365bc74355b4d6fc7fbc1f2fa2de778a92f2d87 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 16:05:11 +0100 Subject: [PATCH 0050/1253] Update codegen tests with unnamed arguments --- src/test/codegen/abi-main-signature-32bit-c-int.rs | 2 +- src/test/codegen/function-arguments.rs | 4 ++-- src/test/codegen/naked-functions.rs | 4 ++-- src/test/codegen/repr-transparent-sysv64.rs | 4 ++-- src/test/codegen/union-abi.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/codegen/abi-main-signature-32bit-c-int.rs b/src/test/codegen/abi-main-signature-32bit-c-int.rs index c7aab09edec71..a7a4520ff9545 100644 --- a/src/test/codegen/abi-main-signature-32bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-32bit-c-int.rs @@ -7,4 +7,4 @@ fn main() { } -// CHECK: define i32 @main(i32, i8**) +// CHECK: define i32 @main(i32{{( %0)?}}, i8**{{( %1)?}}) diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index 5c9aa48c0a5d6..3511c7c5185ee 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -73,7 +73,7 @@ pub fn _box(x: Box) -> Box { x } -// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32)) +// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32){{( %0)?}}) #[no_mangle] pub fn struct_return() -> S { S { @@ -117,7 +117,7 @@ pub fn str(_: &[u8]) { pub fn trait_borrow(_: &Drop) { } -// CHECK: @trait_box({}* noalias nonnull align 1, [3 x [[USIZE]]]* noalias readonly align {{.*}} dereferenceable({{.*}})) +// CHECK: @trait_box({}* noalias nonnull align 1{{( %0)?}}, [3 x [[USIZE]]]* noalias readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}}) #[no_mangle] pub fn trait_box(_: Box) { } diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index 2050193b61b54..5050ed1499414 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -17,7 +17,7 @@ pub fn naked_empty() { // CHECK: Function Attrs: naked #[no_mangle] #[naked] -// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+}}) +// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %0)?}}) pub fn naked_with_args(a: isize) { // CHECK-NEXT: {{.+}}: // CHECK-NEXT: %a = alloca i{{[0-9]+}} @@ -36,7 +36,7 @@ pub fn naked_with_return() -> isize { } // CHECK: Function Attrs: naked -// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}}) +// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %0)?}}) #[no_mangle] #[naked] pub fn naked_with_args_and_return(a: isize) -> isize { diff --git a/src/test/codegen/repr-transparent-sysv64.rs b/src/test/codegen/repr-transparent-sysv64.rs index b71cb14a4ff08..886b0dd9e7b08 100644 --- a/src/test/codegen/repr-transparent-sysv64.rs +++ b/src/test/codegen/repr-transparent-sysv64.rs @@ -10,7 +10,7 @@ pub struct Rgb8 { r: u8, g: u8, b: u8 } #[repr(transparent)] pub struct Rgb8Wrap(Rgb8); -// CHECK: i24 @test_Rgb8Wrap(i24) +// CHECK: i24 @test_Rgb8Wrap(i24{{( %0)?}}) #[no_mangle] pub extern "sysv64" fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} } @@ -23,6 +23,6 @@ pub union FloatBits { #[repr(transparent)] pub struct SmallUnion(FloatBits); -// CHECK: i32 @test_SmallUnion(i32) +// CHECK: i32 @test_SmallUnion(i32{{( %0)?}}) #[no_mangle] pub extern "sysv64" fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} } diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs index 98a9ff9cbe441..afea01e9a2d03 100644 --- a/src/test/codegen/union-abi.rs +++ b/src/test/codegen/union-abi.rs @@ -54,7 +54,7 @@ pub fn test_UnionF32F32(_: UnionF32F32) -> UnionF32F32 { loop {} } pub union UnionF32U32{a:f32, b:u32} -// CHECK: define i32 @test_UnionF32U32(i32) +// CHECK: define i32 @test_UnionF32U32(i32{{( %0)?}}) #[no_mangle] pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { loop {} } From f2ad997921f56f2b7a479eb6a77ad562f11fa531 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 16:07:44 +0100 Subject: [PATCH 0051/1253] Handle extra attributes in repeat-trusted-len.rs test --- src/test/codegen/repeat-trusted-len.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs index 99f3464c0768d..8fbe712065bde 100644 --- a/src/test/codegen/repeat-trusted-len.rs +++ b/src/test/codegen/repeat-trusted-len.rs @@ -13,6 +13,6 @@ pub fn helper(_: usize) { // CHECK-LABEL: @repeat_take_collect #[no_mangle] pub fn repeat_take_collect() -> Vec { -// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1 %{{[0-9]+}}, i8 42, [[USIZE]] 100000, i1 false) +// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1{{.*}} %{{[0-9]+}}, i8 42, [[USIZE]] 100000, i1 false) iter::repeat(42).take(100000).collect() } From 00daf2dabc00646ebf92b6b9007558d6f67fb85a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 31 Dec 2019 16:09:14 +0100 Subject: [PATCH 0052/1253] Account for pointer type suffix in prefetch test --- src/test/codegen/intrinsics/prefetch.rs | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/test/codegen/intrinsics/prefetch.rs b/src/test/codegen/intrinsics/prefetch.rs index 4cd38e142824a..2386fc43007a2 100644 --- a/src/test/codegen/intrinsics/prefetch.rs +++ b/src/test/codegen/intrinsics/prefetch.rs @@ -9,13 +9,13 @@ use std::intrinsics::{prefetch_read_data, prefetch_write_data, #[no_mangle] pub fn check_prefetch_read_data(data: &[i8]) { unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 0, i32 1) prefetch_read_data(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 1, i32 1) prefetch_read_data(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 2, i32 1) prefetch_read_data(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 3, i32 1) prefetch_read_data(data.as_ptr(), 3); } } @@ -23,13 +23,13 @@ pub fn check_prefetch_read_data(data: &[i8]) { #[no_mangle] pub fn check_prefetch_write_data(data: &[i8]) { unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 0, i32 1) prefetch_write_data(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 1, i32 1) prefetch_write_data(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 2, i32 1) prefetch_write_data(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 3, i32 1) prefetch_write_data(data.as_ptr(), 3); } } @@ -37,13 +37,13 @@ pub fn check_prefetch_write_data(data: &[i8]) { #[no_mangle] pub fn check_prefetch_read_instruction(data: &[i8]) { unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 0, i32 0) prefetch_read_instruction(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 1, i32 0) prefetch_read_instruction(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 2, i32 0) prefetch_read_instruction(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 0, i32 3, i32 0) prefetch_read_instruction(data.as_ptr(), 3); } } @@ -51,13 +51,13 @@ pub fn check_prefetch_read_instruction(data: &[i8]) { #[no_mangle] pub fn check_prefetch_write_instruction(data: &[i8]) { unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 0, i32 0) prefetch_write_instruction(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 1, i32 0) prefetch_write_instruction(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 2, i32 0) prefetch_write_instruction(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0) + // CHECK: call void @llvm.prefetch{{.*}}(i8* %{{.*}}, i32 1, i32 3, i32 0) prefetch_write_instruction(data.as_ptr(), 3); } } From b27b1d8efc49ba9a0eec014a620b14b9a95fe12f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 3 Jan 2020 22:49:41 +0100 Subject: [PATCH 0053/1253] Remove legacy debuginfo tests These are no longer relevant, as our minimum supported version is LLVM 7. --- src/test/debuginfo/borrowed-enum-legacy.rs | 84 ------- ...c-enum-with-different-disr-sizes-legacy.rs | 105 -------- .../generic-struct-style-enum-legacy.rs | 86 ------- .../generic-tuple-style-enum-legacy.rs | 108 -------- src/test/debuginfo/recursive-struct-legacy.rs | 235 ------------------ .../debuginfo/struct-style-enum-legacy.rs | 105 -------- src/test/debuginfo/tuple-style-enum-legacy.rs | 105 -------- src/test/debuginfo/unique-enum-legacy.rs | 88 ------- 8 files changed, 916 deletions(-) delete mode 100644 src/test/debuginfo/borrowed-enum-legacy.rs delete mode 100644 src/test/debuginfo/generic-enum-with-different-disr-sizes-legacy.rs delete mode 100644 src/test/debuginfo/generic-struct-style-enum-legacy.rs delete mode 100644 src/test/debuginfo/generic-tuple-style-enum-legacy.rs delete mode 100644 src/test/debuginfo/recursive-struct-legacy.rs delete mode 100644 src/test/debuginfo/struct-style-enum-legacy.rs delete mode 100644 src/test/debuginfo/tuple-style-enum-legacy.rs delete mode 100644 src/test/debuginfo/unique-enum-legacy.rs diff --git a/src/test/debuginfo/borrowed-enum-legacy.rs b/src/test/debuginfo/borrowed-enum-legacy.rs deleted file mode 100644 index 9a973ed74e867..0000000000000 --- a/src/test/debuginfo/borrowed-enum-legacy.rs +++ /dev/null @@ -1,84 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 7.11.90 - 7.12.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:run - -// gdb-command:print *the_a_ref -// gdbg-check:$1 = {{RUST$ENUM$DISR = TheA, x = 0, y = 8970181431921507452}, {RUST$ENUM$DISR = TheA, [...]}} -// gdbr-check:$1 = borrowed_enum_legacy::ABC::TheA{x: 0, y: 8970181431921507452} - -// gdb-command:print *the_b_ref -// gdbg-check:$2 = {{RUST$ENUM$DISR = TheB, [...]}, {RUST$ENUM$DISR = TheB, __0 = 0, __1 = 286331153, __2 = 286331153}} -// gdbr-check:$2 = borrowed_enum_legacy::ABC::TheB(0, 286331153, 286331153) - -// gdb-command:print *univariant_ref -// gdbg-check:$3 = {{__0 = 4820353753753434}} -// gdbr-check:$3 = borrowed_enum_legacy::Univariant::TheOnlyCase(4820353753753434) - - -// === LLDB TESTS ================================================================================== - -// lldb-command:run - -// lldb-command:print *the_a_ref -// lldbg-check:[...]$0 = TheA { x: 0, y: 8970181431921507452 } -// lldbr-check:(borrowed_enum_legacy::ABC::TheA) *the_a_ref = TheA { borrowed_enum_legacy::ABC::TheA: 0, borrowed_enum_legacy::ABC::TheB: 8970181431921507452 } -// lldb-command:print *the_b_ref -// lldbg-check:[...]$1 = TheB(0, 286331153, 286331153) -// lldbr-check:(borrowed_enum_legacy::ABC::TheB) *the_b_ref = { = 0 = 286331153 = 286331153 } -// lldb-command:print *univariant_ref -// lldbg-check:[...]$2 = TheOnlyCase(4820353753753434) -// lldbr-check:(borrowed_enum_legacy::Univariant) *univariant_ref = { borrowed_enum_legacy::TheOnlyCase = { = 4820353753753434 } } - -#![allow(unused_variables)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum ABC { - TheA { x: i64, y: i64 }, - TheB (i64, i32, i32), -} - -// This is a special case since it does not have the implicit discriminant field. -enum Univariant { - TheOnlyCase(i64) -} - -fn main() { - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let the_a = ABC::TheA { x: 0, y: 8970181431921507452 }; - let the_a_ref: &ABC = &the_a; - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let the_b = ABC::TheB (0, 286331153, 286331153); - let the_b_ref: &ABC = &the_b; - - let univariant = Univariant::TheOnlyCase(4820353753753434); - let univariant_ref: &Univariant = &univariant; - - zzz(); // #break -} - -fn zzz() {()} diff --git a/src/test/debuginfo/generic-enum-with-different-disr-sizes-legacy.rs b/src/test/debuginfo/generic-enum-with-different-disr-sizes-legacy.rs deleted file mode 100644 index 4f17e48c6a437..0000000000000 --- a/src/test/debuginfo/generic-enum-with-different-disr-sizes-legacy.rs +++ /dev/null @@ -1,105 +0,0 @@ -// ignore-tidy-linelength -// ignore-lldb: FIXME(#27089) -// min-lldb-version: 310 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== -// gdb-command:run - -// gdb-command:print eight_bytes1 -// gdbg-check:$1 = {{RUST$ENUM$DISR = Variant1, __0 = 100}, {RUST$ENUM$DISR = Variant1, __0 = 100}} -// gdbr-check:$1 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant1(100) - -// gdb-command:print four_bytes1 -// gdbg-check:$2 = {{RUST$ENUM$DISR = Variant1, __0 = 101}, {RUST$ENUM$DISR = Variant1, __0 = 101}} -// gdbr-check:$2 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant1(101) - -// gdb-command:print two_bytes1 -// gdbg-check:$3 = {{RUST$ENUM$DISR = Variant1, __0 = 102}, {RUST$ENUM$DISR = Variant1, __0 = 102}} -// gdbr-check:$3 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant1(102) - -// gdb-command:print one_byte1 -// gdbg-check:$4 = {{RUST$ENUM$DISR = Variant1, __0 = 65 'A'}, {RUST$ENUM$DISR = Variant1, __0 = 65 'A'}} -// gdbr-check:$4 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant1(65) - - -// gdb-command:print eight_bytes2 -// gdbg-check:$5 = {{RUST$ENUM$DISR = Variant2, __0 = 100}, {RUST$ENUM$DISR = Variant2, __0 = 100}} -// gdbr-check:$5 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant2(100) - -// gdb-command:print four_bytes2 -// gdbg-check:$6 = {{RUST$ENUM$DISR = Variant2, __0 = 101}, {RUST$ENUM$DISR = Variant2, __0 = 101}} -// gdbr-check:$6 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant2(101) - -// gdb-command:print two_bytes2 -// gdbg-check:$7 = {{RUST$ENUM$DISR = Variant2, __0 = 102}, {RUST$ENUM$DISR = Variant2, __0 = 102}} -// gdbr-check:$7 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant2(102) - -// gdb-command:print one_byte2 -// gdbg-check:$8 = {{RUST$ENUM$DISR = Variant2, __0 = 65 'A'}, {RUST$ENUM$DISR = Variant2, __0 = 65 'A'}} -// gdbr-check:$8 = generic_enum_with_different_disr_sizes_legacy::Enum::Variant2(65) - -// gdb-command:continue - -// === LLDB TESTS ================================================================================== -// lldb-command:run - -// lldb-command:print eight_bytes1 -// lldb-check:[...]$0 = Variant1(100) -// lldb-command:print four_bytes1 -// lldb-check:[...]$1 = Variant1(101) -// lldb-command:print two_bytes1 -// lldb-check:[...]$2 = Variant1(102) -// lldb-command:print one_byte1 -// lldb-check:[...]$3 = Variant1('A') - -// lldb-command:print eight_bytes2 -// lldb-check:[...]$4 = Variant2(100) -// lldb-command:print four_bytes2 -// lldb-check:[...]$5 = Variant2(101) -// lldb-command:print two_bytes2 -// lldb-check:[...]$6 = Variant2(102) -// lldb-command:print one_byte2 -// lldb-check:[...]$7 = Variant2('A') - -// lldb-command:continue - -#![allow(unused_variables)] -#![allow(dead_code)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -// This test case makes sure that we get correct type descriptions for the enum -// discriminant of different instantiations of the same generic enum type where, -// dependending on the generic type parameter(s), the discriminant has a -// different size in memory. - -enum Enum { - Variant1(T), - Variant2(T) -} - -fn main() { - // These are ordered for descending size on purpose - let eight_bytes1 = Enum::Variant1(100.0f64); - let four_bytes1 = Enum::Variant1(101i32); - let two_bytes1 = Enum::Variant1(102i16); - let one_byte1 = Enum::Variant1(65u8); - - let eight_bytes2 = Enum::Variant2(100.0f64); - let four_bytes2 = Enum::Variant2(101i32); - let two_bytes2 = Enum::Variant2(102i16); - let one_byte2 = Enum::Variant2(65u8); - - zzz(); // #break -} - -fn zzz() { () } diff --git a/src/test/debuginfo/generic-struct-style-enum-legacy.rs b/src/test/debuginfo/generic-struct-style-enum-legacy.rs deleted file mode 100644 index 37a875a4188c1..0000000000000 --- a/src/test/debuginfo/generic-struct-style-enum-legacy.rs +++ /dev/null @@ -1,86 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 -// ignore-gdb-version: 7.11.90 - 7.12.9 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// gdb-command:set print union on -// gdb-command:run - -// gdb-command:print case1 -// gdbg-check:$1 = {{RUST$ENUM$DISR = Case1, a = 0, b = 31868, c = 31868, d = 31868, e = 31868}, {RUST$ENUM$DISR = Case1, [...]}, {RUST$ENUM$DISR = Case1, [...]}} -// gdbr-check:$1 = generic_struct_style_enum_legacy::Regular::Case1{a: 0, b: 31868, c: 31868, d: 31868, e: 31868} - -// gdb-command:print case2 -// gdbg-check:$2 = {{RUST$ENUM$DISR = Case2, [...]}, {RUST$ENUM$DISR = Case2, a = 0, b = 286331153, c = 286331153}, {RUST$ENUM$DISR = Case2, [...]}} -// gdbr-check:$2 = generic_struct_style_enum_legacy::Regular::Case2{a: 0, b: 286331153, c: 286331153} - -// gdb-command:print case3 -// gdbg-check:$3 = {{RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, a = 0, b = 6438275382588823897}} -// gdbr-check:$3 = generic_struct_style_enum_legacy::Regular::Case3{a: 0, b: 6438275382588823897} - -// gdb-command:print univariant -// gdbg-check:$4 = {{a = -1}} -// gdbr-check:$4 = generic_struct_style_enum_legacy::Univariant::TheOnlyCase{a: -1} - - -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -use self::Regular::{Case1, Case2, Case3}; -use self::Univariant::TheOnlyCase; - -// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be -// substituted with something of size `xx` bits and the same alignment as an integer type of the -// same size. - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum Regular { - Case1 { a: T64, b: T16, c: T16, d: T16, e: T16}, - Case2 { a: T64, b: T32, c: T32}, - Case3 { a: T64, b: T64 } -} - -enum Univariant { - TheOnlyCase { a: T } -} - -fn main() { - - // In order to avoid endianness trouble all of the following test values consist of a single - // repeated byte. This way each interpretation of the union should look the same, no matter if - // this is a big or little endian machine. - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let case1: Regular = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 }; - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let case2: Regular = Case2 { a: 0, b: 286331153, c: 286331153 }; - - // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 - // 0b01011001010110010101100101011001 = 1499027801 - // 0b0101100101011001 = 22873 - // 0b01011001 = 89 - let case3: Regular = Case3 { a: 0, b: 6438275382588823897 }; - - let univariant = TheOnlyCase { a: -1 }; - - zzz(); // #break -} - -fn zzz() {()} diff --git a/src/test/debuginfo/generic-tuple-style-enum-legacy.rs b/src/test/debuginfo/generic-tuple-style-enum-legacy.rs deleted file mode 100644 index 452e90008ea60..0000000000000 --- a/src/test/debuginfo/generic-tuple-style-enum-legacy.rs +++ /dev/null @@ -1,108 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 -// ignore-gdb-version: 7.11.90 - 7.12.9 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:set print union on -// gdb-command:run - -// gdb-command:print case1 -// gdbg-check:$1 = {{RUST$ENUM$DISR = Case1, __0 = 0, __1 = 31868, __2 = 31868, __3 = 31868, __4 = 31868}, {RUST$ENUM$DISR = Case1, [...]}, {RUST$ENUM$DISR = Case1, [...]}} -// gdbr-check:$1 = generic_tuple_style_enum_legacy::Regular::Case1(0, 31868, 31868, 31868, 31868) - -// gdb-command:print case2 -// gdbg-check:$2 = {{RUST$ENUM$DISR = Case2, [...]}, {RUST$ENUM$DISR = Case2, __0 = 0, __1 = 286331153, __2 = 286331153}, {RUST$ENUM$DISR = Case2, [...]}} -// gdbr-check:$2 = generic_tuple_style_enum_legacy::Regular::Case2(0, 286331153, 286331153) - -// gdb-command:print case3 -// gdbg-check:$3 = {{RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, __0 = 0, __1 = 6438275382588823897}} -// gdbr-check:$3 = generic_tuple_style_enum_legacy::Regular::Case3(0, 6438275382588823897) - -// gdb-command:print univariant -// gdbg-check:$4 = {{__0 = -1}} -// gdbr-check:$4 = generic_tuple_style_enum_legacy::Univariant::TheOnlyCase(-1) - - -// === LLDB TESTS ================================================================================== - -// lldb-command:run - -// lldb-command:print case1 -// lldbg-check:[...]$0 = Case1(0, 31868, 31868, 31868, 31868) -// lldbr-check:(generic_tuple_style_enum_legacy::Regular::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 } - -// lldb-command:print case2 -// lldbg-check:[...]$1 = Case2(0, 286331153, 286331153) -// lldbr-check:(generic_tuple_style_enum_legacy::Regular::Case2) case2 = Regular::Case2 { generic_tuple_style_enum_legacy::Regular::Case1: 0, generic_tuple_style_enum_legacy::Regular::Case2: 286331153, generic_tuple_style_enum_legacy::Regular::Case3: 286331153 } - -// lldb-command:print case3 -// lldbg-check:[...]$2 = Case3(0, 6438275382588823897) -// lldbr-check:(generic_tuple_style_enum_legacy::Regular::Case3) case3 = Regular::Case3 { generic_tuple_style_enum_legacy::Regular::Case1: 0, generic_tuple_style_enum_legacy::Regular::Case2: 6438275382588823897 } - -// lldb-command:print univariant -// lldbg-check:[...]$3 = TheOnlyCase(-1) -// lldbr-check:(generic_tuple_style_enum_legacy::Univariant) univariant = { generic_tuple_style_enum_legacy::TheOnlyCase = { = -1 } } - -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -use self::Regular::{Case1, Case2, Case3}; -use self::Univariant::TheOnlyCase; - -// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be -// substituted with something of size `xx` bits and the same alignment as an integer type of the -// same size. - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum Regular { - Case1(T64, T16, T16, T16, T16), - Case2(T64, T32, T32), - Case3(T64, T64) -} - -enum Univariant { - TheOnlyCase(T64) -} - -fn main() { - - // In order to avoid endianness trouble all of the following test values consist of a single - // repeated byte. This way each interpretation of the union should look the same, no matter if - // this is a big or little endian machine. - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let case1: Regular = Case1(0_u64, 31868_u16, 31868_u16, 31868_u16, 31868_u16); - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let case2: Regular = Case2(0_i64, 286331153_i32, 286331153_i32); - - // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 - // 0b01011001010110010101100101011001 = 1499027801 - // 0b0101100101011001 = 22873 - // 0b01011001 = 89 - let case3: Regular = Case3(0_i64, 6438275382588823897_i64); - - let univariant = TheOnlyCase(-1_i64); - - zzz(); // #break -} - -fn zzz() { () } diff --git a/src/test/debuginfo/recursive-struct-legacy.rs b/src/test/debuginfo/recursive-struct-legacy.rs deleted file mode 100644 index 99286708ae243..0000000000000 --- a/src/test/debuginfo/recursive-struct-legacy.rs +++ /dev/null @@ -1,235 +0,0 @@ -// ignore-tidy-linelength -// ignore-lldb - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 7.11.90 - 7.12.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// gdb-command:run - -// gdb-command:print stack_unique.value -// gdb-check:$1 = 0 -// gdbg-command:print stack_unique.next.RUST$ENCODED$ENUM$0$Empty.val->value -// gdbr-command:print stack_unique.next.val.value -// gdb-check:$2 = 1 - -// gdbg-command:print unique_unique->value -// gdbr-command:print unique_unique.value -// gdb-check:$3 = 2 -// gdbg-command:print unique_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value -// gdbr-command:print unique_unique.next.val.value -// gdb-check:$4 = 3 - -// gdb-command:print vec_unique[0].value -// gdb-check:$5 = 6.5 -// gdbg-command:print vec_unique[0].next.RUST$ENCODED$ENUM$0$Empty.val->value -// gdbr-command:print vec_unique[0].next.val.value -// gdb-check:$6 = 7.5 - -// gdbg-command:print borrowed_unique->value -// gdbr-command:print borrowed_unique.value -// gdb-check:$7 = 8.5 -// gdbg-command:print borrowed_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value -// gdbr-command:print borrowed_unique.next.val.value -// gdb-check:$8 = 9.5 - -// LONG CYCLE -// gdb-command:print long_cycle1.value -// gdb-check:$9 = 20 -// gdbg-command:print long_cycle1.next->value -// gdbr-command:print long_cycle1.next.value -// gdb-check:$10 = 21 -// gdbg-command:print long_cycle1.next->next->value -// gdbr-command:print long_cycle1.next.next.value -// gdb-check:$11 = 22 -// gdbg-command:print long_cycle1.next->next->next->value -// gdbr-command:print long_cycle1.next.next.next.value -// gdb-check:$12 = 23 - -// gdb-command:print long_cycle2.value -// gdb-check:$13 = 24 -// gdbg-command:print long_cycle2.next->value -// gdbr-command:print long_cycle2.next.value -// gdb-check:$14 = 25 -// gdbg-command:print long_cycle2.next->next->value -// gdbr-command:print long_cycle2.next.next.value -// gdb-check:$15 = 26 - -// gdb-command:print long_cycle3.value -// gdb-check:$16 = 27 -// gdbg-command:print long_cycle3.next->value -// gdbr-command:print long_cycle3.next.value -// gdb-check:$17 = 28 - -// gdb-command:print long_cycle4.value -// gdb-check:$18 = 29.5 - -// gdbg-command:print (*****long_cycle_w_anonymous_types).value -// gdbr-command:print long_cycle_w_anonymous_types.value -// gdb-check:$19 = 30 - -// gdbg-command:print (*****((*****long_cycle_w_anonymous_types).next.RUST$ENCODED$ENUM$0$Empty.val)).value -// gdbr-command:print long_cycle_w_anonymous_types.next.val.value -// gdb-check:$20 = 31 - -// gdb-command:continue - -#![allow(unused_variables)] -#![feature(box_syntax)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -use self::Opt::{Empty, Val}; - -enum Opt { - Empty, - Val { val: T } -} - -struct UniqueNode { - next: Opt>>, - value: T -} - -struct LongCycle1 { - next: Box>, - value: T, -} - -struct LongCycle2 { - next: Box>, - value: T, -} - -struct LongCycle3 { - next: Box>, - value: T, -} - -struct LongCycle4 { - next: Option>>, - value: T, -} - -struct LongCycleWithAnonymousTypes { - next: Opt>>>>>, - value: usize, -} - -// This test case makes sure that recursive structs are properly described. The Node structs are -// generic so that we can have a new type (that newly needs to be described) for the different -// cases. The potential problem with recursive types is that the DI generation algorithm gets -// trapped in an endless loop. To make sure, we actually test this in the different cases, we have -// to operate on a new type each time, otherwise we would just hit the DI cache for all but the -// first case. - -// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description -// algorithm will enter the type reference cycle that is created by a recursive definition from a -// different context each time. - -// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types. -// The different locals will cause the DI algorithm to enter the type reference cycle at different -// points. - -fn main() { - let stack_unique: UniqueNode = UniqueNode { - next: Val { - val: box UniqueNode { - next: Empty, - value: 1, - } - }, - value: 0, - }; - - let unique_unique: Box> = box UniqueNode { - next: Val { - val: box UniqueNode { - next: Empty, - value: 3, - } - }, - value: 2, - }; - - let vec_unique: [UniqueNode; 1] = [UniqueNode { - next: Val { - val: box UniqueNode { - next: Empty, - value: 7.5, - } - }, - value: 6.5, - }]; - - let borrowed_unique: &UniqueNode = &UniqueNode { - next: Val { - val: box UniqueNode { - next: Empty, - value: 9.5, - } - }, - value: 8.5, - }; - - // LONG CYCLE - let long_cycle1: LongCycle1 = LongCycle1 { - next: box LongCycle2 { - next: box LongCycle3 { - next: box LongCycle4 { - next: None, - value: 23, - }, - value: 22, - }, - value: 21 - }, - value: 20 - }; - - let long_cycle2: LongCycle2 = LongCycle2 { - next: box LongCycle3 { - next: box LongCycle4 { - next: None, - value: 26, - }, - value: 25, - }, - value: 24 - }; - - let long_cycle3: LongCycle3 = LongCycle3 { - next: box LongCycle4 { - next: None, - value: 28, - }, - value: 27, - }; - - let long_cycle4: LongCycle4 = LongCycle4 { - next: None, - value: 29.5, - }; - - // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the - // `box` chain. - let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes { - next: Val { - val: box box box box box LongCycleWithAnonymousTypes { - next: Empty, - value: 31, - } - }, - value: 30 - }; - - zzz(); // #break -} - -fn zzz() {()} diff --git a/src/test/debuginfo/struct-style-enum-legacy.rs b/src/test/debuginfo/struct-style-enum-legacy.rs deleted file mode 100644 index 1433493fd5d0f..0000000000000 --- a/src/test/debuginfo/struct-style-enum-legacy.rs +++ /dev/null @@ -1,105 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 7.11.90 - 7.12.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:set print union on -// gdb-command:run - -// gdb-command:print case1 -// gdbg-check:$1 = {{RUST$ENUM$DISR = Case1, a = 0, b = 31868, c = 31868, d = 31868, e = 31868}, {RUST$ENUM$DISR = Case1, [...]}, {RUST$ENUM$DISR = Case1, [...]}} -// gdbr-check:$1 = struct_style_enum_legacy::Regular::Case1{a: 0, b: 31868, c: 31868, d: 31868, e: 31868} - -// gdb-command:print case2 -// gdbg-check:$2 = {{RUST$ENUM$DISR = Case2, [...]}, {RUST$ENUM$DISR = Case2, a = 0, b = 286331153, c = 286331153}, {RUST$ENUM$DISR = Case2, [...]}} -// gdbr-check:$2 = struct_style_enum_legacy::Regular::Case2{a: 0, b: 286331153, c: 286331153} - -// gdb-command:print case3 -// gdbg-check:$3 = {{RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, a = 0, b = 6438275382588823897}} -// gdbr-check:$3 = struct_style_enum_legacy::Regular::Case3{a: 0, b: 6438275382588823897} - -// gdb-command:print univariant -// gdbg-check:$4 = {{a = -1}} -// gdbr-check:$4 = struct_style_enum_legacy::Univariant::TheOnlyCase{a: -1} - - -// === LLDB TESTS ================================================================================== - -// lldb-command:run - -// lldb-command:print case1 -// lldbg-check:[...]$0 = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 } -// lldbr-check:(struct_style_enum_legacy::Regular::Case1) case1 = { a = 0 b = 31868 c = 31868 d = 31868 e = 31868 } - -// lldb-command:print case2 -// lldbg-check:[...]$1 = Case2 { a: 0, b: 286331153, c: 286331153 } -// lldbr-check:(struct_style_enum_legacy::Regular::Case2) case2 = Case2 { struct_style_enum_legacy::Regular::Case1: 0, struct_style_enum_legacy::Regular::Case2: 286331153, struct_style_enum_legacy::Regular::Case3: 286331153 } - -// lldb-command:print case3 -// lldbg-check:[...]$2 = Case3 { a: 0, b: 6438275382588823897 } -// lldbr-check:(struct_style_enum_legacy::Regular::Case3) case3 = Case3 { struct_style_enum_legacy::Regular::Case1: 0, struct_style_enum_legacy::Regular::Case2: 6438275382588823897 } - -// lldb-command:print univariant -// lldbg-check:[...]$3 = TheOnlyCase { a: -1 } -// lldbr-check:(struct_style_enum_legacy::Univariant) univariant = Univariant { struct_style_enum_legacy::TheOnlyCase: TheOnlyCase { a: -1 } } - -#![allow(unused_variables)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -use self::Regular::{Case1, Case2, Case3}; -use self::Univariant::TheOnlyCase; - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum Regular { - Case1 { a: u64, b: u16, c: u16, d: u16, e: u16}, - Case2 { a: u64, b: u32, c: u32}, - Case3 { a: u64, b: u64 } -} - -enum Univariant { - TheOnlyCase { a: i64 } -} - -fn main() { - - // In order to avoid endianness trouble all of the following test values consist of a single - // repeated byte. This way each interpretation of the union should look the same, no matter if - // this is a big or little endian machine. - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let case1 = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 }; - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let case2 = Case2 { a: 0, b: 286331153, c: 286331153 }; - - // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 - // 0b01011001010110010101100101011001 = 1499027801 - // 0b0101100101011001 = 22873 - // 0b01011001 = 89 - let case3 = Case3 { a: 0, b: 6438275382588823897 }; - - let univariant = TheOnlyCase { a: -1 }; - - zzz(); // #break -} - -fn zzz() {()} diff --git a/src/test/debuginfo/tuple-style-enum-legacy.rs b/src/test/debuginfo/tuple-style-enum-legacy.rs deleted file mode 100644 index ebc8e03443881..0000000000000 --- a/src/test/debuginfo/tuple-style-enum-legacy.rs +++ /dev/null @@ -1,105 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 7.11.90 - 7.12.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:set print union on -// gdb-command:run - -// gdb-command:print case1 -// gdbg-check:$1 = {{RUST$ENUM$DISR = Case1, __0 = 0, __1 = 31868, __2 = 31868, __3 = 31868, __4 = 31868}, {RUST$ENUM$DISR = Case1, [...]}, {RUST$ENUM$DISR = Case1, [...]}} -// gdbr-check:$1 = tuple_style_enum_legacy::Regular::Case1(0, 31868, 31868, 31868, 31868) - -// gdb-command:print case2 -// gdbg-check:$2 = {{RUST$ENUM$DISR = Case2, [...]}, {RUST$ENUM$DISR = Case2, __0 = 0, __1 = 286331153, __2 = 286331153}, {RUST$ENUM$DISR = Case2, [...]}} -// gdbr-check:$2 = tuple_style_enum_legacy::Regular::Case2(0, 286331153, 286331153) - -// gdb-command:print case3 -// gdbg-check:$3 = {{RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, [...]}, {RUST$ENUM$DISR = Case3, __0 = 0, __1 = 6438275382588823897}} -// gdbr-check:$3 = tuple_style_enum_legacy::Regular::Case3(0, 6438275382588823897) - -// gdb-command:print univariant -// gdbg-check:$4 = {{__0 = -1}} -// gdbr-check:$4 = tuple_style_enum_legacy::Univariant::TheOnlyCase(-1) - - -// === LLDB TESTS ================================================================================== - -// lldb-command:run - -// lldb-command:print case1 -// lldbg-check:[...]$0 = Case1(0, 31868, 31868, 31868, 31868) -// lldbr-check:(tuple_style_enum_legacy::Regular::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 } - -// lldb-command:print case2 -// lldbg-check:[...]$1 = Case2(0, 286331153, 286331153) -// lldbr-check:(tuple_style_enum_legacy::Regular::Case2) case2 = Case2 { tuple_style_enum_legacy::Regular::Case1: 0, tuple_style_enum_legacy::Regular::Case2: 286331153, tuple_style_enum_legacy::Regular::Case3: 286331153 } - -// lldb-command:print case3 -// lldbg-check:[...]$2 = Case3(0, 6438275382588823897) -// lldbr-check:(tuple_style_enum_legacy::Regular::Case3) case3 = Case3 { tuple_style_enum_legacy::Regular::Case1: 0, tuple_style_enum_legacy::Regular::Case2: 6438275382588823897 } - -// lldb-command:print univariant -// lldbg-check:[...]$3 = TheOnlyCase(-1) -// lldbr-check:(tuple_style_enum_legacy::Univariant) univariant = { tuple_style_enum_legacy::TheOnlyCase = { = -1 } } - -#![allow(unused_variables)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -use self::Regular::{Case1, Case2, Case3}; -use self::Univariant::TheOnlyCase; - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum Regular { - Case1(u64, u16, u16, u16, u16), - Case2(u64, u32, u32), - Case3(u64, u64) -} - -enum Univariant { - TheOnlyCase(i64) -} - -fn main() { - - // In order to avoid endianness trouble all of the following test values consist of a single - // repeated byte. This way each interpretation of the union should look the same, no matter if - // this is a big or little endian machine. - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let case1 = Case1(0, 31868, 31868, 31868, 31868); - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let case2 = Case2(0, 286331153, 286331153); - - // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 - // 0b01011001010110010101100101011001 = 1499027801 - // 0b0101100101011001 = 22873 - // 0b01011001 = 89 - let case3 = Case3(0, 6438275382588823897); - - let univariant = TheOnlyCase(-1); - - zzz(); // #break -} - -fn zzz() {()} diff --git a/src/test/debuginfo/unique-enum-legacy.rs b/src/test/debuginfo/unique-enum-legacy.rs deleted file mode 100644 index e7c9357752897..0000000000000 --- a/src/test/debuginfo/unique-enum-legacy.rs +++ /dev/null @@ -1,88 +0,0 @@ -// ignore-tidy-linelength -// min-lldb-version: 310 - -// As long as LLVM 5 and LLVM 6 are supported, we want to test the -// enum debuginfo fallback mode. Once those are desupported, this -// test can be removed, as there is another (non-"legacy") test that -// tests the new mode. -// ignore-llvm-version: 7.0 - 9.9.9 -// ignore-gdb-version: 7.11.90 - 7.12.9 -// ignore-gdb-version: 8.2 - 9.9 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:run - -// gdb-command:print *the_a -// gdbg-check:$1 = {{RUST$ENUM$DISR = TheA, x = 0, y = 8970181431921507452}, {RUST$ENUM$DISR = TheA, [...]}} -// gdbr-check:$1 = unique_enum_legacy::ABC::TheA{x: 0, y: 8970181431921507452} - -// gdb-command:print *the_b -// gdbg-check:$2 = {{RUST$ENUM$DISR = TheB, [...]}, {RUST$ENUM$DISR = TheB, __0 = 0, __1 = 286331153, __2 = 286331153}} -// gdbr-check:$2 = unique_enum_legacy::ABC::TheB(0, 286331153, 286331153) - -// gdb-command:print *univariant -// gdbg-check:$3 = {{__0 = 123234}} -// gdbr-check:$3 = unique_enum_legacy::Univariant::TheOnlyCase(123234) - - -// === LLDB TESTS ================================================================================== - -// lldb-command:run - -// lldb-command:print *the_a -// lldbg-check:[...]$0 = TheA { x: 0, y: 8970181431921507452 } -// lldbr-check:(unique_enum_legacy::ABC::TheA) *the_a = TheA { unique_enum_legacy::ABC::TheA: 0, unique_enum_legacy::ABC::TheB: 8970181431921507452 } - -// lldb-command:print *the_b -// lldbg-check:[...]$1 = TheB(0, 286331153, 286331153) -// lldbr-check:(unique_enum_legacy::ABC::TheB) *the_b = { = 0 = 286331153 = 286331153 } - -// lldb-command:print *univariant -// lldbg-check:[...]$2 = TheOnlyCase(123234) -// lldbr-check:(unique_enum_legacy::Univariant) *univariant = { unique_enum_legacy::TheOnlyCase = { = 123234 } } - -#![allow(unused_variables)] -#![feature(box_syntax)] -#![feature(omit_gdb_pretty_printer_section)] -#![omit_gdb_pretty_printer_section] - -// The first element is to ensure proper alignment, irrespective of the machines word size. Since -// the size of the discriminant value is machine dependent, this has be taken into account when -// datatype layout should be predictable as in this case. -enum ABC { - TheA { x: i64, y: i64 }, - TheB (i64, i32, i32), -} - -// This is a special case since it does not have the implicit discriminant field. -enum Univariant { - TheOnlyCase(i64) -} - -fn main() { - - // In order to avoid endianness trouble all of the following test values consist of a single - // repeated byte. This way each interpretation of the union should look the same, no matter if - // this is a big or little endian machine. - - // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 - // 0b01111100011111000111110001111100 = 2088533116 - // 0b0111110001111100 = 31868 - // 0b01111100 = 124 - let the_a: Box<_> = box ABC::TheA { x: 0, y: 8970181431921507452 }; - - // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 - // 0b00010001000100010001000100010001 = 286331153 - // 0b0001000100010001 = 4369 - // 0b00010001 = 17 - let the_b: Box<_> = box ABC::TheB (0, 286331153, 286331153); - - let univariant: Box<_> = box Univariant::TheOnlyCase(123234); - - zzz(); // #break -} - -fn zzz() {()} From 3db0015499d002f6e1dff1b615877e9131cfeb25 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 4 Jan 2020 00:13:25 +0100 Subject: [PATCH 0054/1253] Add include path when compiling profiler runtime InstrProfData.inc has been moved to include/ --- src/libprofiler_builtins/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 04cd2efe00093..852b7aac3590b 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -72,6 +72,7 @@ fn main() { cfg.file(root.join("lib").join("profile").join(src)); } + cfg.include(root.join("include")); cfg.warnings(false); cfg.compile("profiler-rt"); } From c6a7751fa7ad31702e389128c4d970324d0aa2cd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 4 Jan 2020 00:19:37 +0100 Subject: [PATCH 0055/1253] Handle changed InstrProfilingRuntime path --- src/libprofiler_builtins/build.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 852b7aac3590b..8adcff67800fe 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -21,7 +21,6 @@ fn main() { "InstrProfilingPlatformLinux.c", "InstrProfilingPlatformOther.c", "InstrProfilingPlatformWindows.c", - "InstrProfilingRuntime.cc", "InstrProfilingUtil.c", "InstrProfilingValue.c", "InstrProfilingWriter.c", @@ -68,10 +67,16 @@ fn main() { let root = env::var_os("RUST_COMPILER_RT_ROOT").unwrap(); let root = Path::new(&root); + let src_root = root.join("lib").join("profile"); for src in profile_sources { - cfg.file(root.join("lib").join("profile").join(src)); + cfg.file(src_root.join(src)); } + // The file was renamed in LLVM 10. + let old_runtime_path = src_root.join("InstrProfilingRuntime.cc"); + let new_runtime_path = src_root.join("InstrProfilingRuntime.cpp"); + cfg.file(if old_runtime_path.exists() { old_runtime_path } else { new_runtime_path }); + cfg.include(root.join("include")); cfg.warnings(false); cfg.compile("profiler-rt"); From 8b199222cc92667cd0e57595ad435cd0a7526af8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 7 Jan 2020 21:26:52 +0100 Subject: [PATCH 0056/1253] Update data layouts to include new X86 address spaces --- src/librustc_target/spec/i386_apple_ios.rs | 4 +++- src/librustc_target/spec/i686_apple_darwin.rs | 4 +++- src/librustc_target/spec/i686_linux_android.rs | 4 +++- src/librustc_target/spec/i686_pc_windows_gnu.rs | 4 +++- src/librustc_target/spec/i686_pc_windows_msvc.rs | 4 +++- src/librustc_target/spec/i686_unknown_cloudabi.rs | 4 +++- src/librustc_target/spec/i686_unknown_freebsd.rs | 4 +++- src/librustc_target/spec/i686_unknown_haiku.rs | 4 +++- src/librustc_target/spec/i686_unknown_linux_gnu.rs | 4 +++- src/librustc_target/spec/i686_unknown_linux_musl.rs | 4 +++- src/librustc_target/spec/i686_unknown_netbsd.rs | 4 +++- src/librustc_target/spec/i686_unknown_openbsd.rs | 4 +++- src/librustc_target/spec/i686_unknown_uefi.rs | 4 +++- src/librustc_target/spec/i686_uwp_windows_gnu.rs | 4 +++- src/librustc_target/spec/i686_uwp_windows_msvc.rs | 4 +++- src/librustc_target/spec/i686_wrs_vxworks.rs | 4 +++- src/librustc_target/spec/x86_64_apple_darwin.rs | 3 ++- src/librustc_target/spec/x86_64_apple_ios.rs | 3 ++- src/librustc_target/spec/x86_64_apple_ios_macabi.rs | 3 ++- src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs | 3 ++- src/librustc_target/spec/x86_64_fuchsia.rs | 3 ++- src/librustc_target/spec/x86_64_linux_android.rs | 3 ++- src/librustc_target/spec/x86_64_linux_kernel.rs | 3 ++- src/librustc_target/spec/x86_64_pc_windows_gnu.rs | 3 ++- src/librustc_target/spec/x86_64_pc_windows_msvc.rs | 3 ++- src/librustc_target/spec/x86_64_rumprun_netbsd.rs | 3 ++- src/librustc_target/spec/x86_64_sun_solaris.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_cloudabi.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_dragonfly.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_freebsd.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_haiku.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_hermit.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_linux_gnu.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs | 4 +++- src/librustc_target/spec/x86_64_unknown_linux_musl.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_netbsd.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_openbsd.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_redox.rs | 3 ++- src/librustc_target/spec/x86_64_unknown_uefi.rs | 3 ++- src/librustc_target/spec/x86_64_uwp_windows_gnu.rs | 3 ++- src/librustc_target/spec/x86_64_uwp_windows_msvc.rs | 3 ++- src/librustc_target/spec/x86_64_wrs_vxworks.rs | 3 ++- 44 files changed, 105 insertions(+), 44 deletions(-) diff --git a/src/librustc_target/spec/i386_apple_ios.rs b/src/librustc_target/spec/i386_apple_ios.rs index 51eb231a6144b..a6c1d24fa62a1 100644 --- a/src/librustc_target/spec/i386_apple_ios.rs +++ b/src/librustc_target/spec/i386_apple_ios.rs @@ -8,7 +8,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128".to_string(), + data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:128-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "ios".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 7dfb2ba992114..033b87b110e12 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -20,7 +20,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128".to_string(), + data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:128-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "macos".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_linux_android.rs b/src/librustc_target/spec/i686_linux_android.rs index 3f73d24ee848b..79242f240269c 100644 --- a/src/librustc_target/spec/i686_linux_android.rs +++ b/src/librustc_target/spec/i686_linux_android.rs @@ -18,7 +18,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "android".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs index 9056e0765d811..35fbf87573137 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -18,7 +18,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:32-n8:16:32-a:0:32-S32" + .to_string(), arch: "x86".to_string(), target_os: "windows".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs index b160007e0621a..ffb66afc76182 100644 --- a/src/librustc_target/spec/i686_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs @@ -19,7 +19,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:32-n8:16:32-a:0:32-S32" + .to_string(), arch: "x86".to_string(), target_os: "windows".to_string(), target_env: "msvc".to_string(), diff --git a/src/librustc_target/spec/i686_unknown_cloudabi.rs b/src/librustc_target/spec/i686_unknown_cloudabi.rs index f3b40633b4007..729b1f68e005c 100644 --- a/src/librustc_target/spec/i686_unknown_cloudabi.rs +++ b/src/librustc_target/spec/i686_unknown_cloudabi.rs @@ -13,7 +13,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "cloudabi".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/src/librustc_target/spec/i686_unknown_freebsd.rs index 71f05a140f3df..88c944a6cb7eb 100644 --- a/src/librustc_target/spec/i686_unknown_freebsd.rs +++ b/src/librustc_target/spec/i686_unknown_freebsd.rs @@ -12,7 +12,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "freebsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_unknown_haiku.rs b/src/librustc_target/spec/i686_unknown_haiku.rs index b807e4eee39a5..4dc27af30dadb 100644 --- a/src/librustc_target/spec/i686_unknown_haiku.rs +++ b/src/librustc_target/spec/i686_unknown_haiku.rs @@ -12,7 +12,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "haiku".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_unknown_linux_gnu.rs b/src/librustc_target/spec/i686_unknown_linux_gnu.rs index 5875cbf78bfe6..0d578f22f9825 100644 --- a/src/librustc_target/spec/i686_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/i686_unknown_linux_gnu.rs @@ -12,7 +12,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/i686_unknown_linux_musl.rs b/src/librustc_target/spec/i686_unknown_linux_musl.rs index 732949034e824..699a0ab45e872 100644 --- a/src/librustc_target/spec/i686_unknown_linux_musl.rs +++ b/src/librustc_target/spec/i686_unknown_linux_musl.rs @@ -27,7 +27,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/i686_unknown_netbsd.rs b/src/librustc_target/spec/i686_unknown_netbsd.rs index 01d2b2d76a0b9..88b1ae7d53c08 100644 --- a/src/librustc_target/spec/i686_unknown_netbsd.rs +++ b/src/librustc_target/spec/i686_unknown_netbsd.rs @@ -12,7 +12,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "netbsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_unknown_openbsd.rs b/src/librustc_target/spec/i686_unknown_openbsd.rs index d7c323e0d8a8a..829cd1ac1a397 100644 --- a/src/librustc_target/spec/i686_unknown_openbsd.rs +++ b/src/librustc_target/spec/i686_unknown_openbsd.rs @@ -13,7 +13,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "openbsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs index e4b8b667ad0db..345590a00be8b 100644 --- a/src/librustc_target/spec/i686_unknown_uefi.rs +++ b/src/librustc_target/spec/i686_unknown_uefi.rs @@ -86,7 +86,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:32-n8:16:32-a:0:32-S32" + .to_string(), target_os: "uefi".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/src/librustc_target/spec/i686_uwp_windows_gnu.rs index 1986474785f50..93f396de0a051 100644 --- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/i686_uwp_windows_gnu.rs @@ -18,7 +18,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:32-n8:16:32-a:0:32-S32" + .to_string(), arch: "x86".to_string(), target_os: "windows".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs index 5e8e8c2a4149c..ed2dba53589ed 100644 --- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs +++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs @@ -11,7 +11,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:32-n8:16:32-a:0:32-S32" + .to_string(), arch: "x86".to_string(), target_os: "windows".to_string(), target_env: "msvc".to_string(), diff --git a/src/librustc_target/spec/i686_wrs_vxworks.rs b/src/librustc_target/spec/i686_wrs_vxworks.rs index c5f9583a35856..f5f66cabb2cfd 100644 --- a/src/librustc_target/spec/i686_wrs_vxworks.rs +++ b/src/librustc_target/spec/i686_wrs_vxworks.rs @@ -12,7 +12,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .to_string(), arch: "x86".to_string(), target_os: "vxworks".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs index 002cee44218e7..e846f42f8f849 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -20,7 +20,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: arch.to_string(), target_os: "macos".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_apple_ios.rs b/src/librustc_target/spec/x86_64_apple_ios.rs index f8441f96c989d..ca02e2deabcf2 100644 --- a/src/librustc_target/spec/x86_64_apple_ios.rs +++ b/src/librustc_target/spec/x86_64_apple_ios.rs @@ -8,7 +8,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "ios".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs b/src/librustc_target/spec/x86_64_apple_ios_macabi.rs index 101d83607d91f..5f4f6ade682d8 100644 --- a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs +++ b/src/librustc_target/spec/x86_64_apple_ios_macabi.rs @@ -8,7 +8,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "ios".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs index 6105eaef7b0af..3e9552ef0cf34 100644 --- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -81,7 +81,8 @@ pub fn target() -> Result { target_os: "unknown".into(), target_env: "sgx".into(), target_vendor: "fortanix".into(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), arch: "x86_64".into(), linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, diff --git a/src/librustc_target/spec/x86_64_fuchsia.rs b/src/librustc_target/spec/x86_64_fuchsia.rs index 5b315bb957ce9..37b6d57366cf5 100644 --- a/src/librustc_target/spec/x86_64_fuchsia.rs +++ b/src/librustc_target/spec/x86_64_fuchsia.rs @@ -11,7 +11,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "fuchsia".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_linux_android.rs b/src/librustc_target/spec/x86_64_linux_android.rs index c3c6c7bf56fef..74097f5bf6f5e 100644 --- a/src/librustc_target/spec/x86_64_linux_android.rs +++ b/src/librustc_target/spec/x86_64_linux_android.rs @@ -14,7 +14,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "android".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/src/librustc_target/spec/x86_64_linux_kernel.rs index a80b021208ed7..89070c99e3941 100644 --- a/src/librustc_target/spec/x86_64_linux_kernel.rs +++ b/src/librustc_target/spec/x86_64_linux_kernel.rs @@ -19,7 +19,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), target_os: "none".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs index 35e0d55cd045e..8f523a3b6c6d9 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -11,7 +11,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "windows".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs index 073d49be5a9ab..75ff6b97a2e1e 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs @@ -11,7 +11,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "windows".to_string(), target_env: "msvc".to_string(), diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs index d71112b87de18..fbade02c55690 100644 --- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs +++ b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs @@ -18,7 +18,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "netbsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_sun_solaris.rs b/src/librustc_target/spec/x86_64_sun_solaris.rs index 3bf3f51ae2512..53f4df9651819 100644 --- a/src/librustc_target/spec/x86_64_sun_solaris.rs +++ b/src/librustc_target/spec/x86_64_sun_solaris.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "solaris".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs index d48120c5401c2..dbc5f965020e9 100644 --- a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs +++ b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs @@ -13,7 +13,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "cloudabi".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs index f55ee6969092b..fd1871b1a57c3 100644 --- a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs +++ b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "dragonfly".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_freebsd.rs b/src/librustc_target/spec/x86_64_unknown_freebsd.rs index 1d9c5cce3f729..a124f582bf3fc 100644 --- a/src/librustc_target/spec/x86_64_unknown_freebsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_freebsd.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "freebsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_haiku.rs b/src/librustc_target/spec/x86_64_unknown_haiku.rs index 4ab15fa4e90f5..51237697714a4 100644 --- a/src/librustc_target/spec/x86_64_unknown_haiku.rs +++ b/src/librustc_target/spec/x86_64_unknown_haiku.rs @@ -14,7 +14,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "haiku".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_hermit.rs b/src/librustc_target/spec/x86_64_unknown_hermit.rs index c9123aae90dda..4a526f90ed5bc 100644 --- a/src/librustc_target/spec/x86_64_unknown_hermit.rs +++ b/src/librustc_target/spec/x86_64_unknown_hermit.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "hermit".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs b/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs index 0b1c8340b6d14..c25cd0809eed8 100644 --- a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs +++ b/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs @@ -14,7 +14,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "hermit".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs index e5fdb386ef301..cab19f149a77c 100644 --- a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs +++ b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs @@ -10,7 +10,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "l4re".to_string(), target_env: "uclibc".to_string(), diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs index cb279e86f1498..29cbb777db5d7 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs index 0b2d7aacc4ddf..0a37399e2fac3 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs @@ -16,7 +16,9 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs index 2e1bc839873c7..34c628e8f67bd 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/x86_64_unknown_netbsd.rs b/src/librustc_target/spec/x86_64_unknown_netbsd.rs index b0fad314662b0..adf09c89c426b 100644 --- a/src/librustc_target/spec/x86_64_unknown_netbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_netbsd.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "netbsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_openbsd.rs b/src/librustc_target/spec/x86_64_unknown_openbsd.rs index f2abd1071227e..dbd163db36b45 100644 --- a/src/librustc_target/spec/x86_64_unknown_openbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_openbsd.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "openbsd".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/x86_64_unknown_redox.rs b/src/librustc_target/spec/x86_64_unknown_redox.rs index 8a5af27f13aac..3d40bafbe1fd4 100644 --- a/src/librustc_target/spec/x86_64_unknown_redox.rs +++ b/src/librustc_target/spec/x86_64_unknown_redox.rs @@ -12,7 +12,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "redox".to_string(), target_env: "relibc".to_string(), diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs index 443479f55f04a..7660b68aae62e 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -38,7 +38,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), target_os: "uefi".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs index da0c324e48618..48366e24a39e4 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs @@ -11,7 +11,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "windows".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs index 40dd52c159151..258df010aae0c 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs +++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs @@ -11,7 +11,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "windows".to_string(), target_env: "msvc".to_string(), diff --git a/src/librustc_target/spec/x86_64_wrs_vxworks.rs b/src/librustc_target/spec/x86_64_wrs_vxworks.rs index 1ab2f3a47c481..f1e27f4d8beaf 100644 --- a/src/librustc_target/spec/x86_64_wrs_vxworks.rs +++ b/src/librustc_target/spec/x86_64_wrs_vxworks.rs @@ -13,7 +13,8 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), arch: "x86_64".to_string(), target_os: "vxworks".to_string(), target_env: "gnu".to_string(), From c9e996f05cff70e69240b9a9d2d56e57af21eb3a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 7 Jan 2020 21:27:51 +0100 Subject: [PATCH 0057/1253] Remove support for datalayout upgrade Only keep the downgrade code --- src/librustc_codegen_llvm/context.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index ad8aac3ea7f16..50a35fe3dcf1d 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -147,18 +147,6 @@ fn strip_x86_address_spaces(data_layout: String) -> String { data_layout.replace("-p270:32:32-p271:32:32-p272:64:64-", "-") } -fn add_x86_address_spaces(mut data_layout: String) -> String { - let address_spaces = "-p270:32:32-p271:32:32-p272:64:64"; - if !data_layout.contains(address_spaces) && data_layout.starts_with("e-m:") { - let mut insert_pos = "e-m:?".len(); - if data_layout[insert_pos..].starts_with("-p:32:32") { - insert_pos += "-p:32:32".len(); - } - data_layout.insert_str(insert_pos, address_spaces); - } - data_layout -} - pub unsafe fn create_module( tcx: TyCtxt<'_>, llcx: &'ll llvm::Context, @@ -172,11 +160,9 @@ pub unsafe fn create_module( if llvm_util::get_major_version() < 9 { target_data_layout = strip_function_ptr_alignment(target_data_layout); } - if sess.target.target.arch == "x86" || sess.target.target.arch == "x86_64" { - if llvm_util::get_major_version() < 10 { + if llvm_util::get_major_version() < 10 { + if sess.target.target.arch == "x86" || sess.target.target.arch == "x86_64" { target_data_layout = strip_x86_address_spaces(target_data_layout); - } else { - target_data_layout = add_x86_address_spaces(target_data_layout); } } From 40571995984a0f2c466f77955e7d147887c2179b Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Tue, 7 Jan 2020 23:21:24 +0000 Subject: [PATCH 0058/1253] rustdoc: Don't allow `#![feature(...)]` on stable or beta --- src/librustdoc/core.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 50d62027c8c6d..efac0d28d3b54 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -302,8 +302,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt cg: codegen_options, externs, target_triple: target, - // Ensure that rustdoc works even if rustc is feature-staged - unstable_features: UnstableFeatures::Allow, + unstable_features: UnstableFeatures::from_environment(), actually_rustdoc: true, debugging_opts: debugging_options, error_format, From b81ab44a8fee7ad838f5abba881547078df7d9ce Mon Sep 17 00:00:00 2001 From: maik Date: Wed, 8 Jan 2020 09:53:33 +0100 Subject: [PATCH 0059/1253] Remove unnecessary global counting --- .../run-make/wasm-export-all-symbols/verify.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js index cfb7817c5404a..a42aec45535a9 100644 --- a/src/test/run-make/wasm-export-all-symbols/verify.js +++ b/src/test/run-make/wasm-export-all-symbols/verify.js @@ -8,14 +8,11 @@ let list = WebAssembly.Module.exports(m); console.log('exports', list); const my_exports = {}; -let nexports_fn = 0; -let nexports_global = 0; +let nexports = 0; + for (const entry of list) { if (entry.kind == 'function'){ - nexports_fn += 1; - } - if (entry.kind == 'global'){ - nexports_global += 1; + nexports += 1; } my_exports[entry.name] = true; } @@ -27,12 +24,9 @@ if (my_exports.FOO === undefined) throw new Error("`FOO` wasn't defined"); if (my_exports.main === undefined) { - if (nexports_fn != 1) + if (nexports != 1) throw new Error("should only have one function export"); } else { - if (nexports_fn != 2) + if (nexports != 2) throw new Error("should only have two function exports"); } - -if (nexports_global != 1) - throw new Error("should only have one static export"); From f1fb384cd62dc13d0b4647c9f988f6f46cbf4b6f Mon Sep 17 00:00:00 2001 From: maik Date: Wed, 8 Jan 2020 10:05:44 +0100 Subject: [PATCH 0060/1253] Check for the entry kind --- src/test/run-make/wasm-export-all-symbols/verify.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js index a42aec45535a9..72db3356f5635 100644 --- a/src/test/run-make/wasm-export-all-symbols/verify.js +++ b/src/test/run-make/wasm-export-all-symbols/verify.js @@ -14,13 +14,13 @@ for (const entry of list) { if (entry.kind == 'function'){ nexports += 1; } - my_exports[entry.name] = true; + my_exports[entry.name] = entry.kind; } -if (my_exports.foo === undefined) +if (my_exports.foo != "function") throw new Error("`foo` wasn't defined"); -if (my_exports.FOO === undefined) +if (my_exports.FOO != "global") throw new Error("`FOO` wasn't defined"); if (my_exports.main === undefined) { From e3f3cb9761c6a18febe8a340026f3e93aaf2b214 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Wed, 8 Jan 2020 13:48:05 +0000 Subject: [PATCH 0061/1253] Recognise riscv64 in compiletest --- src/tools/compiletest/src/util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 003f51a0f43bb..2663b3d160a7a 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -67,6 +67,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("powerpc", "powerpc"), ("powerpc64", "powerpc64"), ("powerpc64le", "powerpc64"), + ("riscv64gc", "riscv64"), ("s390x", "s390x"), ("sparc", "sparc"), ("sparc64", "sparc64"), From 2c5766f2d4b329f73d144a000c7cc5136f49cad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2020 08:05:31 -0800 Subject: [PATCH 0062/1253] Unify output of "variant not found" errors --- src/librustc_typeck/astconv.rs | 8 +++- src/librustc_typeck/check/method/suggest.rs | 5 ++- .../associated-const-no-item.rs | 2 +- .../associated-item-enum.stderr | 6 +-- src/test/ui/auto-ref-slice-plus-ref.stderr | 8 ++-- src/test/ui/block-result/issue-3563.rs | 2 +- src/test/ui/block-result/issue-3563.stderr | 2 +- src/test/ui/bogus-tag.stderr | 2 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../ui/coherence/coherence_inherent.stderr | 2 +- .../ui/coherence/coherence_inherent_cc.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 22 +++++------ .../issue-32128.stderr | 2 +- .../issue-33784.stderr | 6 +-- .../private-field.stderr | 2 +- .../invalid-const-arg-for-type-param.stderr | 2 +- .../ui/consts/too_generic_eval_ice.stderr | 2 +- src/test/ui/copy-a-resource.stderr | 2 +- .../derives/derive-assoc-type-not-impl.stderr | 2 +- src/test/ui/did_you_mean/bad-assoc-pat.rs | 12 +++--- src/test/ui/did_you_mean/bad-assoc-pat.stderr | 6 +-- src/test/ui/did_you_mean/issue-40006.rs | 2 +- src/test/ui/did_you_mean/issue-40006.stderr | 2 +- .../ui/dont-suggest-private-trait-method.rs | 2 +- .../dont-suggest-private-trait-method.stderr | 2 +- src/test/ui/empty/empty-struct-braces-expr.rs | 6 +-- .../ui/empty/empty-struct-braces-expr.stderr | 6 +-- src/test/ui/error-codes/E0599.stderr | 2 +- src/test/ui/error-festival.stderr | 2 +- .../ui/hygiene/no_implicit_prelude.stderr | 2 +- src/test/ui/hygiene/trait_items.rs | 2 +- src/test/ui/hygiene/trait_items.stderr | 2 +- src/test/ui/impl-trait/bindings-opaque.stderr | 6 +-- ...issue-21659-show-relevant-trait-impls-3.rs | 2 +- ...e-21659-show-relevant-trait-impls-3.stderr | 2 +- .../method-suggestion-no-duplication.stderr | 2 +- .../impl-trait/no-method-suggested-traits.rs | 2 +- .../no-method-suggested-traits.stderr | 38 +++++++++---------- .../ui/infinite/infinite-autoderef.stderr | 2 +- src/test/ui/issues/issue-10465.stderr | 2 +- src/test/ui/issues/issue-13853.stderr | 2 +- src/test/ui/issues/issue-19521.stderr | 2 +- src/test/ui/issues/issue-19692.stderr | 2 +- src/test/ui/issues/issue-21596.stderr | 2 +- src/test/ui/issues/issue-22933-2.rs | 2 +- src/test/ui/issues/issue-22933-2.stderr | 2 +- src/test/ui/issues/issue-22933-3.rs | 2 +- src/test/ui/issues/issue-23173.rs | 6 +-- src/test/ui/issues/issue-23173.stderr | 8 ++-- src/test/ui/issues/issue-23217.rs | 2 +- src/test/ui/issues/issue-23217.stderr | 2 +- src/test/ui/issues/issue-25385.rs | 4 +- src/test/ui/issues/issue-2823.stderr | 2 +- src/test/ui/issues/issue-28344.stderr | 4 +- src/test/ui/issues/issue-28586.rs | 2 +- src/test/ui/issues/issue-28971.rs | 2 +- src/test/ui/issues/issue-28971.stderr | 2 +- src/test/ui/issues/issue-29124.rs | 4 +- src/test/ui/issues/issue-29124.stderr | 4 +- src/test/ui/issues/issue-30123.rs | 2 +- src/test/ui/issues/issue-30123.stderr | 2 +- src/test/ui/issues/issue-31173.stderr | 2 +- src/test/ui/issues/issue-33575.rs | 2 +- src/test/ui/issues/issue-33575.stderr | 2 +- src/test/ui/issues/issue-34209.rs | 2 +- src/test/ui/issues/issue-34209.stderr | 3 +- src/test/ui/issues/issue-34334.rs | 2 +- src/test/ui/issues/issue-34334.stderr | 2 +- src/test/ui/issues/issue-35677.stderr | 2 +- src/test/ui/issues/issue-3707.rs | 2 +- src/test/ui/issues/issue-3707.stderr | 2 +- src/test/ui/issues/issue-38919.rs | 2 +- src/test/ui/issues/issue-38919.stderr | 2 +- src/test/ui/issues/issue-39175.stderr | 2 +- src/test/ui/issues/issue-39559.rs | 2 +- src/test/ui/issues/issue-39559.stderr | 2 +- src/test/ui/issues/issue-3973.rs | 2 +- src/test/ui/issues/issue-3973.stderr | 2 +- src/test/ui/issues/issue-41880.rs | 2 +- src/test/ui/issues/issue-41880.stderr | 2 +- src/test/ui/issues/issue-42880.stderr | 2 +- src/test/ui/issues/issue-43189.rs | 2 +- src/test/ui/issues/issue-43189.stderr | 2 +- .../option-as_deref.rs | 2 +- .../option-as_deref.stderr | 2 +- .../option-as_deref_mut.rs | 2 +- .../option-as_deref_mut.stderr | 2 +- .../result-as_deref.stderr | 2 +- .../result-as_deref_err.stderr | 2 +- .../result-as_deref_mut.stderr | 2 +- .../result-as_deref_mut_err.stderr | 2 +- .../result-as_deref_mut_ok.stderr | 2 +- .../result-as_deref_ok.stderr | 2 +- src/test/ui/issues/issue-5153.rs | 2 +- src/test/ui/issues/issue-5153.stderr | 2 +- src/test/ui/issues/issue-54062.stderr | 2 +- src/test/ui/issues/issue-57362-1.stderr | 2 +- src/test/ui/issues/issue-57362-2.stderr | 2 +- src/test/ui/issues/issue-58734.rs | 2 +- src/test/ui/issues/issue-58734.stderr | 2 +- src/test/ui/issues/issue-64430.stderr | 2 +- ...issue-65284-suggest-generic-trait-bound.rs | 2 +- ...e-65284-suggest-generic-trait-bound.stderr | 2 +- src/test/ui/issues/issue-7950.rs | 2 +- src/test/ui/issues/issue-7950.stderr | 2 +- src/test/ui/lexical-scopes.stderr | 2 +- src/test/ui/methods/method-call-err-msg.rs | 2 +- .../ui/methods/method-call-err-msg.stderr | 2 +- .../ui/mismatched_types/issue-36053-2.stderr | 2 +- .../method-help-unsatisfied-bound.rs | 2 +- .../method-help-unsatisfied-bound.stderr | 2 +- src/test/ui/never_type/issue-2149.rs | 2 +- src/test/ui/never_type/issue-2149.stderr | 2 +- src/test/ui/non-copyable-void.stderr | 2 +- src/test/ui/noncopyable-class.stderr | 2 +- src/test/ui/object-pointer-types.stderr | 6 +-- ...point-at-arbitrary-self-type-method.stderr | 2 +- ...at-arbitrary-self-type-trait-method.stderr | 2 +- src/test/ui/self/suggest-self-2.rs | 2 +- src/test/ui/self/suggest-self-2.stderr | 2 +- .../ui/shadowed/shadowed-trait-methods.stderr | 2 +- src/test/ui/span/issue-7575.rs | 6 +-- src/test/ui/span/issue-7575.stderr | 4 +- .../specialization-trait-not-implemented.rs | 2 +- ...pecialization-trait-not-implemented.stderr | 2 +- src/test/ui/suggestions/constrain-trait.fixed | 4 +- src/test/ui/suggestions/constrain-trait.rs | 4 +- .../ui/suggestions/constrain-trait.stderr | 4 +- ...it-with-missing-trait-bounds-in-arg.stderr | 2 +- src/test/ui/suggestions/issue-21673.stderr | 4 +- .../suggestions/mut-borrow-needed-by-trait.rs | 2 +- .../mut-borrow-needed-by-trait.stderr | 2 +- src/test/ui/suggestions/remove-as_str.rs | 8 ++-- src/test/ui/suggestions/remove-as_str.stderr | 8 ++-- ...oc-fn-call-with-turbofish-through-deref.rs | 2 +- ...n-call-with-turbofish-through-deref.stderr | 2 +- .../suggest-assoc-fn-call-with-turbofish.rs | 2 +- ...uggest-assoc-fn-call-with-turbofish.stderr | 2 +- .../ui/suggestions/suggest-methods.stderr | 4 +- src/test/ui/suggestions/suggest-variants.rs | 6 +-- .../ui/suggestions/suggest-variants.stderr | 12 +++--- src/test/ui/traits/trait-impl-1.rs | 2 +- src/test/ui/traits/trait-impl-1.stderr | 2 +- src/test/ui/traits/trait-item-privacy.rs | 12 +++--- src/test/ui/traits/trait-item-privacy.stderr | 12 +++--- src/test/ui/ufcs/ufcs-partially-resolved.rs | 4 +- .../ui/ufcs/ufcs-partially-resolved.stderr | 4 +- ...ed-closures-static-call-wrong-trait.stderr | 2 +- src/test/ui/underscore-imports/hygiene.stderr | 4 +- src/test/ui/underscore-imports/shadow.stderr | 2 +- src/test/ui/union/union-derive-clone.rs | 2 +- src/test/ui/union/union-derive-clone.stderr | 2 +- src/test/ui/unique-object-noncopyable.stderr | 2 +- src/test/ui/unique-pinned-nocopy.stderr | 2 +- .../ui/unspecified-self-in-trait-ref.stderr | 8 ++-- 156 files changed, 260 insertions(+), 254 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 36d119bf7698f..4fe45ffa74763 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2114,9 +2114,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let msg = format!("expected type, found variant `{}`", assoc_ident); tcx.sess.span_err(span, &msg); } else if qself_ty.is_enum() { - let mut err = tcx.sess.struct_span_err( + let mut err = struct_span_err!( + tcx.sess, assoc_ident.span, - &format!("no variant `{}` in enum `{}`", assoc_ident, qself_ty), + E0599, + "no variant named `{}` found for enum `{}`", + assoc_ident, + qself_ty, ); let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT"); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 1cc1eb2c7b2df..40edad3674093 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -361,10 +361,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.sess, span, E0599, - "no {} named `{}` found for type `{}` in the current scope", + "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, - ty_str + actual.prefix_string(), + ty_str, ); if let Some(span) = tcx.sess.confused_type_with_std_module.borrow().get(&span) diff --git a/src/test/ui/associated-const/associated-const-no-item.rs b/src/test/ui/associated-const/associated-const-no-item.rs index 35fb662f63aee..024d14e21b5fd 100644 --- a/src/test/ui/associated-const/associated-const-no-item.rs +++ b/src/test/ui/associated-const/associated-const-no-item.rs @@ -3,7 +3,7 @@ trait Foo { } const X: i32 = ::ID; -//~^ ERROR no associated item named `ID` found for type `i32` +//~^ ERROR no associated item named `ID` found fn main() { assert_eq!(1, X); diff --git a/src/test/ui/associated-item/associated-item-enum.stderr b/src/test/ui/associated-item/associated-item-enum.stderr index 5a62b9736dedd..6f89530eac933 100644 --- a/src/test/ui/associated-item/associated-item-enum.stderr +++ b/src/test/ui/associated-item/associated-item-enum.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `mispellable` found for type `Enum` in the current scope +error[E0599]: no variant or associated item named `mispellable` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:17:11 | LL | enum Enum { Variant } @@ -10,7 +10,7 @@ LL | Enum::mispellable(); | variant or associated item not found in `Enum` | help: there is a method with a similar name: `misspellable` -error[E0599]: no variant or associated item named `mispellable_trait` found for type `Enum` in the current scope +error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:18:11 | LL | enum Enum { Variant } @@ -19,7 +19,7 @@ LL | enum Enum { Variant } LL | Enum::mispellable_trait(); | ^^^^^^^^^^^^^^^^^ variant or associated item not found in `Enum` -error[E0599]: no variant or associated item named `MISPELLABLE` found for type `Enum` in the current scope +error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:19:11 | LL | enum Enum { Variant } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index 3e36f2402a990..a0739a7a90b0a 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for type `std::vec::Vec<{integer}>` in the current scope +error[E0599]: no method named `test_mut` found for struct `std::vec::Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -8,7 +8,7 @@ LL | a.test_mut(); = note: the following trait defines an item `test_mut`, perhaps you need to implement it: candidate #1: `MyIter` -error[E0599]: no method named `test` found for type `std::vec::Vec<{integer}>` in the current scope +error[E0599]: no method named `test` found for struct `std::vec::Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); @@ -18,7 +18,7 @@ LL | a.test(); = note: the following trait defines an item `test`, perhaps you need to implement it: candidate #1: `MyIter` -error[E0599]: no method named `test` found for type `[{integer}; 1]` in the current scope +error[E0599]: no method named `test` found for array `[{integer}; 1]` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:10:11 | LL | ([1]).test(); @@ -28,7 +28,7 @@ LL | ([1]).test(); = note: the following trait defines an item `test`, perhaps you need to implement it: candidate #1: `MyIter` -error[E0599]: no method named `test` found for type `&[{integer}; 1]` in the current scope +error[E0599]: no method named `test` found for reference `&[{integer}; 1]` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:11:12 | LL | (&[1]).test(); diff --git a/src/test/ui/block-result/issue-3563.rs b/src/test/ui/block-result/issue-3563.rs index 9b313d3e9b278..0b652a1f54bf2 100644 --- a/src/test/ui/block-result/issue-3563.rs +++ b/src/test/ui/block-result/issue-3563.rs @@ -1,7 +1,7 @@ trait A { fn a(&self) { || self.b() - //~^ ERROR no method named `b` found for type `&Self` in the current scope + //~^ ERROR no method named `b` found } } fn main() {} diff --git a/src/test/ui/block-result/issue-3563.stderr b/src/test/ui/block-result/issue-3563.stderr index 237b8c54ce301..be551f6e889fc 100644 --- a/src/test/ui/block-result/issue-3563.stderr +++ b/src/test/ui/block-result/issue-3563.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `b` found for type `&Self` in the current scope +error[E0599]: no method named `b` found for reference `&Self` in the current scope --> $DIR/issue-3563.rs:3:17 | LL | || self.b() diff --git a/src/test/ui/bogus-tag.stderr b/src/test/ui/bogus-tag.stderr index 890f6800c22af..cb3199e7c886e 100644 --- a/src/test/ui/bogus-tag.stderr +++ b/src/test/ui/bogus-tag.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `Hsl` found for type `Color` in the current scope +error[E0599]: no variant or associated item named `Hsl` found for enum `Color` in the current scope --> $DIR/bogus-tag.rs:7:16 | LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), } diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index 4cab52e3e974c..0f932cda07fc3 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for type `std::boxed::Box` in the current scope +error[E0599]: no method named `eat` found for struct `std::boxed::Box` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/coherence/coherence_inherent.stderr b/src/test/ui/coherence/coherence_inherent.stderr index e719d5254f639..3d37d8af31df3 100644 --- a/src/test/ui/coherence/coherence_inherent.stderr +++ b/src/test/ui/coherence/coherence_inherent.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `the_fn` found for type `&Lib::TheStruct` in the current scope +error[E0599]: no method named `the_fn` found for reference `&Lib::TheStruct` in the current scope --> $DIR/coherence_inherent.rs:31:11 | LL | s.the_fn(); diff --git a/src/test/ui/coherence/coherence_inherent_cc.stderr b/src/test/ui/coherence/coherence_inherent_cc.stderr index c666c1a3d1b3f..d968c8b4680df 100644 --- a/src/test/ui/coherence/coherence_inherent_cc.stderr +++ b/src/test/ui/coherence/coherence_inherent_cc.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `the_fn` found for type `&coherence_inherent_cc_lib::TheStruct` in the current scope +error[E0599]: no method named `the_fn` found for reference `&coherence_inherent_cc_lib::TheStruct` in the current scope --> $DIR/coherence_inherent_cc.rs:23:11 | LL | s.the_fn(); diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index 79ba93130a73a..d6b399acb7330 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.rs:6:28: 6:33]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-18343.rs:6:28: 6:33]>` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index a44b971841538..f9dfdddad9d46 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for type `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -37,7 +37,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_func.closure)(); | ^ ^ -error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope +error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the current scope --> $DIR/issue-2392.rs:45:14 | LL | struct BoxedObj { @@ -51,7 +51,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_fn.boxed_closure)(); | ^ ^ -error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope +error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the current scope --> $DIR/issue-2392.rs:48:19 | LL | struct BoxedObj { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for type `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for type `Obj u32 {func}>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj u32 {func}>` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for type `Obj u32 + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj u32 + 'static)>>` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { @@ -104,7 +104,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (check_expression().closure)(); | ^ ^ -error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope +error[E0599]: no method named `f1` found for struct `FuncContainer` in the current scope --> $DIR/issue-2392.rs:64:31 | LL | struct FuncContainer { @@ -118,7 +118,7 @@ help: to call the function stored in `f1`, surround the field access with parent LL | ((*self.container).f1)(1); | ^ ^ -error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope +error[E0599]: no method named `f2` found for struct `FuncContainer` in the current scope --> $DIR/issue-2392.rs:65:31 | LL | struct FuncContainer { @@ -132,7 +132,7 @@ help: to call the function stored in `f2`, surround the field access with parent LL | ((*self.container).f2)(1); | ^ ^ -error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope +error[E0599]: no method named `f3` found for struct `FuncContainer` in the current scope --> $DIR/issue-2392.rs:66:31 | LL | struct FuncContainer { diff --git a/src/test/ui/confuse-field-and-method/issue-32128.stderr b/src/test/ui/confuse-field-and-method/issue-32128.stderr index b2f7894ba0560..a8d97bdfe2fb5 100644 --- a/src/test/ui/confuse-field-and-method/issue-32128.stderr +++ b/src/test/ui/confuse-field-and-method/issue-32128.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `example` found for type `Example` in the current scope +error[E0599]: no method named `example` found for struct `Example` in the current scope --> $DIR/issue-32128.rs:12:10 | LL | struct Example { diff --git a/src/test/ui/confuse-field-and-method/issue-33784.stderr b/src/test/ui/confuse-field-and-method/issue-33784.stderr index af29a9963e1f2..c109896e825be 100644 --- a/src/test/ui/confuse-field-and-method/issue-33784.stderr +++ b/src/test/ui/confuse-field-and-method/issue-33784.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for type `&Obj<[closure@$DIR/issue-33784.rs:25:43: 25:48]>` in the current scope +error[E0599]: no method named `closure` found for reference `&Obj<[closure@$DIR/issue-33784.rs:25:43: 25:48]>` in the current scope --> $DIR/issue-33784.rs:27:7 | LL | p.closure(); @@ -9,7 +9,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (p.closure)(); | ^ ^ -error[E0599]: no method named `fn_ptr` found for type `&&Obj<[closure@$DIR/issue-33784.rs:25:43: 25:48]>` in the current scope +error[E0599]: no method named `fn_ptr` found for reference `&&Obj<[closure@$DIR/issue-33784.rs:25:43: 25:48]>` in the current scope --> $DIR/issue-33784.rs:29:7 | LL | q.fn_ptr(); @@ -20,7 +20,7 @@ help: to call the function stored in `fn_ptr`, surround the field access with pa LL | (q.fn_ptr)(); | ^ ^ -error[E0599]: no method named `c_fn_ptr` found for type `&D` in the current scope +error[E0599]: no method named `c_fn_ptr` found for reference `&D` in the current scope --> $DIR/issue-33784.rs:32:7 | LL | s.c_fn_ptr(); diff --git a/src/test/ui/confuse-field-and-method/private-field.stderr b/src/test/ui/confuse-field-and-method/private-field.stderr index 97c949e32e341..82cb235d47a7d 100644 --- a/src/test/ui/confuse-field-and-method/private-field.stderr +++ b/src/test/ui/confuse-field-and-method/private-field.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `dog_age` found for type `animal::Dog` in the current scope +error[E0599]: no method named `dog_age` found for struct `animal::Dog` in the current scope --> $DIR/private-field.rs:16:23 | LL | pub struct Dog { diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr index 47b090cb88678..19e7d2036bfc8 100644 --- a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr +++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr @@ -4,7 +4,7 @@ error[E0107]: wrong number of const arguments: expected 0, found 1 LL | let _: u32 = 5i32.try_into::<32>().unwrap(); | ^^ unexpected const argument -error[E0599]: no method named `f` found for type `S` in the current scope +error[E0599]: no method named `f` found for struct `S` in the current scope --> $DIR/invalid-const-arg-for-type-param.rs:7:7 | LL | struct S; diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 2fb9977f4d700..599d1d79e7555 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -1,4 +1,4 @@ -error[E0599]: no associated item named `HOST_SIZE` found for type `Foo` in the current scope +error[E0599]: no associated item named `HOST_SIZE` found for struct `Foo` in the current scope --> $DIR/too_generic_eval_ice.rs:7:19 | LL | pub struct Foo(A, B); diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index 054bd0914d31c..c95e8d239d2b9 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `Foo` in the current scope +error[E0599]: no method named `clone` found for struct `Foo` in the current scope --> $DIR/copy-a-resource.rs:18:16 | LL | struct Foo { diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index 038de80508ac2..2083a1d65220f 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `Bar` in the current scope +error[E0599]: no method named `clone` found for struct `Bar` in the current scope --> $DIR/derive-assoc-type-not-impl.rs:18:30 | LL | struct Bar { diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.rs b/src/test/ui/did_you_mean/bad-assoc-pat.rs index 7e7ba59dca816..3f912f7ffc63e 100644 --- a/src/test/ui/did_you_mean/bad-assoc-pat.rs +++ b/src/test/ui/did_you_mean/bad-assoc-pat.rs @@ -2,25 +2,25 @@ fn main() { match 0u8 { [u8]::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `[u8]` in the current scope + //~| ERROR no associated item named `AssocItem` found (u8, u8)::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `(u8, u8)` in the current sco + //~| ERROR no associated item named `AssocItem` found _::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `_` in the current scope + //~| ERROR no associated item named `AssocItem` found } match &0u8 { &(u8,)::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `(u8,)` in the current scope + //~| ERROR no associated item named `AssocItem` found } } macro_rules! pat { ($ty: ty) => ($ty::AssocItem) //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `u8` in the current scope + //~| ERROR no associated item named `AssocItem` found } macro_rules! ty { () => (u8) @@ -31,6 +31,6 @@ fn check_macros() { pat!(u8) => {} ty!()::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found for type `u8` in the current scope + //~| ERROR no associated item named `AssocItem` found } } diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.stderr b/src/test/ui/did_you_mean/bad-assoc-pat.stderr index 59b865437a2e0..3f1946b94f64b 100644 --- a/src/test/ui/did_you_mean/bad-assoc-pat.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-pat.stderr @@ -37,13 +37,13 @@ LL | ($ty: ty) => ($ty::AssocItem) LL | pat!(u8) => {} | -------- in this macro invocation -error[E0599]: no associated item named `AssocItem` found for type `[u8]` in the current scope +error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope --> $DIR/bad-assoc-pat.rs:3:15 | LL | [u8]::AssocItem => {} | ^^^^^^^^^ associated item not found in `[u8]` -error[E0599]: no associated item named `AssocItem` found for type `(u8, u8)` in the current scope +error[E0599]: no associated item named `AssocItem` found for tuple `(u8, u8)` in the current scope --> $DIR/bad-assoc-pat.rs:6:19 | LL | (u8, u8)::AssocItem => {} @@ -55,7 +55,7 @@ error[E0599]: no associated item named `AssocItem` found for type `_` in the cur LL | _::AssocItem => {} | ^^^^^^^^^ associated item not found in `_` -error[E0599]: no associated item named `AssocItem` found for type `(u8,)` in the current scope +error[E0599]: no associated item named `AssocItem` found for tuple `(u8,)` in the current scope --> $DIR/bad-assoc-pat.rs:14:17 | LL | &(u8,)::AssocItem => {} diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs index ea21592997bfe..60633c6930cdf 100644 --- a/src/test/ui/did_you_mean/issue-40006.rs +++ b/src/test/ui/did_you_mean/issue-40006.rs @@ -35,5 +35,5 @@ impl S { } fn main() { - S.hello_method(); //~ no method named `hello_method` found for type `S` in the current scope + S.hello_method(); //~ no method named `hello_method` found } diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index d1e995013cb93..072e61f6a3cd1 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -56,7 +56,7 @@ error: missing `fn`, `type`, or `const` for associated-item declaration LL | pub hello_method(&self) { | ^ missing `fn`, `type`, or `const` -error[E0599]: no method named `hello_method` found for type `S` in the current scope +error[E0599]: no method named `hello_method` found for struct `S` in the current scope --> $DIR/issue-40006.rs:38:7 | LL | struct S; diff --git a/src/test/ui/dont-suggest-private-trait-method.rs b/src/test/ui/dont-suggest-private-trait-method.rs index ef0904c1a2dbf..6e2b1abd1370f 100644 --- a/src/test/ui/dont-suggest-private-trait-method.rs +++ b/src/test/ui/dont-suggest-private-trait-method.rs @@ -2,5 +2,5 @@ struct T; fn main() { T::new(); - //~^ ERROR no function or associated item named `new` found for type `T` in the current scope + //~^ ERROR no function or associated item named `new` found } diff --git a/src/test/ui/dont-suggest-private-trait-method.stderr b/src/test/ui/dont-suggest-private-trait-method.stderr index 5189ffa62d1ba..fd7fdb4f7226c 100644 --- a/src/test/ui/dont-suggest-private-trait-method.stderr +++ b/src/test/ui/dont-suggest-private-trait-method.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `new` found for type `T` in the current scope +error[E0599]: no function or associated item named `new` found for struct `T` in the current scope --> $DIR/dont-suggest-private-trait-method.rs:4:8 | LL | struct T; diff --git a/src/test/ui/empty/empty-struct-braces-expr.rs b/src/test/ui/empty/empty-struct-braces-expr.rs index 1a38d3d7601b8..f4144277f16be 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.rs +++ b/src/test/ui/empty/empty-struct-braces-expr.rs @@ -22,8 +22,8 @@ fn main() { let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` let xe1 = XEmpty1(); //~^ ERROR expected function, tuple struct or tuple variant, found struct `XEmpty1` - let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for type - let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for type + let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for enum + let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for enum - XE::Empty1 {}; //~ ERROR no variant `Empty1` in enum `empty_struct::XE` + XE::Empty1 {}; //~ ERROR no variant named `Empty1` found for enum `empty_struct::XE` } diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index f427c1ba0adfb..20f4c320e669a 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -58,7 +58,7 @@ LL | let xe1 = XEmpty1(); | did you mean `XEmpty1 { /* fields */ }`? | help: a unit struct with a similar name exists: `XEmpty2` -error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope +error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:25:19 | LL | let xe3 = XE::Empty3; @@ -67,7 +67,7 @@ LL | let xe3 = XE::Empty3; | variant or associated item not found in `empty_struct::XE` | help: there is a variant with a similar name: `XEmpty3` -error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope +error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:26:19 | LL | let xe3 = XE::Empty3(); @@ -76,7 +76,7 @@ LL | let xe3 = XE::Empty3(); | variant or associated item not found in `empty_struct::XE` | help: there is a variant with a similar name: `XEmpty3` -error: no variant `Empty1` in enum `empty_struct::XE` +error[E0599]: no variant named `Empty1` found for enum `empty_struct::XE` --> $DIR/empty-struct-braces-expr.rs:28:9 | LL | XE::Empty1 {}; diff --git a/src/test/ui/error-codes/E0599.stderr b/src/test/ui/error-codes/E0599.stderr index 89bfccf2fbc56..a78a003661d6f 100644 --- a/src/test/ui/error-codes/E0599.stderr +++ b/src/test/ui/error-codes/E0599.stderr @@ -1,4 +1,4 @@ -error[E0599]: no associated item named `NotEvenReal` found for type `Foo` in the current scope +error[E0599]: no associated item named `NotEvenReal` found for struct `Foo` in the current scope --> $DIR/E0599.rs:4:20 | LL | struct Foo; diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 73571a375b5f6..6b80d99b3afe9 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -20,7 +20,7 @@ LL | x += 2; | = note: an implementation of `std::ops::AddAssign` might be missing for `&str` -error[E0599]: no method named `z` found for type `&str` in the current scope +error[E0599]: no method named `z` found for reference `&str` in the current scope --> $DIR/error-festival.rs:16:7 | LL | x.z(); diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 736369dab8354..5d75f5034bc65 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -15,7 +15,7 @@ LL | fn f() { ::bar::m!(); } LL | Vec::new(); | ^^^ use of undeclared type or module `Vec` -error[E0599]: no method named `clone` found for type `()` in the current scope +error[E0599]: no method named `clone` found for unit type `()` in the current scope --> $DIR/no_implicit_prelude.rs:12:12 | LL | fn f() { ::bar::m!(); } diff --git a/src/test/ui/hygiene/trait_items.rs b/src/test/ui/hygiene/trait_items.rs index a116c5b38ce97..15c4acbc939bc 100644 --- a/src/test/ui/hygiene/trait_items.rs +++ b/src/test/ui/hygiene/trait_items.rs @@ -14,7 +14,7 @@ mod bar { } mod baz { - pub macro m() { ().f() } //~ ERROR no method named `f` found for type `()` in the current scope + pub macro m() { ().f() } //~ ERROR no method named `f` found fn f() { ::bar::m!(); } } diff --git a/src/test/ui/hygiene/trait_items.stderr b/src/test/ui/hygiene/trait_items.stderr index c3ce484edf7a9..8e3609292a7f9 100644 --- a/src/test/ui/hygiene/trait_items.stderr +++ b/src/test/ui/hygiene/trait_items.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `f` found for type `()` in the current scope +error[E0599]: no method named `f` found for unit type `()` in the current scope --> $DIR/trait_items.rs:17:24 | LL | fn f() { ::baz::m!(); } diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr index 644d26b34060c..1605f3434cf5a 100644 --- a/src/test/ui/impl-trait/bindings-opaque.stderr +++ b/src/test/ui/impl-trait/bindings-opaque.stderr @@ -6,19 +6,19 @@ LL | #![feature(impl_trait_in_bindings)] | = note: `#[warn(incomplete_features)]` on by default -error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope +error[E0599]: no method named `count_ones` found for opaque type `impl std::marker::Copy` in the current scope --> $DIR/bindings-opaque.rs:11:17 | LL | let _ = FOO.count_ones(); | ^^^^^^^^^^ method not found in `impl std::marker::Copy` -error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope +error[E0599]: no method named `count_ones` found for opaque type `impl std::marker::Copy` in the current scope --> $DIR/bindings-opaque.rs:13:17 | LL | let _ = BAR.count_ones(); | ^^^^^^^^^^ method not found in `impl std::marker::Copy` -error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope +error[E0599]: no method named `count_ones` found for opaque type `impl std::marker::Copy` in the current scope --> $DIR/bindings-opaque.rs:15:17 | LL | let _ = foo.count_ones(); diff --git a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs index 2bff01be9b813..41f48cb56933e 100644 --- a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs +++ b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs @@ -18,5 +18,5 @@ fn main() { let f1 = Bar; f1.foo(1usize); - //~^ error: method named `foo` found for type `Bar` in the current scope + //~^ error: method named `foo` found for struct `Bar` in the current scope } diff --git a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr index 441191beaf588..57417975474f7 100644 --- a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `Bar` in the current scope +error[E0599]: no method named `foo` found for struct `Bar` in the current scope --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:20:8 | LL | struct Bar; diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr index fb870d6c6f076..7f2eb0c21e61d 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `is_empty` found for type `Foo` in the current scope +error[E0599]: no method named `is_empty` found for struct `Foo` in the current scope --> $DIR/method-suggestion-no-duplication.rs:7:15 | LL | struct Foo; diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.rs b/src/test/ui/impl-trait/no-method-suggested-traits.rs index c912873a6c05c..c8abc2d8f8ee0 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.rs +++ b/src/test/ui/impl-trait/no-method-suggested-traits.rs @@ -25,7 +25,7 @@ fn main() { //~|items from traits can only be used if the trait is in scope std::rc::Rc::new(&mut Box::new(&1u32)).method(); //~^items from traits can only be used if the trait is in scope - //~| ERROR no method named `method` found for type + //~| ERROR no method named `method` found for struct 'a'.method(); //~^ ERROR no method named diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index f0a03e1be82ac..da25617e18759 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&u32>>` in the current scope +error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::boxed::Box<&u32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope +error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | fn method(&self) {} @@ -78,7 +78,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&i32>>` in the current scope +error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::boxed::Box<&i32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -90,7 +90,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for type `Foo` in the current scope +error[E0599]: no method named `method` found for struct `Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:40:9 | LL | struct Foo; @@ -106,7 +106,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `no_method_suggested_traits::Reexported` -error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope +error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -129,7 +129,7 @@ LL | 1u64.method2(); = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope +error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -139,7 +139,7 @@ LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method2` found for type `no_method_suggested_traits::Foo` in the current scope +error[E0599]: no method named `method2` found for struct `no_method_suggested_traits::Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:50:37 | LL | no_method_suggested_traits::Foo.method2(); @@ -149,7 +149,7 @@ LL | no_method_suggested_traits::Foo.method2(); = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -159,7 +159,7 @@ LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).metho = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method2` found for type `no_method_suggested_traits::Bar` in the current scope +error[E0599]: no method named `method2` found for enum `no_method_suggested_traits::Bar` in the current scope --> $DIR/no-method-suggested-traits.rs:54:40 | LL | no_method_suggested_traits::Bar::X.method2(); @@ -169,7 +169,7 @@ LL | no_method_suggested_traits::Bar::X.method2(); = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -179,7 +179,7 @@ LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).me = note: the following trait defines an item `method2`, perhaps you need to implement it: candidate #1: `foo::Bar` -error[E0599]: no method named `method3` found for type `Foo` in the current scope +error[E0599]: no method named `method3` found for struct `Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:59:9 | LL | struct Foo; @@ -192,7 +192,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` -error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -202,7 +202,7 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` -error[E0599]: no method named `method3` found for type `Bar` in the current scope +error[E0599]: no method named `method3` found for enum `Bar` in the current scope --> $DIR/no-method-suggested-traits.rs:63:12 | LL | enum Bar { X } @@ -215,7 +215,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` -error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `std::rc::Rc<&mut std::boxed::Box<&Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -231,31 +231,31 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&usize>>` in the current scope +error[E0599]: no method named `method3` found for struct `std::rc::Rc<&mut std::boxed::Box<&usize>>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); | ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&usize>>` -error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Foo` in the current scope +error[E0599]: no method named `method3` found for struct `no_method_suggested_traits::Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:71:37 | LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); | ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` -error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Bar` in the current scope +error[E0599]: no method named `method3` found for enum `no_method_suggested_traits::Bar` in the current scope --> $DIR/no-method-suggested-traits.rs:74:40 | LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index f4567554d0dbb..8c59fbd530129 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr @@ -37,7 +37,7 @@ LL | Foo.bar(); | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate -error[E0599]: no method named `bar` found for type `Foo` in the current scope +error[E0599]: no method named `bar` found for struct `Foo` in the current scope --> $DIR/infinite-autoderef.rs:26:9 | LL | struct Foo; diff --git a/src/test/ui/issues/issue-10465.stderr b/src/test/ui/issues/issue-10465.stderr index 80ca051ceff0d..666fb6ab2bbb1 100644 --- a/src/test/ui/issues/issue-10465.stderr +++ b/src/test/ui/issues/issue-10465.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `&b::B` in the current scope +error[E0599]: no method named `foo` found for reference `&b::B` in the current scope --> $DIR/issue-10465.rs:17:15 | LL | b.foo(); diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr index cdb261a238e56..2f31636f8adf9 100644 --- a/src/test/ui/issues/issue-13853.stderr +++ b/src/test/ui/issues/issue-13853.stderr @@ -12,7 +12,7 @@ LL | self.iter() = help: type parameters must be constrained to match other types = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error[E0599]: no method named `iter` found for type `&G` in the current scope +error[E0599]: no method named `iter` found for reference `&G` in the current scope --> $DIR/issue-13853.rs:27:23 | LL | for node in graph.iter() { diff --git a/src/test/ui/issues/issue-19521.stderr b/src/test/ui/issues/issue-19521.stderr index c15c5392fac25..b6847cd755c3f 100644 --- a/src/test/ui/issues/issue-19521.stderr +++ b/src/test/ui/issues/issue-19521.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `homura` found for type `&'static str` in the current scope +error[E0599]: no method named `homura` found for reference `&'static str` in the current scope --> $DIR/issue-19521.rs:2:8 | LL | "".homura()(); diff --git a/src/test/ui/issues/issue-19692.stderr b/src/test/ui/issues/issue-19692.stderr index fe920c1693982..b412d7bc70436 100644 --- a/src/test/ui/issues/issue-19692.stderr +++ b/src/test/ui/issues/issue-19692.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `kaname` found for type `Homura` in the current scope +error[E0599]: no method named `kaname` found for struct `Homura` in the current scope --> $DIR/issue-19692.rs:4:40 | LL | struct Homura; diff --git a/src/test/ui/issues/issue-21596.stderr b/src/test/ui/issues/issue-21596.stderr index 4e5cace525787..efde16167b71b 100644 --- a/src/test/ui/issues/issue-21596.stderr +++ b/src/test/ui/issues/issue-21596.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `to_string` found for type `*const u8` in the current scope +error[E0599]: no method named `to_string` found for raw pointer `*const u8` in the current scope --> $DIR/issue-21596.rs:4:22 | LL | println!("{}", z.to_string()); diff --git a/src/test/ui/issues/issue-22933-2.rs b/src/test/ui/issues/issue-22933-2.rs index 98a354b1bd0fc..dfd84b9a79d40 100644 --- a/src/test/ui/issues/issue-22933-2.rs +++ b/src/test/ui/issues/issue-22933-2.rs @@ -2,7 +2,7 @@ enum Delicious { Pie = 0x1, Apple = 0x2, ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, - //~^ ERROR no variant or associated item named `PIE` found for type `Delicious` + //~^ ERROR no variant or associated item named `PIE` found } fn main() {} diff --git a/src/test/ui/issues/issue-22933-2.stderr b/src/test/ui/issues/issue-22933-2.stderr index 72038ea20a3fa..584b05ec44d3f 100644 --- a/src/test/ui/issues/issue-22933-2.stderr +++ b/src/test/ui/issues/issue-22933-2.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `PIE` found for type `Delicious` in the current scope +error[E0599]: no variant or associated item named `PIE` found for enum `Delicious` in the current scope --> $DIR/issue-22933-2.rs:4:55 | LL | enum Delicious { diff --git a/src/test/ui/issues/issue-22933-3.rs b/src/test/ui/issues/issue-22933-3.rs index 8518ed34aee9f..fbcce4b834467 100644 --- a/src/test/ui/issues/issue-22933-3.rs +++ b/src/test/ui/issues/issue-22933-3.rs @@ -1,4 +1,4 @@ const FOO: [u32; u8::MIN as usize] = []; -//~^ ERROR no associated item named `MIN` found for type `u8` +//~^ ERROR no associated item named `MIN` found fn main() {} diff --git a/src/test/ui/issues/issue-23173.rs b/src/test/ui/issues/issue-23173.rs index 7c15598448d7f..92f4c546440ab 100644 --- a/src/test/ui/issues/issue-23173.rs +++ b/src/test/ui/issues/issue-23173.rs @@ -7,7 +7,7 @@ fn use_token(token: &Token) { unimplemented!() } fn main() { use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura` - Struct::method(); //~ ERROR no function or associated item named `method` found for type - Struct::method; //~ ERROR no function or associated item named `method` found for type - Struct::Assoc; //~ ERROR no associated item named `Assoc` found for type `Struct` in + Struct::method(); //~ ERROR no function or associated item named `method` found + Struct::method; //~ ERROR no function or associated item named `method` found + Struct::Assoc; //~ ERROR no associated item named `Assoc` found } diff --git a/src/test/ui/issues/issue-23173.stderr b/src/test/ui/issues/issue-23173.stderr index 699e41156fa80..89f70fda786ea 100644 --- a/src/test/ui/issues/issue-23173.stderr +++ b/src/test/ui/issues/issue-23173.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `Homura` found for type `Token` in the current scope +error[E0599]: no variant or associated item named `Homura` found for enum `Token` in the current scope --> $DIR/issue-23173.rs:9:23 | LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } @@ -7,7 +7,7 @@ LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } LL | use_token(&Token::Homura); | ^^^^^^ variant or associated item not found in `Token` -error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope +error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope --> $DIR/issue-23173.rs:10:13 | LL | struct Struct { @@ -16,7 +16,7 @@ LL | struct Struct { LL | Struct::method(); | ^^^^^^ function or associated item not found in `Struct` -error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope +error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope --> $DIR/issue-23173.rs:11:13 | LL | struct Struct { @@ -25,7 +25,7 @@ LL | struct Struct { LL | Struct::method; | ^^^^^^ function or associated item not found in `Struct` -error[E0599]: no associated item named `Assoc` found for type `Struct` in the current scope +error[E0599]: no associated item named `Assoc` found for struct `Struct` in the current scope --> $DIR/issue-23173.rs:12:13 | LL | struct Struct { diff --git a/src/test/ui/issues/issue-23217.rs b/src/test/ui/issues/issue-23217.rs index 157f20d22d8ae..09f9ebccf2505 100644 --- a/src/test/ui/issues/issue-23217.rs +++ b/src/test/ui/issues/issue-23217.rs @@ -1,5 +1,5 @@ pub enum SomeEnum { - B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found for type `SomeEnum` + B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found } fn main() {} diff --git a/src/test/ui/issues/issue-23217.stderr b/src/test/ui/issues/issue-23217.stderr index 97100ed375374..a81b459a34cbe 100644 --- a/src/test/ui/issues/issue-23217.stderr +++ b/src/test/ui/issues/issue-23217.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `A` found for type `SomeEnum` in the current scope +error[E0599]: no variant or associated item named `A` found for enum `SomeEnum` in the current scope --> $DIR/issue-23217.rs:2:19 | LL | pub enum SomeEnum { diff --git a/src/test/ui/issues/issue-25385.rs b/src/test/ui/issues/issue-25385.rs index adad6c35a3f67..ea042a6c76bb4 100644 --- a/src/test/ui/issues/issue-25385.rs +++ b/src/test/ui/issues/issue-25385.rs @@ -1,6 +1,6 @@ macro_rules! foo { ($e:expr) => { $e.foo() } - //~^ ERROR no method named `foo` found for type `i32` in the current scope + //~^ ERROR no method named `foo` found } fn main() { @@ -8,5 +8,5 @@ fn main() { foo!(a); foo!(1i32.foo()); - //~^ ERROR no method named `foo` found for type `i32` in the current scope + //~^ ERROR no method named `foo` found } diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index c9ede03003434..aa720fd45895a 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `C` in the current scope +error[E0599]: no method named `clone` found for struct `C` in the current scope --> $DIR/issue-2823.rs:13:16 | LL | struct C { diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index e315317c98a6c..77bc829209440 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -4,7 +4,7 @@ error[E0191]: the value of the associated type `Output` (from trait `std::ops::B LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^ help: specify the associated type: `BitXor` -error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope +error[E0599]: no function or associated item named `bitor` found for trait object `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:4:25 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); @@ -19,7 +19,7 @@ error[E0191]: the value of the associated type `Output` (from trait `std::ops::B LL | let g = BitXor::bitor; | ^^^^^^ help: specify the associated type: `BitXor` -error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope +error[E0599]: no function or associated item named `bitor` found for trait object `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:8:21 | LL | let g = BitXor::bitor; diff --git a/src/test/ui/issues/issue-28586.rs b/src/test/ui/issues/issue-28586.rs index 4d286be1e3302..c543ef9b0e3d8 100644 --- a/src/test/ui/issues/issue-28586.rs +++ b/src/test/ui/issues/issue-28586.rs @@ -2,6 +2,6 @@ pub trait Foo {} impl Foo for [u8; usize::BYTES] {} -//~^ ERROR no associated item named `BYTES` found for type `usize` +//~^ ERROR no associated item named `BYTES` found fn main() { } diff --git a/src/test/ui/issues/issue-28971.rs b/src/test/ui/issues/issue-28971.rs index 6493565d21647..f0a1e2d006179 100644 --- a/src/test/ui/issues/issue-28971.rs +++ b/src/test/ui/issues/issue-28971.rs @@ -5,7 +5,7 @@ fn main(){ foo(|| { match Foo::Bar(1) { Foo::Baz(..) => (), - //~^ ERROR no variant or associated item named `Baz` found for type `Foo` + //~^ ERROR no variant or associated item named `Baz` found _ => (), } }); diff --git a/src/test/ui/issues/issue-28971.stderr b/src/test/ui/issues/issue-28971.stderr index 7411896443dfe..2736ee881d564 100644 --- a/src/test/ui/issues/issue-28971.stderr +++ b/src/test/ui/issues/issue-28971.stderr @@ -1,4 +1,4 @@ -error[E0599]: no variant or associated item named `Baz` found for type `Foo` in the current scope +error[E0599]: no variant or associated item named `Baz` found for enum `Foo` in the current scope --> $DIR/issue-28971.rs:7:18 | LL | enum Foo { diff --git a/src/test/ui/issues/issue-29124.rs b/src/test/ui/issues/issue-29124.rs index 1cd3f84f7a227..dd2784841758c 100644 --- a/src/test/ui/issues/issue-29124.rs +++ b/src/test/ui/issues/issue-29124.rs @@ -13,7 +13,7 @@ fn func() -> Ret { fn main() { Obj::func.x(); - //~^ ERROR no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope + //~^ ERROR no method named `x` found func.x(); - //~^ ERROR no method named `x` found for type `fn() -> Ret {func}` in the current scope + //~^ ERROR no method named `x` found } diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index c537c6118f3a8..fff20248b70d5 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope +error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in the current scope --> $DIR/issue-29124.rs:15:15 | LL | Obj::func.x(); @@ -6,7 +6,7 @@ LL | Obj::func.x(); | = note: Obj::func is a function, perhaps you wish to call it -error[E0599]: no method named `x` found for type `fn() -> Ret {func}` in the current scope +error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope --> $DIR/issue-29124.rs:17:10 | LL | func.x(); diff --git a/src/test/ui/issues/issue-30123.rs b/src/test/ui/issues/issue-30123.rs index 4fc32e0de8d57..705355d91bf3c 100644 --- a/src/test/ui/issues/issue-30123.rs +++ b/src/test/ui/issues/issue-30123.rs @@ -5,5 +5,5 @@ use issue_30123_aux::*; fn main() { let ug = Graph::::new_undirected(); - //~^ ERROR no function or associated item named `new_undirected` found for type + //~^ ERROR no function or associated item named `new_undirected` found } diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 32bbd4d03d6d7..bc6731601f095 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `new_undirected` found for type `issue_30123_aux::Graph` in the current scope +error[E0599]: no function or associated item named `new_undirected` found for struct `issue_30123_aux::Graph` in the current scope --> $DIR/issue-30123.rs:7:33 | LL | let ug = Graph::::new_undirected(); diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index 38cf3c4f930e8..a614b96ac1439 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -7,7 +7,7 @@ LL | .cloned() = note: expected type `u8` found reference `&_` -error[E0599]: no method named `collect` found for type `std::iter::Cloned, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>` in the current scope +error[E0599]: no method named `collect` found for struct `std::iter::Cloned, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>` in the current scope --> $DIR/issue-31173.rs:14:10 | LL | .collect(); diff --git a/src/test/ui/issues/issue-33575.rs b/src/test/ui/issues/issue-33575.rs index 09c499452adb6..de544afae73b2 100644 --- a/src/test/ui/issues/issue-33575.rs +++ b/src/test/ui/issues/issue-33575.rs @@ -1,4 +1,4 @@ fn main() { - let baz = ().foo(); //~ ERROR no method named `foo` found for type `()` in the current scope + let baz = ().foo(); //~ ERROR no method named `foo` found ::from_str(&baz); // No complaints about `str` being unsized } diff --git a/src/test/ui/issues/issue-33575.stderr b/src/test/ui/issues/issue-33575.stderr index e6b74d262c340..bbd8042d1cd6b 100644 --- a/src/test/ui/issues/issue-33575.stderr +++ b/src/test/ui/issues/issue-33575.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `()` in the current scope +error[E0599]: no method named `foo` found for unit type `()` in the current scope --> $DIR/issue-33575.rs:2:18 | LL | let baz = ().foo(); diff --git a/src/test/ui/issues/issue-34209.rs b/src/test/ui/issues/issue-34209.rs index fc2c3679e13b8..632ddb91b36fd 100644 --- a/src/test/ui/issues/issue-34209.rs +++ b/src/test/ui/issues/issue-34209.rs @@ -4,7 +4,7 @@ enum S { fn bug(l: S) { match l { - S::B {} => {}, //~ ERROR no variant `B` in enum `S` + S::B {} => {}, //~ ERROR no variant named `B` found for enum `S` } } diff --git a/src/test/ui/issues/issue-34209.stderr b/src/test/ui/issues/issue-34209.stderr index 194bb2bfab8ae..f9a25b69ff621 100644 --- a/src/test/ui/issues/issue-34209.stderr +++ b/src/test/ui/issues/issue-34209.stderr @@ -1,4 +1,4 @@ -error: no variant `B` in enum `S` +error[E0599]: no variant named `B` found for enum `S` --> $DIR/issue-34209.rs:7:12 | LL | enum S { @@ -9,3 +9,4 @@ LL | S::B {} => {}, error: aborting due to previous error +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-34334.rs b/src/test/ui/issues/issue-34334.rs index e34b5c9a0f47e..afe4d42edd8c8 100644 --- a/src/test/ui/issues/issue-34334.rs +++ b/src/test/ui/issues/issue-34334.rs @@ -7,5 +7,5 @@ fn main () { //~| ERROR expected expression, found reserved identifier `_` //~| ERROR expected expression, found reserved identifier `_` let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); - //~^ ERROR no method named `iter` found for type `()` in the current scope + //~^ ERROR no method named `iter` found } diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index 3055e316a082a..c52ea4ef9daa9 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -43,7 +43,7 @@ LL | let sr: Vec<(u32, _, _) = vec![]; | | | cannot assign to this expression -error[E0599]: no method named `iter` found for type `()` in the current scope +error[E0599]: no method named `iter` found for unit type `()` in the current scope --> $DIR/issue-34334.rs:9:36 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr index b381203856e92..a998f95d306cb 100644 --- a/src/test/ui/issues/issue-35677.stderr +++ b/src/test/ui/issues/issue-35677.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `is_subset` found for type `&std::collections::HashSet` in the current scope +error[E0599]: no method named `is_subset` found for reference `&std::collections::HashSet` in the current scope --> $DIR/issue-35677.rs:4:10 | LL | this.is_subset(other) diff --git a/src/test/ui/issues/issue-3707.rs b/src/test/ui/issues/issue-3707.rs index 844a2dc00698e..0817c51ee4eab 100644 --- a/src/test/ui/issues/issue-3707.rs +++ b/src/test/ui/issues/issue-3707.rs @@ -7,7 +7,7 @@ impl Obj { return 1+1 == 2 } pub fn chirp(&self) { - self.boom(); //~ ERROR no method named `boom` found for type `&Obj` in the current scope + self.boom(); //~ ERROR no method named `boom` found } } diff --git a/src/test/ui/issues/issue-3707.stderr b/src/test/ui/issues/issue-3707.stderr index b98bc572a397c..6ca2deee377a3 100644 --- a/src/test/ui/issues/issue-3707.stderr +++ b/src/test/ui/issues/issue-3707.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `boom` found for type `&Obj` in the current scope +error[E0599]: no method named `boom` found for reference `&Obj` in the current scope --> $DIR/issue-3707.rs:10:14 | LL | self.boom(); diff --git a/src/test/ui/issues/issue-38919.rs b/src/test/ui/issues/issue-38919.rs index 60a8793b4e6be..3d28f1936b47f 100644 --- a/src/test/ui/issues/issue-38919.rs +++ b/src/test/ui/issues/issue-38919.rs @@ -1,5 +1,5 @@ fn foo() { - T::Item; //~ ERROR no associated item named `Item` found for type `T` in the current scope + T::Item; //~ ERROR no associated item named `Item` found } fn main() { } diff --git a/src/test/ui/issues/issue-38919.stderr b/src/test/ui/issues/issue-38919.stderr index 603d42ca35e0b..0022065a32c3d 100644 --- a/src/test/ui/issues/issue-38919.stderr +++ b/src/test/ui/issues/issue-38919.stderr @@ -1,4 +1,4 @@ -error[E0599]: no associated item named `Item` found for type `T` in the current scope +error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope --> $DIR/issue-38919.rs:2:8 | LL | T::Item; diff --git a/src/test/ui/issues/issue-39175.stderr b/src/test/ui/issues/issue-39175.stderr index 8b173e1b50c1e..2f6e676538e96 100644 --- a/src/test/ui/issues/issue-39175.stderr +++ b/src/test/ui/issues/issue-39175.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `exec` found for type `&mut std::process::Command` in the current scope +error[E0599]: no method named `exec` found for mutable reference `&mut std::process::Command` in the current scope --> $DIR/issue-39175.rs:15:39 | LL | Command::new("echo").arg("hello").exec(); diff --git a/src/test/ui/issues/issue-39559.rs b/src/test/ui/issues/issue-39559.rs index 5af48ca4c0dbc..3a75956af5280 100644 --- a/src/test/ui/issues/issue-39559.rs +++ b/src/test/ui/issues/issue-39559.rs @@ -12,7 +12,7 @@ impl Dim for Dim3 { pub struct Vector { entries: [T; D::dim()], - //~^ ERROR no function or associated item named `dim` found for type `D` in the current scope + //~^ ERROR no function or associated item named `dim` found _dummy: D, } diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr index b945b5e665459..0554b232c248b 100644 --- a/src/test/ui/issues/issue-39559.stderr +++ b/src/test/ui/issues/issue-39559.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `dim` found for type `D` in the current scope +error[E0599]: no function or associated item named `dim` found for type parameter `D` in the current scope --> $DIR/issue-39559.rs:14:21 | LL | entries: [T; D::dim()], diff --git a/src/test/ui/issues/issue-3973.rs b/src/test/ui/issues/issue-3973.rs index 4e00915683a2d..a5ed5b87051e7 100644 --- a/src/test/ui/issues/issue-3973.rs +++ b/src/test/ui/issues/issue-3973.rs @@ -20,6 +20,6 @@ impl ToString_ for Point { fn main() { let p = Point::new(0.0, 0.0); - //~^ ERROR no function or associated item named `new` found for type `Point` + //~^ ERROR no function or associated item named `new` found for struct `Point` println!("{}", p.to_string()); } diff --git a/src/test/ui/issues/issue-3973.stderr b/src/test/ui/issues/issue-3973.stderr index ee07a410a9c86..63282e8d86d7b 100644 --- a/src/test/ui/issues/issue-3973.stderr +++ b/src/test/ui/issues/issue-3973.stderr @@ -7,7 +7,7 @@ LL | | Point { x: x, y: y } LL | | } | |_____^ not a member of trait `ToString_` -error[E0599]: no function or associated item named `new` found for type `Point` in the current scope +error[E0599]: no function or associated item named `new` found for struct `Point` in the current scope --> $DIR/issue-3973.rs:22:20 | LL | struct Point { diff --git a/src/test/ui/issues/issue-41880.rs b/src/test/ui/issues/issue-41880.rs index 16facc5a78f8d..10cde21abd766 100644 --- a/src/test/ui/issues/issue-41880.rs +++ b/src/test/ui/issues/issue-41880.rs @@ -25,5 +25,5 @@ impl Iterator for Iterate where F: Fn(&T) -> T { fn main() { let a = iterate(0, |x| x+1); println!("{:?}", a.iter().take(10).collect::>()); - //~^ ERROR no method named `iter` found for type `Iterate<{integer} + //~^ ERROR no method named `iter` found } diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index 0e1d55c339eb4..09d5594f73f06 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for type `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/issues/issue-42880.stderr b/src/test/ui/issues/issue-42880.stderr index 763bb9ae0ea9c..82cdc20df2fbd 100644 --- a/src/test/ui/issues/issue-42880.stderr +++ b/src/test/ui/issues/issue-42880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no associated item named `String` found for type `std::string::String` in the current scope +error[E0599]: no associated item named `String` found for struct `std::string::String` in the current scope --> $DIR/issue-42880.rs:4:22 | LL | let f = |&Value::String(_)| (); diff --git a/src/test/ui/issues/issue-43189.rs b/src/test/ui/issues/issue-43189.rs index f4f4dce7682fa..ce667a5006e6f 100644 --- a/src/test/ui/issues/issue-43189.rs +++ b/src/test/ui/issues/issue-43189.rs @@ -8,5 +8,5 @@ extern crate xcrate_issue_43189_b; fn main() { ().a(); - //~^ ERROR no method named `a` found for type `()` in the current scope [E0599] + //~^ ERROR no method named `a` found } diff --git a/src/test/ui/issues/issue-43189.stderr b/src/test/ui/issues/issue-43189.stderr index 4dae6c1cd158e..3f63cb8e78fba 100644 --- a/src/test/ui/issues/issue-43189.stderr +++ b/src/test/ui/issues/issue-43189.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `a` found for type `()` in the current scope +error[E0599]: no method named `a` found for unit type `()` in the current scope --> $DIR/issue-43189.rs:10:8 | LL | ().a(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs index 24c61425b8e29..5b6b8f8de18e2 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs @@ -1,4 +1,4 @@ fn main() { let _result = &Some(42).as_deref(); -//~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>` +//~^ ERROR no method named `as_deref` found for enum `std::option::Option<{integer}>` } diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr index 0eb7bf0247565..f91f6e891ed90 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope +error[E0599]: no method named `as_deref` found for enum `std::option::Option<{integer}>` in the current scope --> $DIR/option-as_deref.rs:2:29 | LL | let _result = &Some(42).as_deref(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs index 67ad73f584773..c5fe6ea82cb0e 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs @@ -1,4 +1,4 @@ fn main() { let _result = &mut Some(42).as_deref_mut(); -//~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>` +//~^ ERROR no method named `as_deref_mut` found for enum `std::option::Option<{integer}>` } diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr index 845ddb52319c7..583236345cac1 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope +error[E0599]: no method named `as_deref_mut` found for enum `std::option::Option<{integer}>` in the current scope --> $DIR/option-as_deref_mut.rs:2:33 | LL | let _result = &mut Some(42).as_deref_mut(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr index 5e016748770dc..fae11fe62b16c 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref` found for type `std::result::Result<{integer}, _>` in the current scope +error[E0599]: no method named `as_deref` found for enum `std::result::Result<{integer}, _>` in the current scope --> $DIR/result-as_deref.rs:4:27 | LL | let _result = &Ok(42).as_deref(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr index 6dc13da548b12..48a662e98b547 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_err` found for type `std::result::Result<_, {integer}>` in the current scope +error[E0599]: no method named `as_deref_err` found for enum `std::result::Result<_, {integer}>` in the current scope --> $DIR/result-as_deref_err.rs:4:28 | LL | let _result = &Err(41).as_deref_err(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr index f21e97388b6f4..2c6231fb3b589 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_mut` found for type `std::result::Result<{integer}, _>` in the current scope +error[E0599]: no method named `as_deref_mut` found for enum `std::result::Result<{integer}, _>` in the current scope --> $DIR/result-as_deref_mut.rs:4:31 | LL | let _result = &mut Ok(42).as_deref_mut(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr index 44c0c954eeeca..8a5c2f4006051 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_mut_err` found for type `std::result::Result<_, {integer}>` in the current scope +error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Result<_, {integer}>` in the current scope --> $DIR/result-as_deref_mut_err.rs:4:32 | LL | let _result = &mut Err(41).as_deref_mut_err(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr index b8369c9b82e1a..af8d657999cb0 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_mut_ok` found for type `std::result::Result<{integer}, _>` in the current scope +error[E0599]: no method named `as_deref_mut_ok` found for enum `std::result::Result<{integer}, _>` in the current scope --> $DIR/result-as_deref_mut_ok.rs:4:31 | LL | let _result = &mut Ok(42).as_deref_mut_ok(); diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr index b26705a99e3bc..145e610d52c7c 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `as_deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope +error[E0599]: no method named `as_deref_ok` found for enum `std::result::Result<{integer}, _>` in the current scope --> $DIR/result-as_deref_ok.rs:4:27 | LL | let _result = &Ok(42).as_deref_ok(); diff --git a/src/test/ui/issues/issue-5153.rs b/src/test/ui/issues/issue-5153.rs index e6737662088f2..5bf0579030ad0 100644 --- a/src/test/ui/issues/issue-5153.rs +++ b/src/test/ui/issues/issue-5153.rs @@ -8,5 +8,5 @@ impl Foo for isize { fn main() { (&5isize as &dyn Foo).foo(); - //~^ ERROR: no method named `foo` found for type `&dyn Foo` in the current scope + //~^ ERROR: no method named `foo` found for reference `&dyn Foo` in the current scope } diff --git a/src/test/ui/issues/issue-5153.stderr b/src/test/ui/issues/issue-5153.stderr index 5034e6d538e3e..4680c8b131c50 100644 --- a/src/test/ui/issues/issue-5153.stderr +++ b/src/test/ui/issues/issue-5153.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `&dyn Foo` in the current scope +error[E0599]: no method named `foo` found for reference `&dyn Foo` in the current scope --> $DIR/issue-5153.rs:10:27 | LL | (&5isize as &dyn Foo).foo(); diff --git a/src/test/ui/issues/issue-54062.stderr b/src/test/ui/issues/issue-54062.stderr index 3830ad4b1e3ae..5222e3ee95d59 100644 --- a/src/test/ui/issues/issue-54062.stderr +++ b/src/test/ui/issues/issue-54062.stderr @@ -4,7 +4,7 @@ error[E0616]: field `inner` of struct `std::sync::Mutex` is private LL | let _ = test.comps.inner.lock().unwrap(); | ^^^^^^^^^^^^^^^^ -error[E0599]: no method named `unwrap` found for type `std::sys_common::mutex::MutexGuard<'_>` in the current scope +error[E0599]: no method named `unwrap` found for struct `std::sys_common::mutex::MutexGuard<'_>` in the current scope --> $DIR/issue-54062.rs:10:37 | LL | let _ = test.comps.inner.lock().unwrap(); diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index c4000c8a9d41e..e762b7bc0c899 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `f` found for type `fn(&u8)` in the current scope +error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current scope --> $DIR/issue-57362-1.rs:20:7 | LL | a.f(); diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr index 2e713cc0ab508..3528084f6ceb4 100644 --- a/src/test/ui/issues/issue-57362-2.stderr +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `make_g` found for type `for<'r> fn(&'r ())` in the current scope +error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope --> $DIR/issue-57362-2.rs:22:25 | LL | let x = ::make_g(); diff --git a/src/test/ui/issues/issue-58734.rs b/src/test/ui/issues/issue-58734.rs index bbdfebe1577c7..b253c135b8c52 100644 --- a/src/test/ui/issues/issue-58734.rs +++ b/src/test/ui/issues/issue-58734.rs @@ -18,5 +18,5 @@ fn main() { Trait::exists(()); // no object safety error Trait::nonexistent(()); - //~^ ERROR no function or associated item named `nonexistent` found for type `dyn Trait` + //~^ ERROR no function or associated item named `nonexistent` found } diff --git a/src/test/ui/issues/issue-58734.stderr b/src/test/ui/issues/issue-58734.stderr index 07f2a046b2dbb..5e98cfadf8ae7 100644 --- a/src/test/ui/issues/issue-58734.stderr +++ b/src/test/ui/issues/issue-58734.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `nonexistent` found for type `dyn Trait` in the current scope +error[E0599]: no function or associated item named `nonexistent` found for trait object `dyn Trait` in the current scope --> $DIR/issue-58734.rs:20:12 | LL | Trait::nonexistent(()); diff --git a/src/test/ui/issues/issue-64430.stderr b/src/test/ui/issues/issue-64430.stderr index f1b2de8d8b36f..e7a244e9df576 100644 --- a/src/test/ui/issues/issue-64430.stderr +++ b/src/test/ui/issues/issue-64430.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `bar` found for type `Foo` in the current scope +error[E0599]: no method named `bar` found for struct `Foo` in the current scope --> $DIR/issue-64430.rs:7:9 | LL | pub struct Foo; diff --git a/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs b/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs index e0eaafdfc2f22..018ce0459fd6f 100644 --- a/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs +++ b/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.rs @@ -5,7 +5,7 @@ trait Foo { trait Bar {} fn do_stuff(t : T) { - t.foo() //~ ERROR no method named `foo` found for type `T` in the current scope + t.foo() //~ ERROR no method named `foo` found } fn main() {} diff --git a/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.stderr b/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.stderr index 24bf60abf6a78..4807a0930e7d0 100644 --- a/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.stderr +++ b/src/test/ui/issues/issue-65284-suggest-generic-trait-bound.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `T` in the current scope +error[E0599]: no method named `foo` found for type parameter `T` in the current scope --> $DIR/issue-65284-suggest-generic-trait-bound.rs:8:7 | LL | t.foo() diff --git a/src/test/ui/issues/issue-7950.rs b/src/test/ui/issues/issue-7950.rs index 7add8afee437f..d3dcb3380bbcc 100644 --- a/src/test/ui/issues/issue-7950.rs +++ b/src/test/ui/issues/issue-7950.rs @@ -4,5 +4,5 @@ struct Foo; fn main() { Foo::bar(); - //~^ ERROR no function or associated item named `bar` found for type `Foo` + //~^ ERROR no function or associated item named `bar` found for struct `Foo` } diff --git a/src/test/ui/issues/issue-7950.stderr b/src/test/ui/issues/issue-7950.stderr index bbeab405e2935..73e13c65cf37f 100644 --- a/src/test/ui/issues/issue-7950.stderr +++ b/src/test/ui/issues/issue-7950.stderr @@ -1,4 +1,4 @@ -error[E0599]: no function or associated item named `bar` found for type `Foo` in the current scope +error[E0599]: no function or associated item named `bar` found for struct `Foo` in the current scope --> $DIR/issue-7950.rs:6:10 | LL | struct Foo; diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr index a7843a930119a..6bb0877e9b9ba 100644 --- a/src/test/ui/lexical-scopes.stderr +++ b/src/test/ui/lexical-scopes.stderr @@ -9,7 +9,7 @@ help: possible better candidate is found in another module, you can import it in LL | use T; | -error[E0599]: no function or associated item named `f` found for type `Foo` in the current scope +error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope --> $DIR/lexical-scopes.rs:10:10 | LL | Foo::f(); diff --git a/src/test/ui/methods/method-call-err-msg.rs b/src/test/ui/methods/method-call-err-msg.rs index e0dec0a4a705f..5ff4b412667c2 100644 --- a/src/test/ui/methods/method-call-err-msg.rs +++ b/src/test/ui/methods/method-call-err-msg.rs @@ -15,6 +15,6 @@ fn main() { let y = Foo; y.zero() - .take() //~ ERROR no method named `take` found for type `Foo` in the current scope + .take() //~ ERROR no method named `take` found .one(0); } diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr index 94c27b7d17865..7efdd91708a80 100644 --- a/src/test/ui/methods/method-call-err-msg.stderr +++ b/src/test/ui/methods/method-call-err-msg.stderr @@ -25,7 +25,7 @@ LL | fn two(self, _: isize, _: isize) -> Foo { self } LL | .two(0); | ^^^ expected 2 parameters -error[E0599]: no method named `take` found for type `Foo` in the current scope +error[E0599]: no method named `take` found for struct `Foo` in the current scope --> $DIR/method-call-err-msg.rs:18:7 | LL | pub struct Foo; diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index da018aa89482c..f8d677b99d693 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `count` found for type `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` in the current scope +error[E0599]: no method named `count` found for struct `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` in the current scope --> $DIR/issue-36053-2.rs:7:55 | LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs index 83cea16846515..58ceaffc96400 100644 --- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs @@ -3,5 +3,5 @@ struct Foo; fn main() { let a: Result<(), Foo> = Ok(()); a.unwrap(); - //~^ ERROR no method named `unwrap` found for type `std::result::Result<(), Foo>` + //~^ ERROR no method named `unwrap` found } diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr index 865092e4e9ccc..bbfb00050566a 100644 --- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `unwrap` found for type `std::result::Result<(), Foo>` in the current scope +error[E0599]: no method named `unwrap` found for enum `std::result::Result<(), Foo>` in the current scope --> $DIR/method-help-unsatisfied-bound.rs:5:7 | LL | a.unwrap(); diff --git a/src/test/ui/never_type/issue-2149.rs b/src/test/ui/never_type/issue-2149.rs index d46f0e61793f3..d6426d2cfabfd 100644 --- a/src/test/ui/never_type/issue-2149.rs +++ b/src/test/ui/never_type/issue-2149.rs @@ -11,5 +11,5 @@ impl VecMonad for Vec { } fn main() { ["hi"].bind(|x| [x] ); - //~^ ERROR no method named `bind` found for type `[&str; 1]` in the current scope + //~^ ERROR no method named `bind` found } diff --git a/src/test/ui/never_type/issue-2149.stderr b/src/test/ui/never_type/issue-2149.stderr index 8ce2ba033321e..9645244751dab 100644 --- a/src/test/ui/never_type/issue-2149.stderr +++ b/src/test/ui/never_type/issue-2149.stderr @@ -6,7 +6,7 @@ LL | for elt in self { r = r + f(*elt); } | = help: the trait `std::ops::Add>` is not implemented for `()` -error[E0599]: no method named `bind` found for type `[&str; 1]` in the current scope +error[E0599]: no method named `bind` found for array `[&str; 1]` in the current scope --> $DIR/issue-2149.rs:13:12 | LL | ["hi"].bind(|x| [x] ); diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr index b05c29c0d4036..074ed66a26183 100644 --- a/src/test/ui/non-copyable-void.stderr +++ b/src/test/ui/non-copyable-void.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `libc::c_void` in the current scope +error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope --> $DIR/non-copyable-void.rs:11:23 | LL | let _z = (*y).clone(); diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index c1c5021138189..6c3c4a6ac9888 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `Foo` in the current scope +error[E0599]: no method named `clone` found for struct `Foo` in the current scope --> $DIR/noncopyable-class.rs:34:16 | LL | struct Foo { diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index 2df628ecf8e50..855894b4495c6 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `owned` found for type `&dyn Foo` in the current scope +error[E0599]: no method named `owned` found for reference `&dyn Foo` in the current scope --> $DIR/object-pointer-types.rs:11:7 | LL | x.owned(); @@ -8,7 +8,7 @@ LL | x.owned(); = note: the following trait defines an item `owned`, perhaps you need to implement it: candidate #1: `Foo` -error[E0599]: no method named `owned` found for type `&mut dyn Foo` in the current scope +error[E0599]: no method named `owned` found for mutable reference `&mut dyn Foo` in the current scope --> $DIR/object-pointer-types.rs:17:7 | LL | x.owned(); @@ -18,7 +18,7 @@ LL | x.owned(); = note: the following trait defines an item `owned`, perhaps you need to implement it: candidate #1: `Foo` -error[E0599]: no method named `managed` found for type `std::boxed::Box<(dyn Foo + 'static)>` in the current scope +error[E0599]: no method named `managed` found for struct `std::boxed::Box<(dyn Foo + 'static)>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr index dec5809f1539b..96401cb71d961 100644 --- a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr +++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `A` in the current scope +error[E0599]: no method named `foo` found for struct `A` in the current scope --> $DIR/point-at-arbitrary-self-type-method.rs:8:7 | LL | struct A; diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr index e93c4da9dfc85..28a7b68a6821f 100644 --- a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr +++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `A` in the current scope +error[E0599]: no method named `foo` found for struct `A` in the current scope --> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7 | LL | trait B { fn foo(self: Box); } diff --git a/src/test/ui/self/suggest-self-2.rs b/src/test/ui/self/suggest-self-2.rs index d6bf543352701..1e001827e475f 100644 --- a/src/test/ui/self/suggest-self-2.rs +++ b/src/test/ui/self/suggest-self-2.rs @@ -18,7 +18,7 @@ impl Foo { //~^ ERROR cannot find function `bar` in this scope self.bar(); - //~^ ERROR no method named `bar` found for type + //~^ ERROR no method named `bar` found for reference } } diff --git a/src/test/ui/self/suggest-self-2.stderr b/src/test/ui/self/suggest-self-2.stderr index 452c31275153a..4bd025ea07630 100644 --- a/src/test/ui/self/suggest-self-2.stderr +++ b/src/test/ui/self/suggest-self-2.stderr @@ -28,7 +28,7 @@ error[E0425]: cannot find function `bar` in this scope LL | bar(); | ^^^ not found in this scope -error[E0599]: no method named `bar` found for type `&Foo` in the current scope +error[E0599]: no method named `bar` found for reference `&Foo` in the current scope --> $DIR/suggest-self-2.rs:20:14 | LL | self.bar(); diff --git a/src/test/ui/shadowed/shadowed-trait-methods.stderr b/src/test/ui/shadowed/shadowed-trait-methods.stderr index 3597cc53420aa..362907ecbd7ef 100644 --- a/src/test/ui/shadowed/shadowed-trait-methods.stderr +++ b/src/test/ui/shadowed/shadowed-trait-methods.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `f` found for type `()` in the current scope +error[E0599]: no method named `f` found for unit type `()` in the current scope --> $DIR/shadowed-trait-methods.rs:13:8 | LL | ().f() diff --git a/src/test/ui/span/issue-7575.rs b/src/test/ui/span/issue-7575.rs index ea0a66540b931..eddd158aef081 100644 --- a/src/test/ui/span/issue-7575.rs +++ b/src/test/ui/span/issue-7575.rs @@ -60,15 +60,15 @@ impl ManyImplTrait for Myisize {} fn no_param_bound(u: usize, m: Myisize) -> usize { u.f8(42) + u.f9(342) + m.fff(42) - //~^ ERROR no method named `f9` found for type `usize` in the current scope - //~| ERROR no method named `fff` found for type `Myisize` in the current scope + //~^ ERROR no method named `f9` found + //~| ERROR no method named `fff` found } fn param_bound(t: T) -> bool { t.is_str() - //~^ ERROR no method named `is_str` found for type `T` in the current scope + //~^ ERROR no method named `is_str` found } fn main() { diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 53a6238422b57..eb85be039ba04 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -38,7 +38,7 @@ help: disambiguate the method call for candidate #3 LL | u.f8(42) + UnusedTrait::f9(u, 342) + m.fff(42) | ^^^^^^^^^^^^^^^^^^^^^^^ -error[E0599]: no method named `fff` found for type `Myisize` in the current scope +error[E0599]: no method named `fff` found for struct `Myisize` in the current scope --> $DIR/issue-7575.rs:62:30 | LL | struct Myisize(isize); @@ -57,7 +57,7 @@ note: the candidate is defined in an impl for the type `Myisize` LL | fn fff(i: isize) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0599]: no method named `is_str` found for type `T` in the current scope +error[E0599]: no method named `is_str` found for type parameter `T` in the current scope --> $DIR/issue-7575.rs:70:7 | LL | t.is_str() diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs index 34a141685739c..5c104449fe9c0 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs @@ -20,5 +20,5 @@ default impl Foo for T { fn main() { println!("{}", MyStruct.foo_one()); - //~^ ERROR no method named `foo_one` found for type `MyStruct` in the current scope + //~^ ERROR no method named `foo_one` found } 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 bbfe4c3d59dcf..19809778a5e36 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo_one` found for type `MyStruct` in the current scope +error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope --> $DIR/specialization-trait-not-implemented.rs:22:29 | LL | struct MyStruct; diff --git a/src/test/ui/suggestions/constrain-trait.fixed b/src/test/ui/suggestions/constrain-trait.fixed index dda9e931353b2..f292f27f0f342 100644 --- a/src/test/ui/suggestions/constrain-trait.fixed +++ b/src/test/ui/suggestions/constrain-trait.fixed @@ -12,13 +12,13 @@ trait GetString { trait UseString: std::fmt::Debug + GetString { fn use_string(&self) { - println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` + println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found } } trait UseString2: GetString { fn use_string(&self) { - println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` + println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found } } diff --git a/src/test/ui/suggestions/constrain-trait.rs b/src/test/ui/suggestions/constrain-trait.rs index 4ef0eff5bd769..99ccf7a7f3bdf 100644 --- a/src/test/ui/suggestions/constrain-trait.rs +++ b/src/test/ui/suggestions/constrain-trait.rs @@ -12,13 +12,13 @@ trait GetString { trait UseString: std::fmt::Debug { fn use_string(&self) { - println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` + println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found } } trait UseString2 { fn use_string(&self) { - println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self` + println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found } } diff --git a/src/test/ui/suggestions/constrain-trait.stderr b/src/test/ui/suggestions/constrain-trait.stderr index 3cc351ac80aed..f1c50e59a845e 100644 --- a/src/test/ui/suggestions/constrain-trait.stderr +++ b/src/test/ui/suggestions/constrain-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `get_a` found for type `&Self` in the current scope +error[E0599]: no method named `get_a` found for reference `&Self` in the current scope --> $DIR/constrain-trait.rs:15:31 | LL | println!("{:?}", self.get_a()); @@ -10,7 +10,7 @@ help: the following trait defines an item `get_a`, perhaps you need to add anoth LL | trait UseString: std::fmt::Debug + GetString { | ^^^^^^^^^^^ -error[E0599]: no method named `get_a` found for type `&Self` in the current scope +error[E0599]: no method named `get_a` found for reference `&Self` in the current scope --> $DIR/constrain-trait.rs:21:31 | LL | println!("{:?}", self.get_a()); diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr index 4aec72006eef0..db54d044d9e92 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `hello` found for type `impl Foo` in the current scope +error[E0599]: no method named `hello` found for type parameter `impl Foo` in the current scope --> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9 | LL | foo.hello(); diff --git a/src/test/ui/suggestions/issue-21673.stderr b/src/test/ui/suggestions/issue-21673.stderr index f2496f696d698..14c7b18ea51d3 100644 --- a/src/test/ui/suggestions/issue-21673.stderr +++ b/src/test/ui/suggestions/issue-21673.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `method` found for type `&T` in the current scope +error[E0599]: no method named `method` found for reference `&T` in the current scope --> $DIR/issue-21673.rs:6:7 | LL | x.method() @@ -10,7 +10,7 @@ help: the following trait defines an item `method`, perhaps you need to restrict LL | fn call_method(x: &T) { | ^^^^^^^^ -error[E0599]: no method named `method` found for type `T` in the current scope +error[E0599]: no method named `method` found for type parameter `T` in the current scope --> $DIR/issue-21673.rs:10:7 | LL | x.method() diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs b/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs index dcef2ada63bea..f8b86377187c5 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs @@ -19,5 +19,5 @@ fn main() { //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - writeln!(fp, "hello world").unwrap(); //~ ERROR no method named `write_fmt` found for type + writeln!(fp, "hello world").unwrap(); //~ ERROR no method named `write_fmt` found for struct } diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index daa8e1162d197..2c3c07c19e7bd 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -25,7 +25,7 @@ LL | let fp = BufWriter::new(fp); = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` = note: required by `std::io::BufWriter` -error[E0599]: no method named `write_fmt` found for type `std::io::BufWriter<&dyn std::io::Write>` in the current scope +error[E0599]: no method named `write_fmt` found for struct `std::io::BufWriter<&dyn std::io::Write>` in the current scope --> $DIR/mut-borrow-needed-by-trait.rs:22:5 | LL | writeln!(fp, "hello world").unwrap(); diff --git a/src/test/ui/suggestions/remove-as_str.rs b/src/test/ui/suggestions/remove-as_str.rs index d10300b48ba1e..289a784ba6af3 100644 --- a/src/test/ui/suggestions/remove-as_str.rs +++ b/src/test/ui/suggestions/remove-as_str.rs @@ -1,21 +1,21 @@ fn foo1(s: &str) { s.as_str(); - //~^ ERROR no method named `as_str` found for type `&str` in the current scope + //~^ ERROR no method named `as_str` found } fn foo2<'a>(s: &'a str) { s.as_str(); - //~^ ERROR no method named `as_str` found for type `&'a str` in the current scope + //~^ ERROR no method named `as_str` found } fn foo3(s: &mut str) { s.as_str(); - //~^ ERROR no method named `as_str` found for type `&mut str` in the current scope + //~^ ERROR no method named `as_str` found } fn foo4(s: &&str) { s.as_str(); - //~^ ERROR no method named `as_str` found for type `&&str` in the current scope + //~^ ERROR no method named `as_str` found } fn main() {} diff --git a/src/test/ui/suggestions/remove-as_str.stderr b/src/test/ui/suggestions/remove-as_str.stderr index eae9cc075084a..534c497780a95 100644 --- a/src/test/ui/suggestions/remove-as_str.stderr +++ b/src/test/ui/suggestions/remove-as_str.stderr @@ -1,22 +1,22 @@ -error[E0599]: no method named `as_str` found for type `&str` in the current scope +error[E0599]: no method named `as_str` found for reference `&str` in the current scope --> $DIR/remove-as_str.rs:2:7 | LL | s.as_str(); | -^^^^^^-- help: remove this method call -error[E0599]: no method named `as_str` found for type `&'a str` in the current scope +error[E0599]: no method named `as_str` found for reference `&'a str` in the current scope --> $DIR/remove-as_str.rs:7:7 | LL | s.as_str(); | -^^^^^^-- help: remove this method call -error[E0599]: no method named `as_str` found for type `&mut str` in the current scope +error[E0599]: no method named `as_str` found for mutable reference `&mut str` in the current scope --> $DIR/remove-as_str.rs:12:7 | LL | s.as_str(); | -^^^^^^-- help: remove this method call -error[E0599]: no method named `as_str` found for type `&&str` in the current scope +error[E0599]: no method named `as_str` found for reference `&&str` in the current scope --> $DIR/remove-as_str.rs:17:7 | LL | s.as_str(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs index 5480adb31015a..f738a1f211981 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs @@ -9,5 +9,5 @@ fn main() { let shared_state = RefCell::new(HasAssocMethod); let state = shared_state.borrow_mut(); state.hello(); - //~^ ERROR no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>` + //~^ ERROR no method named `hello` found } diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr index a1c0126146e73..507f822e7b804 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `hello` found for type `std::cell::RefMut<'_, HasAssocMethod>` in the current scope +error[E0599]: no method named `hello` found for struct `std::cell::RefMut<'_, HasAssocMethod>` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11 | LL | state.hello(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index ef4b38de94732..2a829db538390 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -7,5 +7,5 @@ impl GenericAssocMethod { fn main() { let x = GenericAssocMethod(33i32); x.default_hello(); - //~^ ERROR no method named `default_hello` found for type `GenericAssocMethod` + //~^ ERROR no method named `default_hello` found } diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 8cfa7de08bb38..dfc1887d3af90 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `default_hello` found for type `GenericAssocMethod` in the current scope +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7 | LL | struct GenericAssocMethod(T); diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr index 4678410eb4859..a715c565946e0 100644 --- a/src/test/ui/suggestions/suggest-methods.stderr +++ b/src/test/ui/suggestions/suggest-methods.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `bat` found for type `Foo` in the current scope +error[E0599]: no method named `bat` found for struct `Foo` in the current scope --> $DIR/suggest-methods.rs:18:7 | LL | struct Foo; @@ -7,7 +7,7 @@ LL | struct Foo; LL | f.bat(1.0); | ^^^ help: there is a method with a similar name: `bar` -error[E0599]: no method named `is_emtpy` found for type `std::string::String` in the current scope +error[E0599]: no method named `is_emtpy` found for struct `std::string::String` in the current scope --> $DIR/suggest-methods.rs:21:15 | LL | let _ = s.is_emtpy(); diff --git a/src/test/ui/suggestions/suggest-variants.rs b/src/test/ui/suggestions/suggest-variants.rs index d418834432e08..dd05d0f04abe3 100644 --- a/src/test/ui/suggestions/suggest-variants.rs +++ b/src/test/ui/suggestions/suggest-variants.rs @@ -9,9 +9,9 @@ struct S { } fn main() { - println!("My shape is {:?}", Shape::Squareee { size: 5}); //~ ERROR no variant `Squareee` - println!("My shape is {:?}", Shape::Circl { size: 5}); //~ ERROR no variant `Circl` - println!("My shape is {:?}", Shape::Rombus{ size: 5}); //~ ERROR no variant `Rombus` + println!("My shape is {:?}", Shape::Squareee { size: 5}); //~ ERROR no variant named `Squareee` + println!("My shape is {:?}", Shape::Circl { size: 5}); //~ ERROR no variant named `Circl` + println!("My shape is {:?}", Shape::Rombus{ size: 5}); //~ ERROR no variant named `Rombus` Shape::Squareee; //~ ERROR no variant Shape::Circl; //~ ERROR no variant Shape::Rombus; //~ ERROR no variant diff --git a/src/test/ui/suggestions/suggest-variants.stderr b/src/test/ui/suggestions/suggest-variants.stderr index b4338e2055431..9227baa3e1a5c 100644 --- a/src/test/ui/suggestions/suggest-variants.stderr +++ b/src/test/ui/suggestions/suggest-variants.stderr @@ -1,4 +1,4 @@ -error: no variant `Squareee` in enum `Shape` +error[E0599]: no variant named `Squareee` found for enum `Shape` --> $DIR/suggest-variants.rs:12:41 | LL | enum Shape { @@ -7,7 +7,7 @@ LL | enum Shape { LL | println!("My shape is {:?}", Shape::Squareee { size: 5}); | ^^^^^^^^ help: there is a variant with a similar name: `Square` -error: no variant `Circl` in enum `Shape` +error[E0599]: no variant named `Circl` found for enum `Shape` --> $DIR/suggest-variants.rs:13:41 | LL | enum Shape { @@ -16,7 +16,7 @@ LL | enum Shape { LL | println!("My shape is {:?}", Shape::Circl { size: 5}); | ^^^^^ help: there is a variant with a similar name: `Circle` -error: no variant `Rombus` in enum `Shape` +error[E0599]: no variant named `Rombus` found for enum `Shape` --> $DIR/suggest-variants.rs:14:41 | LL | enum Shape { @@ -25,7 +25,7 @@ LL | enum Shape { LL | println!("My shape is {:?}", Shape::Rombus{ size: 5}); | ^^^^^^ variant not found in `Shape` -error[E0599]: no variant or associated item named `Squareee` found for type `Shape` in the current scope +error[E0599]: no variant or associated item named `Squareee` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:15:12 | LL | enum Shape { @@ -37,7 +37,7 @@ LL | Shape::Squareee; | variant or associated item not found in `Shape` | help: there is a variant with a similar name: `Square` -error[E0599]: no variant or associated item named `Circl` found for type `Shape` in the current scope +error[E0599]: no variant or associated item named `Circl` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:16:12 | LL | enum Shape { @@ -49,7 +49,7 @@ LL | Shape::Circl; | variant or associated item not found in `Shape` | help: there is a variant with a similar name: `Circle` -error[E0599]: no variant or associated item named `Rombus` found for type `Shape` in the current scope +error[E0599]: no variant or associated item named `Rombus` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:17:12 | LL | enum Shape { diff --git a/src/test/ui/traits/trait-impl-1.rs b/src/test/ui/traits/trait-impl-1.rs index 43b822218354f..d22ac72d1cc4d 100644 --- a/src/test/ui/traits/trait-impl-1.rs +++ b/src/test/ui/traits/trait-impl-1.rs @@ -12,5 +12,5 @@ impl T for i32 {} fn main() { let x = &42i32; - x.foo(); //~ERROR: no method named `foo` found for type `&i32` in the current scope + x.foo(); //~ERROR: no method named `foo` found } diff --git a/src/test/ui/traits/trait-impl-1.stderr b/src/test/ui/traits/trait-impl-1.stderr index 0d61c3ed00d90..da0936e8eebdc 100644 --- a/src/test/ui/traits/trait-impl-1.stderr +++ b/src/test/ui/traits/trait-impl-1.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `foo` found for type `&i32` in the current scope +error[E0599]: no method named `foo` found for reference `&i32` in the current scope --> $DIR/trait-impl-1.rs:15:7 | LL | x.foo(); diff --git a/src/test/ui/traits/trait-item-privacy.rs b/src/test/ui/traits/trait-item-privacy.rs index d58bbef38c492..8507d8ef17e36 100644 --- a/src/test/ui/traits/trait-item-privacy.rs +++ b/src/test/ui/traits/trait-item-privacy.rs @@ -64,8 +64,8 @@ fn check_method() { // Methods, method call // a, b, c are resolved as trait items, their traits need to be in scope - S.a(); //~ ERROR no method named `a` found for type `S` in the current scope - S.b(); //~ ERROR no method named `b` found for type `S` in the current scope + S.a(); //~ ERROR no method named `a` found + S.b(); //~ ERROR no method named `b` found S.c(); // OK // a, b, c are resolved as inherent items, their traits don't need to be in scope let c = &S as &dyn C; @@ -76,9 +76,9 @@ fn check_method() { // Methods, UFCS // a, b, c are resolved as trait items, their traits need to be in scope S::a(&S); - //~^ ERROR no function or associated item named `a` found for type `S` + //~^ ERROR no function or associated item named `a` found S::b(&S); - //~^ ERROR no function or associated item named `b` found for type `S` + //~^ ERROR no function or associated item named `b` found S::c(&S); // OK // a, b, c are resolved as inherent items, their traits don't need to be in scope C::a(&S); //~ ERROR method `a` is private @@ -94,8 +94,8 @@ fn check_assoc_const() { // Associated constants // A, B, C are resolved as trait items, their traits need to be in scope - S::A; //~ ERROR no associated item named `A` found for type `S` in the current scope - S::B; //~ ERROR no associated item named `B` found for type `S` in the current scope + S::A; //~ ERROR no associated item named `A` found + S::B; //~ ERROR no associated item named `B` found S::C; // OK // A, B, C are resolved as inherent items, their traits don't need to be in scope C::A; //~ ERROR associated constant `A` is private diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 64a92c6b0b478..4df8845de279a 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `a` found for type `S` in the current scope +error[E0599]: no method named `a` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:67:7 | LL | struct S; @@ -11,7 +11,7 @@ LL | S.a(); = note: the following trait defines an item `a`, perhaps you need to implement it: candidate #1: `method::A` -error[E0599]: no method named `b` found for type `S` in the current scope +error[E0599]: no method named `b` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:68:7 | LL | struct S; @@ -39,7 +39,7 @@ error[E0624]: method `a` is private LL | c.a(); | ^ -error[E0599]: no function or associated item named `a` found for type `S` in the current scope +error[E0599]: no function or associated item named `a` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:78:8 | LL | struct S; @@ -52,7 +52,7 @@ LL | S::a(&S); = note: the following trait defines an item `a`, perhaps you need to implement it: candidate #1: `method::A` -error[E0599]: no function or associated item named `b` found for type `S` in the current scope +error[E0599]: no function or associated item named `b` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:80:8 | LL | struct S; @@ -73,7 +73,7 @@ error[E0624]: method `a` is private LL | C::a(&S); | ^^^^ -error[E0599]: no associated item named `A` found for type `S` in the current scope +error[E0599]: no associated item named `A` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:97:8 | LL | struct S; @@ -86,7 +86,7 @@ LL | S::A; = note: the following trait defines an item `A`, perhaps you need to implement it: candidate #1: `assoc_const::A` -error[E0599]: no associated item named `B` found for type `S` in the current scope +error[E0599]: no associated item named `B` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:98:8 | LL | struct S; diff --git a/src/test/ui/ufcs/ufcs-partially-resolved.rs b/src/test/ui/ufcs/ufcs-partially-resolved.rs index 82a593ff16cfa..66d4db3ebaf0a 100644 --- a/src/test/ui/ufcs/ufcs-partially-resolved.rs +++ b/src/test/ui/ufcs/ufcs-partially-resolved.rs @@ -35,7 +35,7 @@ fn main() { ::N::NN; //~ ERROR cannot find associated type `N` in `A` let _: ::Y::NN; //~ ERROR ambiguous associated type let _: ::Y::NN; //~ ERROR expected associated type, found variant `E::Y` - ::Y::NN; //~ ERROR no associated item named `NN` found for type `::Y` + ::Y::NN; //~ ERROR no associated item named `NN` found ::Y::NN; //~ ERROR expected associated type, found variant `E::Y` let _: ::NN; //~ ERROR cannot find associated type `NN` in `Tr::N` @@ -52,5 +52,5 @@ fn main() { let _: ::Z; //~ ERROR expected associated type, found method `Dr::Z` ::X; //~ ERROR expected method or associated constant, found associated type `Dr::X` let _: ::Z::N; //~ ERROR expected associated type, found method `Dr::Z` - ::X::N; //~ ERROR no associated item named `N` found for type `::X` + ::X::N; //~ ERROR no associated item named `N` found } diff --git a/src/test/ui/ufcs/ufcs-partially-resolved.stderr b/src/test/ui/ufcs/ufcs-partially-resolved.stderr index dbd41da6daf0b..60ebe8ee053a6 100644 --- a/src/test/ui/ufcs/ufcs-partially-resolved.stderr +++ b/src/test/ui/ufcs/ufcs-partially-resolved.stderr @@ -207,13 +207,13 @@ error[E0223]: ambiguous associated type LL | let _: ::Y::NN; | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::Y as Trait>::NN` -error[E0599]: no associated item named `NN` found for type `::Y` in the current scope +error[E0599]: no associated item named `NN` found for associated type `::Y` in the current scope --> $DIR/ufcs-partially-resolved.rs:38:20 | LL | ::Y::NN; | ^^ associated item not found in `::Y` -error[E0599]: no associated item named `N` found for type `::X` in the current scope +error[E0599]: no associated item named `N` found for associated type `::X` in the current scope --> $DIR/ufcs-partially-resolved.rs:55:20 | LL | ::X::N; diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr index 18276d5710cf8..2d058521e4ef6 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `call` found for type `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` in the current scope +error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` in the current scope --> $DIR/unboxed-closures-static-call-wrong-trait.rs:7:10 | LL | mut_.call((0, )); diff --git a/src/test/ui/underscore-imports/hygiene.stderr b/src/test/ui/underscore-imports/hygiene.stderr index 44cfc5cc5d22e..2983613786038 100644 --- a/src/test/ui/underscore-imports/hygiene.stderr +++ b/src/test/ui/underscore-imports/hygiene.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `deref` found for type `&()` in the current scope +error[E0599]: no method named `deref` found for reference `&()` in the current scope --> $DIR/hygiene.rs:38:11 | LL | (&()).deref(); @@ -10,7 +10,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use std::ops::Deref; | -error[E0599]: no method named `deref_mut` found for type `&mut ()` in the current scope +error[E0599]: no method named `deref_mut` found for mutable reference `&mut ()` in the current scope --> $DIR/hygiene.rs:39:15 | LL | (&mut ()).deref_mut(); diff --git a/src/test/ui/underscore-imports/shadow.stderr b/src/test/ui/underscore-imports/shadow.stderr index 102c17f6f5618..eb16fa9d5660b 100644 --- a/src/test/ui/underscore-imports/shadow.stderr +++ b/src/test/ui/underscore-imports/shadow.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `deref` found for type `&()` in the current scope +error[E0599]: no method named `deref` found for reference `&()` in the current scope --> $DIR/shadow.rs:19:11 | LL | x.deref(); diff --git a/src/test/ui/union/union-derive-clone.rs b/src/test/ui/union/union-derive-clone.rs index 60e280f53f52c..4a106cc940a18 100644 --- a/src/test/ui/union/union-derive-clone.rs +++ b/src/test/ui/union/union-derive-clone.rs @@ -34,5 +34,5 @@ struct CloneNoCopy; fn main() { let u = U5 { a: ManuallyDrop::new(CloneNoCopy) }; - let w = u.clone(); //~ ERROR no method named `clone` found for type `U5` + let w = u.clone(); //~ ERROR no method named `clone` found for union `U5` } diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 6893f9176f2db..0ef5753b5907d 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -6,7 +6,7 @@ LL | #[derive(Clone)] | = note: required by `std::clone::AssertParamIsCopy` -error[E0599]: no method named `clone` found for type `U5` in the current scope +error[E0599]: no method named `clone` found for union `U5` in the current scope --> $DIR/union-derive-clone.rs:37:15 | LL | union U5 { diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index cd46878c19be4..92cda6482c0d9 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `std::boxed::Box` in the current scope +error[E0599]: no method named `clone` found for struct `std::boxed::Box` in the current scope --> $DIR/unique-object-noncopyable.rs:24:16 | LL | let _z = y.clone(); diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr index 19ef2b21c2685..e5c3eaccbd3ec 100644 --- a/src/test/ui/unique-pinned-nocopy.stderr +++ b/src/test/ui/unique-pinned-nocopy.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `clone` found for type `std::boxed::Box` in the current scope +error[E0599]: no method named `clone` found for struct `std::boxed::Box` in the current scope --> $DIR/unique-pinned-nocopy.rs:12:16 | LL | let _j = i.clone(); diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr index b72d45ebdbfbc..e057a7842b2aa 100644 --- a/src/test/ui/unspecified-self-in-trait-ref.stderr +++ b/src/test/ui/unspecified-self-in-trait-ref.stderr @@ -1,22 +1,22 @@ -error[E0599]: no function or associated item named `lol` found for type `dyn Foo<_>` in the current scope +error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:10:18 | LL | let a = Foo::lol(); | ^^^ function or associated item not found in `dyn Foo<_>` -error[E0599]: no function or associated item named `lol` found for type `dyn Foo<_>` in the current scope +error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:12:23 | LL | let b = Foo::<_>::lol(); | ^^^ function or associated item not found in `dyn Foo<_>` -error[E0599]: no function or associated item named `lol` found for type `dyn Bar<_, _>` in the current scope +error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:14:18 | LL | let c = Bar::lol(); | ^^^ function or associated item not found in `dyn Bar<_, _>` -error[E0599]: no function or associated item named `lol` found for type `dyn Bar` in the current scope +error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:16:30 | LL | let d = Bar::::lol(); From 9c0000cacac904a9b04c64ca349f54169b98f60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 15 Nov 2019 18:53:17 -0800 Subject: [PATCH 0063/1253] Point at opaque and closure type definitions in type errors --- src/librustc/infer/error_reporting/mod.rs | 97 ++++++++++++++++++- src/librustc_typeck/check/mod.rs | 3 +- .../dont-suggest-missing-await.stderr | 3 + .../suggest-missing-await-closure.stderr | 3 + .../async-await/suggest-missing-await.stderr | 3 + .../ui/closures/closure-reform-bad.stderr | 2 + src/test/ui/impl-trait/equality2.stderr | 12 +++ src/test/ui/issues/issue-24036.stderr | 2 + .../fn-or-tuple-struct-without-args.stderr | 2 +- .../ui/suggestions/opaque-type-error.stderr | 3 + ..._type_does_not_live_long_enough.nll.stderr | 3 + ...eric_type_does_not_live_long_enough.stderr | 3 + .../never_reveal_concrete_type.stderr | 3 + ...o_revealing_outside_defining_module.stderr | 6 ++ 14 files changed, 137 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 92292b3d35f24..e134a6c17cc3d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -68,9 +68,11 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::Node; -use errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString}; +use errors::{ + pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString, +}; use rustc_error_codes::*; -use rustc_span::{Pos, Span}; +use rustc_span::{DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::{cmp, fmt}; @@ -1289,6 +1291,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { mut values: Option>, terr: &TypeError<'tcx>, ) { + let span = cause.span(self.tcx); + // For some types of errors, expected-found does not make // sense, so just ignore the values we were given. match terr { @@ -1298,6 +1302,85 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => {} } + struct OpaqueTypesVisitor<'tcx> { + types: FxHashMap<&'static str, FxHashSet>, + expected: FxHashMap<&'static str, FxHashSet>, + found: FxHashMap<&'static str, FxHashSet>, + ignore_span: Span, + tcx: TyCtxt<'tcx>, + } + + impl<'tcx> OpaqueTypesVisitor<'tcx> { + fn visit_expected_found( + tcx: TyCtxt<'tcx>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ignore_span: Span, + ) -> Self { + let mut types_visitor = OpaqueTypesVisitor { + types: Default::default(), + expected: Default::default(), + found: Default::default(), + ignore_span, + tcx, + }; + expected.visit_with(&mut types_visitor); + std::mem::swap(&mut types_visitor.expected, &mut types_visitor.types); + found.visit_with(&mut types_visitor); + std::mem::swap(&mut types_visitor.found, &mut types_visitor.types); + types_visitor + } + + fn report(&self, err: &mut DiagnosticBuilder<'_>) { + for (target, types) in &[("expected", &self.expected), ("found", &self.found)] { + for (key, values) in types.iter() { + let count = values.len(); + for sp in values { + err.span_label( + *sp, + format!( + "{}this is {}the {} {}{}", + if sp.is_desugaring(DesugaringKind::Async) { + "in the desugared `async fn`, " + } else { + "" + }, + if count > 1 { "one of" } else { "" }, + target, + key, + pluralize!(count), + ), + ); + } + } + } + } + } + + impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + let kind = match t.kind { + ty::Closure(..) => "closure", + ty::Opaque(..) => "opaque type", + _ => "", + }; + match t.kind { + ty::Closure(def_id, _) | ty::Opaque(def_id, _) => { + let span = self.tcx.def_span(def_id); + debug!("note_type_err visit_ty {:?}", span.macro_backtrace()); + if !self.ignore_span.overlaps(span) + && !self.expected.values().any(|exp| exp.iter().any(|sp| *sp == span)) + { + let entry = self.types.entry(kind).or_default(); + entry.insert(span); + } + } + _ => {} + } + t.super_visit_with(self) + } + } + debug!("note_type_err(diag={:?})", diag); let (expected_found, exp_found, is_simple_error) = match values { None => (None, None, false), @@ -1306,6 +1389,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ValuePairs::Types(exp_found) => { let is_simple_err = exp_found.expected.is_simple_text() && exp_found.found.is_simple_text(); + OpaqueTypesVisitor::visit_expected_found( + self.tcx, + exp_found.expected, + exp_found.found, + span, + ) + .report(diag); (is_simple_err, Some(exp_found)) } @@ -1323,8 +1413,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } }; - let span = cause.span(self.tcx); - // Ignore msg for object safe coercion // since E0038 message will be printed match terr { @@ -1336,7 +1424,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } }; - if let Some((expected, found)) = expected_found { let expected_label = exp_found.map_or("type".into(), |ef| ef.expected.prefix_string()); let found_label = exp_found.map_or("type".into(), |ef| ef.found.prefix_string()); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e6fbae09ba1a0..00ad00cf1b24c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4743,14 +4743,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .join(", "); } Some(Node::Expr(hir::Expr { - kind: ExprKind::Closure(_, _, body_id, closure_span, _), + kind: ExprKind::Closure(_, _, body_id, _, _), span: full_closure_span, .. })) => { if *full_closure_span == expr.span { return false; } - err.span_label(*closure_span, "closure defined here"); msg = "call this closure"; let body = hir.body(*body_id); sugg_call = body diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 239f801c39d4e..5bf10e0089207 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | +LL | async fn make_u32() -> u32 { + | --- in the desugared `async fn`, this is the found opaque type +... LL | take_u32(x) | ^ expected `u32`, found opaque type | diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index 1efc20082a08a..43366e6bbbfab 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | +LL | async fn make_u32() -> u32 { + | --- in the desugared `async fn`, this is the found opaque type +... LL | take_u32(x) | ^ | | diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 7ab024434b2bf..c7fcbdd8138c1 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:13:14 | +LL | async fn make_u32() -> u32 { + | --- in the desugared `async fn`, this is the found opaque type +... LL | take_u32(x) | ^ | | diff --git a/src/test/ui/closures/closure-reform-bad.stderr b/src/test/ui/closures/closure-reform-bad.stderr index 63236cf542464..16727b58e1ff6 100644 --- a/src/test/ui/closures/closure-reform-bad.stderr +++ b/src/test/ui/closures/closure-reform-bad.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/closure-reform-bad.rs:11:15 | +LL | let f = |s: &str| println!("{}{}", s, string); + | ------------------------------------- this is the found closure LL | call_bare(f) | ^ expected fn pointer, found closure | diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 312976b72d20e..4e1880f31dc2a 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/equality2.rs:25:18 | +LL | fn hide(x: T) -> impl Foo { + | -------- this is the found opaque type +... LL | let _: u32 = hide(0_u32); | --- ^^^^^^^^^^^ expected `u32`, found opaque type | | @@ -12,6 +15,9 @@ LL | let _: u32 = hide(0_u32); error[E0308]: mismatched types --> $DIR/equality2.rs:31:18 | +LL | fn hide(x: T) -> impl Foo { + | -------- this is the found opaque type +... LL | let _: i32 = Leak::leak(hide(0_i32)); | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type | | @@ -25,6 +31,9 @@ LL | let _: i32 = Leak::leak(hide(0_i32)); error[E0308]: mismatched types --> $DIR/equality2.rs:38:10 | +LL | fn hide(x: T) -> impl Foo { + | -------- this is the expected opaque type +... LL | x = (x.1, | ^^^ expected `u32`, found `i32` | @@ -34,6 +43,9 @@ LL | x = (x.1, error[E0308]: mismatched types --> $DIR/equality2.rs:41:10 | +LL | fn hide(x: T) -> impl Foo { + | -------- this is the expected opaque type +... LL | x.0); | ^^^ expected `i32`, found `u32` | diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index b0e729a59eb22..670bf57067b56 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-24036.rs:3:9 | +LL | let mut x = |c| c + 1; + | --------- this is the expected closure LL | x = |c| c + 1; | ^^^^^^^^^ expected closure, found a different closure | diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 2f0a457a79594..5b18c239b6ee3 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -236,7 +236,7 @@ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:46:20 | LL | let closure = || 42; - | -- closure defined here + | ----- this is the found closure LL | let _: usize = closure; | ----- ^^^^^^^ | | | diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr index 1465b9e49ef1a..3a7ea2bcdd2a4 100644 --- a/src/test/ui/suggestions/opaque-type-error.stderr +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -1,6 +1,9 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | +LL | fn thing_two() -> impl Future> { + | ------------------------------------ this is the found opaque type +... LL | / if true { LL | | thing_one() | | ----------- expected because of this diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index dc41cbc5fe3f8..182a3c7e81e60 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -11,6 +11,9 @@ LL | let z: i32 = x; | --- ^ expected `i32`, found opaque type | | | expected due to this +... +LL | type WrongGeneric = impl 'static; + | ------------------------------------ this is the found opaque type | = note: expected type `i32` found opaque type `WrongGeneric::<&{integer}>` diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index 24d23de797690..b061ec3fff8f4 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -11,6 +11,9 @@ LL | let z: i32 = x; | --- ^ expected `i32`, found opaque type | | | expected due to this +... +LL | type WrongGeneric = impl 'static; + | ------------------------------------ this is the found opaque type | = note: expected type `i32` found opaque type `WrongGeneric::<&{integer}>` diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr index 07962e36da1e6..415ac4bbdcba7 100644 --- a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/never_reveal_concrete_type.rs:13:27 | +LL | type NoReveal = impl std::fmt::Debug; + | ------------------------------------- this is the found opaque type +... LL | let _: &'static str = x; | ------------ ^ expected `&str`, found opaque type | | diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index a2081424ab497..3e67dc90dcb5c 100644 --- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:15:19 | +LL | pub type Boo = impl ::std::fmt::Debug; + | -------------------------------------- this is the found opaque type +... LL | let _: &str = bomp(); | ---- ^^^^^^ expected `&str`, found opaque type | | @@ -12,6 +15,9 @@ LL | let _: &str = bomp(); error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 | +LL | pub type Boo = impl ::std::fmt::Debug; + | -------------------------------------- this is the expected opaque type +... LL | fn bomp() -> boo::Boo { | -------- expected `Boo` because of return type LL | "" From c55615155d161c8abb307db0019ab58545cd246b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 15 Dec 2019 14:05:08 -0800 Subject: [PATCH 0064/1253] review comments --- src/librustc/infer/error_reporting/mod.rs | 40 +++++++++++-------- .../dont-suggest-missing-await.stderr | 2 +- .../suggest-missing-await-closure.stderr | 2 +- .../async-await/suggest-missing-await.stderr | 5 ++- .../ui/closures/closure-reform-bad.stderr | 2 +- .../extern/extern-types-distinct-types.stderr | 5 +++ src/test/ui/impl-trait/equality2.stderr | 14 +++++-- src/test/ui/issues/issue-24036.stderr | 2 +- .../fn-or-tuple-struct-without-args.stderr | 2 +- .../ui/suggestions/opaque-type-error.stderr | 2 +- ..._type_does_not_live_long_enough.nll.stderr | 2 +- ...eric_type_does_not_live_long_enough.stderr | 2 +- .../never_reveal_concrete_type.stderr | 2 +- ...o_revealing_outside_defining_module.stderr | 4 +- 14 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index e134a6c17cc3d..d0243dad700b6 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1339,16 +1339,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label( *sp, format!( - "{}this is {}the {} {}{}", + "{}the {} {}{}{}", + if count > 1 { "one of " } else { "" }, + target, + key, + pluralize!(count), if sp.is_desugaring(DesugaringKind::Async) { - "in the desugared `async fn`, " + " in the `Output` of this `async fn`" } else { "" }, - if count > 1 { "one of" } else { "" }, - target, - key, - pluralize!(count), ), ); } @@ -1364,18 +1364,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Opaque(..) => "opaque type", _ => "", }; - match t.kind { - ty::Closure(def_id, _) | ty::Opaque(def_id, _) => { - let span = self.tcx.def_span(def_id); - debug!("note_type_err visit_ty {:?}", span.macro_backtrace()); - if !self.ignore_span.overlaps(span) - && !self.expected.values().any(|exp| exp.iter().any(|sp| *sp == span)) - { - let entry = self.types.entry(kind).or_default(); - entry.insert(span); - } + if let ty::Closure(def_id, _) | ty::Opaque(def_id, _) = t.kind { + let span = self.tcx.def_span(def_id); + // Avoid cluttering the output when the "found" and error span overlap: + // + // error[E0308]: mismatched types + // --> $DIR/issue-20862.rs:2:5 + // | + // LL | |y| x + y + // | ^^^^^^^^^ + // | | + // | the found closure + // | expected `()`, found closure + // | + // = note: expected unit type `()` + // found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]` + if !self.ignore_span.overlaps(span) { + self.types.entry(kind).or_default().insert(span); } - _ => {} } t.super_visit_with(self) } diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 5bf10e0089207..5c9b1d2c4d71c 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | async fn make_u32() -> u32 { - | --- in the desugared `async fn`, this is the found opaque type + | --- the found opaque type in the `Output` of this `async fn` ... LL | take_u32(x) | ^ expected `u32`, found opaque type diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index 43366e6bbbfab..5926c8351ff3d 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | LL | async fn make_u32() -> u32 { - | --- in the desugared `async fn`, this is the found opaque type + | --- the found opaque type in the `Output` of this `async fn` ... LL | take_u32(x) | ^ diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index c7fcbdd8138c1..c0dc32b83fb0b 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:13:14 | LL | async fn make_u32() -> u32 { - | --- in the desugared `async fn`, this is the found opaque type + | --- the found opaque type in the `Output` of this `async fn` ... LL | take_u32(x) | ^ @@ -16,6 +16,9 @@ LL | take_u32(x) error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:23:5 | +LL | async fn dummy() {} + | - the found opaque type in the `Output` of this `async fn` +... LL | dummy() | ^^^^^^^ expected `()`, found opaque type | diff --git a/src/test/ui/closures/closure-reform-bad.stderr b/src/test/ui/closures/closure-reform-bad.stderr index 16727b58e1ff6..3c4ae450764da 100644 --- a/src/test/ui/closures/closure-reform-bad.stderr +++ b/src/test/ui/closures/closure-reform-bad.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/closure-reform-bad.rs:11:15 | LL | let f = |s: &str| println!("{}{}", s, string); - | ------------------------------------- this is the found closure + | ------------------------------------- the found closure LL | call_bare(f) | ^ expected fn pointer, found closure | diff --git a/src/test/ui/extern/extern-types-distinct-types.stderr b/src/test/ui/extern/extern-types-distinct-types.stderr index 2e258d687d385..32b45ee10ad6f 100644 --- a/src/test/ui/extern/extern-types-distinct-types.stderr +++ b/src/test/ui/extern/extern-types-distinct-types.stderr @@ -1,6 +1,11 @@ error[E0308]: mismatched types --> $DIR/extern-types-distinct-types.rs:9:5 | +LL | type A; + | ------- the found foreign type +LL | type B; + | ------- the expected foreign type +... LL | r | ^ expected extern type `B`, found extern type `A` | diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 4e1880f31dc2a..b882514f61609 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/equality2.rs:25:18 | LL | fn hide(x: T) -> impl Foo { - | -------- this is the found opaque type + | -------- the found opaque type ... LL | let _: u32 = hide(0_u32); | --- ^^^^^^^^^^^ expected `u32`, found opaque type @@ -16,7 +16,7 @@ error[E0308]: mismatched types --> $DIR/equality2.rs:31:18 | LL | fn hide(x: T) -> impl Foo { - | -------- this is the found opaque type + | -------- the found opaque type ... LL | let _: i32 = Leak::leak(hide(0_i32)); | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type @@ -32,7 +32,10 @@ error[E0308]: mismatched types --> $DIR/equality2.rs:38:10 | LL | fn hide(x: T) -> impl Foo { - | -------- this is the expected opaque type + | -------- + | | + | the expected opaque type + | the found opaque type ... LL | x = (x.1, | ^^^ expected `u32`, found `i32` @@ -44,7 +47,10 @@ error[E0308]: mismatched types --> $DIR/equality2.rs:41:10 | LL | fn hide(x: T) -> impl Foo { - | -------- this is the expected opaque type + | -------- + | | + | the expected opaque type + | the found opaque type ... LL | x.0); | ^^^ expected `i32`, found `u32` diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index 670bf57067b56..036c05fc848cf 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-24036.rs:3:9 | LL | let mut x = |c| c + 1; - | --------- this is the expected closure + | --------- the expected closure LL | x = |c| c + 1; | ^^^^^^^^^ expected closure, found a different closure | diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 5b18c239b6ee3..232e54b5d37b2 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -236,7 +236,7 @@ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:46:20 | LL | let closure = || 42; - | ----- this is the found closure + | ----- the found closure LL | let _: usize = closure; | ----- ^^^^^^^ | | | diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr index 3a7ea2bcdd2a4..167d61bdf7c70 100644 --- a/src/test/ui/suggestions/opaque-type-error.stderr +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -2,7 +2,7 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | LL | fn thing_two() -> impl Future> { - | ------------------------------------ this is the found opaque type + | ------------------------------------ the found opaque type ... LL | / if true { LL | | thing_one() diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index 182a3c7e81e60..9549074d4bf78 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -13,7 +13,7 @@ LL | let z: i32 = x; | expected due to this ... LL | type WrongGeneric = impl 'static; - | ------------------------------------ this is the found opaque type + | ------------------------------------ the found opaque type | = note: expected type `i32` found opaque type `WrongGeneric::<&{integer}>` diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index b061ec3fff8f4..5a7f9d74eba5b 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -13,7 +13,7 @@ LL | let z: i32 = x; | expected due to this ... LL | type WrongGeneric = impl 'static; - | ------------------------------------ this is the found opaque type + | ------------------------------------ the found opaque type | = note: expected type `i32` found opaque type `WrongGeneric::<&{integer}>` diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr index 415ac4bbdcba7..70c99c944d654 100644 --- a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/never_reveal_concrete_type.rs:13:27 | LL | type NoReveal = impl std::fmt::Debug; - | ------------------------------------- this is the found opaque type + | ------------------------------------- the found opaque type ... LL | let _: &'static str = x; | ------------ ^ expected `&str`, found opaque type diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index 3e67dc90dcb5c..375c0bc7fe2ed 100644 --- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:15:19 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- this is the found opaque type + | -------------------------------------- the found opaque type ... LL | let _: &str = bomp(); | ---- ^^^^^^ expected `&str`, found opaque type @@ -16,7 +16,7 @@ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- this is the expected opaque type + | -------------------------------------- the expected opaque type ... LL | fn bomp() -> boo::Boo { | -------- expected `Boo` because of return type From 0dcdbaec0b49a149316719b32241d8975bd192c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 15 Dec 2019 22:20:30 -0800 Subject: [PATCH 0065/1253] Point at the def span of trait refs E0277 --- src/librustc/infer/error_reporting/mod.rs | 9 ++++- src/librustc/traits/error_reporting.rs | 34 ++++++++++++++++--- .../ui/async-await/issue-64130-3-other.stderr | 3 ++ src/test/ui/impl-trait/auto-trait-leak.stderr | 3 ++ .../ui/impl-trait/auto-trait-leak2.stderr | 6 ++++ .../ui/kindck/kindck-nonsendable-1.stderr | 4 ++- src/test/ui/no-send-res-ports.stderr | 15 +++++--- src/test/ui/not-clone-closure.stderr | 10 ++++-- 8 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index d0243dad700b6..d736d45a5a485 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -71,6 +71,7 @@ use rustc_hir::Node; use errors::{ pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString, }; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_error_codes::*; use rustc_span::{DesugaringKind, Pos, Span}; use rustc_target::spec::abi; @@ -1362,9 +1363,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let kind = match t.kind { ty::Closure(..) => "closure", ty::Opaque(..) => "opaque type", + ty::Generator(..) => "generator", + ty::Foreign(..) => "foreign type", _ => "", }; - if let ty::Closure(def_id, _) | ty::Opaque(def_id, _) = t.kind { + if let ty::Closure(def_id, _) + | ty::Opaque(def_id, _) + | ty::Generator(def_id, ..) + | ty::Foreign(def_id) = t.kind + { let span = self.tcx.def_span(def_id); // Avoid cluttering the output when the "found" and error span overlap: // diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 00251d55706d7..8c2cc412a480b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -446,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { flags.push((sym::from_method, Some(method.to_string()))); } } - if let Some(t) = self.get_parent_trait_ref(&obligation.cause.code) { + if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { flags.push((sym::parent_trait, Some(t))); } @@ -665,13 +665,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } /// Gets the parent trait chain start - fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option { + fn get_parent_trait_ref( + &self, + code: &ObligationCauseCode<'tcx>, + ) -> Option<(String, Option)> { match code { &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); match self.get_parent_trait_ref(&data.parent_code) { Some(t) => Some(t), - None => Some(parent_trait_ref.skip_binder().self_ty().to_string()), + None => { + let ty = parent_trait_ref.skip_binder().self_ty(); + let span = if let ty::Closure(def_id, _) + | ty::Opaque(def_id, _) + | ty::Generator(def_id, ..) + | ty::Foreign(def_id) = ty.kind + { + Some(self.tcx.def_span(def_id)) + } else { + None + }; + Some((ty.to_string(), span)) + } } } _ => None, @@ -719,9 +734,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); - let (post_message, pre_message) = self + let (post_message, pre_message, type_def) = self .get_parent_trait_ref(&obligation.cause.code) - .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t))) + .map(|(t, s)| { + ( + format!(" in `{}`", t), + format!("within `{}`, ", t), + s.map(|s| (format!("within this `{}`", t), s)), + ) + }) .unwrap_or_default(); let OnUnimplementedNote { message, label, note, enclosing_scope } = @@ -795,6 +816,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { err.span_label(span, explanation); } + if let Some((msg, span)) = type_def { + err.span_label(span, &msg); + } if let Some(ref s) = note { // If it has a custom `#[rustc_on_unimplemented]` note, let's display it err.note(s.as_str()); diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr index 155c5cc8ea137..d6828172928dd 100644 --- a/src/test/ui/async-await/issue-64130-3-other.stderr +++ b/src/test/ui/async-await/issue-64130-3-other.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl std::future:: | LL | fn is_qux(t: T) { } | ------ --- required by this bound in `is_qux` +LL | +LL | async fn bar() { + | - within this `impl std::future::Future` ... LL | is_qux(bar()); | ^^^^^^ within `impl std::future::Future`, the trait `Qux` is not implemented for `Foo` diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index d11941fee1824..20815e80acb89 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -77,6 +77,9 @@ LL | fn send(_: T) {} ... LL | send(cycle2().clone()); | ^^^^ `std::rc::Rc` cannot be sent between threads safely +... +LL | fn cycle2() -> impl Clone { + | ---------- within this `impl std::clone::Clone` | = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc` = note: required because it appears within the type `impl std::clone::Clone` diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr index d163e1dff7ac9..a93b3dbc71b60 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr @@ -1,6 +1,9 @@ error[E0277]: `std::rc::Rc>` cannot be sent between threads safely --> $DIR/auto-trait-leak2.rs:13:5 | +LL | fn before() -> impl Fn(i32) { + | ------------ within this `impl std::ops::Fn<(i32,)>` +... LL | fn send(_: T) {} | ---- ---- required by this bound in `send` ... @@ -19,6 +22,9 @@ LL | fn send(_: T) {} ... LL | send(after()); | ^^^^ `std::rc::Rc>` cannot be sent between threads safely +... +LL | fn after() -> impl Fn(i32) { + | ------------ within this `impl std::ops::Fn<(i32,)>` | = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22 p:std::rc::Rc>]` diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr index 40b67f8fe8cd7..39640e373991f 100644 --- a/src/test/ui/kindck/kindck-nonsendable-1.stderr +++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr @@ -5,7 +5,9 @@ LL | fn bar(_: F) { } | --- ---- required by this bound in `bar` ... LL | bar(move|| foo(x)); - | ^^^ `std::rc::Rc` cannot be sent between threads safely + | ^^^ ------------- within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc]` + | | + | `std::rc::Rc` cannot be sent between threads safely | = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc` = note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc]` diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr index 8cb690a35c874..65946ee8a20cf 100644 --- a/src/test/ui/no-send-res-ports.stderr +++ b/src/test/ui/no-send-res-ports.stderr @@ -1,13 +1,20 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely --> $DIR/no-send-res-ports.rs:29:5 | -LL | thread::spawn(move|| { - | ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely +LL | thread::spawn(move|| { + | _____^^^^^^^^^^^^^_- + | | | + | | `std::rc::Rc<()>` cannot be sent between threads safely +LL | | +LL | | let y = x; +LL | | println!("{:?}", y); +LL | | }); + | |_____- within this `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]` | ::: $SRC_DIR/libstd/thread/mod.rs:LL:COL | -LL | F: Send + 'static, - | ---- required by this bound in `std::thread::spawn` +LL | F: Send + 'static, + | ---- required by this bound in `std::thread::spawn` | = help: within `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` = note: required because it appears within the type `Port<()>` diff --git a/src/test/ui/not-clone-closure.stderr b/src/test/ui/not-clone-closure.stderr index b66391b83b8db..20c7f81cf5ef5 100644 --- a/src/test/ui/not-clone-closure.stderr +++ b/src/test/ui/not-clone-closure.stderr @@ -1,8 +1,14 @@ error[E0277]: the trait bound `S: std::clone::Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]` --> $DIR/not-clone-closure.rs:11:23 | -LL | let hello = hello.clone(); - | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`, the trait `std::clone::Clone` is not implemented for `S` +LL | let hello = move || { + | _________________- +LL | | println!("Hello {}", a.0); +LL | | }; + | |_____- within this `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]` +LL | +LL | let hello = hello.clone(); + | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`, the trait `std::clone::Clone` is not implemented for `S` | = note: required because it appears within the type `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]` From 542be6fb6c3e3e3eae5aae04ac772aa0ab53b9a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 15 Dec 2019 22:48:45 -0800 Subject: [PATCH 0066/1253] review comment: wording --- src/librustc/infer/error_reporting/mod.rs | 14 ++++++++------ .../async-await/dont-suggest-missing-await.stderr | 2 +- .../suggest-missing-await-closure.stderr | 2 +- .../ui/async-await/suggest-missing-await.stderr | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index d736d45a5a485..8a444b8d45263 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1340,16 +1340,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label( *sp, format!( - "{}the {} {}{}{}", - if count > 1 { "one of " } else { "" }, - target, - key, - pluralize!(count), + "{}{}{} {}{}", if sp.is_desugaring(DesugaringKind::Async) { - " in the `Output` of this `async fn`" + "the `Output` of this `async fn`'s " + } else if count == 1 { + "the " } else { "" }, + if count > 1 { "one of the " } else { "" }, + target, + key, + pluralize!(count), ), ); } diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 5c9b1d2c4d71c..dc3a4752fb1f7 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | async fn make_u32() -> u32 { - | --- the found opaque type in the `Output` of this `async fn` + | --- the `Output` of this `async fn`'s found opaque type ... LL | take_u32(x) | ^ expected `u32`, found opaque type diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index 5926c8351ff3d..2703cec581ddf 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | LL | async fn make_u32() -> u32 { - | --- the found opaque type in the `Output` of this `async fn` + | --- the `Output` of this `async fn`'s found opaque type ... LL | take_u32(x) | ^ diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index c0dc32b83fb0b..6ac05a87aae80 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:13:14 | LL | async fn make_u32() -> u32 { - | --- the found opaque type in the `Output` of this `async fn` + | --- the `Output` of this `async fn`'s found opaque type ... LL | take_u32(x) | ^ @@ -17,7 +17,7 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:23:5 | LL | async fn dummy() {} - | - the found opaque type in the `Output` of this `async fn` + | - the `Output` of this `async fn`'s found opaque type ... LL | dummy() | ^^^^^^^ expected `()`, found opaque type From b522ba02374169372a80d867894818c92e8c534a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Jan 2020 17:31:37 -0800 Subject: [PATCH 0067/1253] review comments --- src/librustc/infer/error_reporting/mod.rs | 50 +++++++++++++++-------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 8a444b8d45263..bc75e0a75f09d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1303,10 +1303,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => {} } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + enum TyKind { + Closure, + Opaque, + Generator, + Foreign, + } + + impl TyKind { + fn descr(&self) -> &'static str { + match self { + Self::Closure => "closure", + Self::Opaque => "opaque type", + Self::Generator => "generator", + Self::Foreign => "foreign type", + } + } + + fn from_ty(ty: Ty<'_>) -> Option<(Self, DefId)> { + match ty.kind { + ty::Closure(def_id, _) => Some((Self::Closure, def_id)), + ty::Opaque(def_id, _) => Some((Self::Opaque, def_id)), + ty::Generator(def_id, ..) => Some((Self::Generator, def_id)), + ty::Foreign(def_id) => Some((Self::Foreign, def_id)), + _ => None, + } + } + } + struct OpaqueTypesVisitor<'tcx> { - types: FxHashMap<&'static str, FxHashSet>, - expected: FxHashMap<&'static str, FxHashSet>, - found: FxHashMap<&'static str, FxHashSet>, + types: FxHashMap>, + expected: FxHashMap>, + found: FxHashMap>, ignore_span: Span, tcx: TyCtxt<'tcx>, } @@ -1350,7 +1379,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }, if count > 1 { "one of the " } else { "" }, target, - key, + key.descr(), pluralize!(count), ), ); @@ -1362,18 +1391,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - let kind = match t.kind { - ty::Closure(..) => "closure", - ty::Opaque(..) => "opaque type", - ty::Generator(..) => "generator", - ty::Foreign(..) => "foreign type", - _ => "", - }; - if let ty::Closure(def_id, _) - | ty::Opaque(def_id, _) - | ty::Generator(def_id, ..) - | ty::Foreign(def_id) = t.kind - { + if let Some((kind, def_id)) = TyKind::from_ty(t) { let span = self.tcx.def_span(def_id); // Avoid cluttering the output when the "found" and error span overlap: // From ffcdbad263fc2522696b3376627aca503fe0fe8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2020 09:09:43 -0800 Subject: [PATCH 0068/1253] review comments --- src/librustc/infer/error_reporting/mod.rs | 66 ++++++++++++++--------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index bc75e0a75f09d..b6d6ca0dcef72 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1303,15 +1303,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => {} } + /// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks + /// extra information about each type, but we only care about the category. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - enum TyKind { + enum TyCategory { Closure, Opaque, Generator, Foreign, } - impl TyKind { + impl TyCategory { fn descr(&self) -> &'static str { match self { Self::Closure => "closure", @@ -1334,8 +1336,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { struct OpaqueTypesVisitor<'tcx> { types: FxHashMap>, - expected: FxHashMap>, - found: FxHashMap>, + expected: FxHashMap>, + found: FxHashMap>, ignore_span: Span, tcx: TyCtxt<'tcx>, } @@ -1354,6 +1356,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ignore_span, tcx, }; + // The visitor puts all the relevant encountered types in `self.types`, but in + // here we want to visit two separate types with no relation to each other, so we + // move the results from `types` to `expected` or `found` as appropriate. expected.visit_with(&mut types_visitor); std::mem::swap(&mut types_visitor.expected, &mut types_visitor.types); found.visit_with(&mut types_visitor); @@ -1362,28 +1367,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } fn report(&self, err: &mut DiagnosticBuilder<'_>) { - for (target, types) in &[("expected", &self.expected), ("found", &self.found)] { - for (key, values) in types.iter() { - let count = values.len(); - for sp in values { - err.span_label( - *sp, - format!( - "{}{}{} {}{}", - if sp.is_desugaring(DesugaringKind::Async) { - "the `Output` of this `async fn`'s " - } else if count == 1 { - "the " - } else { - "" - }, - if count > 1 { "one of the " } else { "" }, - target, - key.descr(), - pluralize!(count), - ), - ); - } + self.add_labels_for_types(err, "expected", &self.expected); + self.add_labels_for_types(err, "found", &self.found); + } + + fn add_labels_for_types( + &self, + err: &mut DiagnosticBuilder<'_>, + target: &str, + types: &FxHashMap>, + ) { + for (key, values) in types.iter() { + let count = values.len(); + let kind = key.descr(); + for sp in values { + err.span_label( + *sp, + format!( + "{}{}{} {}{}", + if sp.is_desugaring(DesugaringKind::Async) { + "the `Output` of this `async fn`'s " + } else if count == 1 { + "the " + } else { + "" + }, + if count > 1 { "one of the " } else { "" }, + target, + key, + pluralize!(count), + ), + ); } } } From 705e0874de4787dd65eb8484fd67ad635e136c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2020 09:26:47 -0800 Subject: [PATCH 0069/1253] reduce code duplication --- src/librustc/infer/error_reporting/mod.rs | 70 +++++++++++------------ src/librustc/traits/error_reporting.rs | 13 +---- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index b6d6ca0dcef72..27523b1e689e2 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1303,39 +1303,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => {} } - /// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks - /// extra information about each type, but we only care about the category. - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - enum TyCategory { - Closure, - Opaque, - Generator, - Foreign, - } - - impl TyCategory { - fn descr(&self) -> &'static str { - match self { - Self::Closure => "closure", - Self::Opaque => "opaque type", - Self::Generator => "generator", - Self::Foreign => "foreign type", - } - } - - fn from_ty(ty: Ty<'_>) -> Option<(Self, DefId)> { - match ty.kind { - ty::Closure(def_id, _) => Some((Self::Closure, def_id)), - ty::Opaque(def_id, _) => Some((Self::Opaque, def_id)), - ty::Generator(def_id, ..) => Some((Self::Generator, def_id)), - ty::Foreign(def_id) => Some((Self::Foreign, def_id)), - _ => None, - } - } - } - struct OpaqueTypesVisitor<'tcx> { - types: FxHashMap>, + types: FxHashMap>, expected: FxHashMap>, found: FxHashMap>, ignore_span: Span, @@ -1375,7 +1344,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, err: &mut DiagnosticBuilder<'_>, target: &str, - types: &FxHashMap>, + types: &FxHashMap>, ) { for (key, values) in types.iter() { let count = values.len(); @@ -1394,7 +1363,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }, if count > 1 { "one of the " } else { "" }, target, - key, + kind, pluralize!(count), ), ); @@ -1405,7 +1374,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - if let Some((kind, def_id)) = TyKind::from_ty(t) { + if let Some((kind, def_id)) = TyCategory::from_ty(t) { let span = self.tcx.def_span(def_id); // Avoid cluttering the output when the "found" and error span overlap: // @@ -2067,3 +2036,34 @@ impl<'tcx> ObligationCause<'tcx> { } } } + +/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks +/// extra information about each type, but we only care about the category. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +crate enum TyCategory { + Closure, + Opaque, + Generator, + Foreign, +} + +impl TyCategory { + fn descr(&self) -> &'static str { + match self { + Self::Closure => "closure", + Self::Opaque => "opaque type", + Self::Generator => "generator", + Self::Foreign => "foreign type", + } + } + + pub fn from_ty(ty: Ty<'_>) -> Option<(Self, DefId)> { + match ty.kind { + ty::Closure(def_id, _) => Some((Self::Closure, def_id)), + ty::Opaque(def_id, _) => Some((Self::Opaque, def_id)), + ty::Generator(def_id, ..) => Some((Self::Generator, def_id)), + ty::Foreign(def_id) => Some((Self::Foreign, def_id)), + _ => None, + } + } +} diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8c2cc412a480b..a42ddbbbcc6a3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -6,7 +6,7 @@ use super::{ TraitNotObjectSafe, }; -use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode; +use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{self, InferCtxt}; use crate::mir::interpret::ErrorHandled; @@ -676,15 +676,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Some(t) => Some(t), None => { let ty = parent_trait_ref.skip_binder().self_ty(); - let span = if let ty::Closure(def_id, _) - | ty::Opaque(def_id, _) - | ty::Generator(def_id, ..) - | ty::Foreign(def_id) = ty.kind - { - Some(self.tcx.def_span(def_id)) - } else { - None - }; + let span = + TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id)); Some((ty.to_string(), span)) } } From 33ae3220b638551834fddf5c0658563d8a52e89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jan 2020 09:28:01 -0800 Subject: [PATCH 0070/1253] remove unnecessary `Debug` --- src/librustc/infer/error_reporting/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 27523b1e689e2..5e5f39e6c7a22 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -2039,7 +2039,7 @@ impl<'tcx> ObligationCause<'tcx> { /// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks /// extra information about each type, but we only care about the category. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] crate enum TyCategory { Closure, Opaque, From 7c52718ba22179451bca76d246037a5f7480eae1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 8 Jan 2020 09:44:45 -0800 Subject: [PATCH 0071/1253] Remove obsolete llvm_tools flag --- src/bootstrap/tool.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 9fd20386e367b..89245825ed5b9 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -289,7 +289,6 @@ fn rustbook_features() -> Vec { macro_rules! bootstrap_tool { ($( $name:ident, $path:expr, $tool_name:expr - $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)* $(,features = $features:expr)* ; @@ -301,15 +300,6 @@ macro_rules! bootstrap_tool { )+ } - impl Tool { - /// Whether this tool requires LLVM to run - pub fn uses_llvm_tools(&self) -> bool { - match self { - $(Tool::$name => false $(|| $llvm)*,)+ - } - } - } - impl<'a> Builder<'a> { pub fn tool_exe(&self, tool: Tool) -> PathBuf { match tool { @@ -377,7 +367,7 @@ bootstrap_tool!( Tidy, "src/tools/tidy", "tidy"; Linkchecker, "src/tools/linkchecker", "linkchecker"; CargoTest, "src/tools/cargotest", "cargotest"; - Compiletest, "src/tools/compiletest", "compiletest", llvm_tools = true; + Compiletest, "src/tools/compiletest", "compiletest"; BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true; From 51b7044347d2cb9e2eae18ad49c79803dda60be2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 8 Jan 2020 10:04:18 -0800 Subject: [PATCH 0072/1253] Build compiletest with in-tree libtest --- src/bootstrap/tool.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 89245825ed5b9..7f24768a4f10e 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -290,6 +290,7 @@ macro_rules! bootstrap_tool { ($( $name:ident, $path:expr, $tool_name:expr $(,is_external_tool = $external:expr)* + $(,is_unstable_tool = $unstable:expr)* $(,features = $features:expr)* ; )+) => { @@ -340,7 +341,12 @@ macro_rules! bootstrap_tool { compiler: self.compiler, target: self.target, tool: $tool_name, - mode: Mode::ToolBootstrap, + mode: if false $(|| $unstable)* { + // use in-tree libraries for unstable features + Mode::ToolStd + } else { + Mode::ToolBootstrap + }, path: $path, is_optional_tool: false, source_type: if false $(|| $external)* { @@ -367,7 +373,7 @@ bootstrap_tool!( Tidy, "src/tools/tidy", "tidy"; Linkchecker, "src/tools/linkchecker", "linkchecker"; CargoTest, "src/tools/cargotest", "cargotest"; - Compiletest, "src/tools/compiletest", "compiletest"; + Compiletest, "src/tools/compiletest", "compiletest", is_unstable_tool = true; BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true; From 4fce9c27fbd7e0b54ebf3b5ad7620d95dea2f982 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 7 Jan 2020 16:51:34 +0900 Subject: [PATCH 0073/1253] Delay bug to prevent ICE in MIR borrowck --- src/librustc_mir/transform/elaborate_drops.rs | 8 +++++++- src/test/ui/mir/issue-67947.rs | 7 +++++++ src/test/ui/mir/issue-67947.stderr | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/mir/issue-67947.rs create mode 100644 src/test/ui/mir/issue-67947.stderr diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 86baf4deb5197..b9d9ed592fc72 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -28,7 +28,13 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { let param_env = tcx.param_env(src.def_id()).with_reveal_all(); let move_data = match MoveData::gather_moves(body, tcx, param_env) { Ok(move_data) => move_data, - Err(_) => bug!("No `move_errors` should be allowed in MIR borrowck"), + Err((move_data, _)) => { + tcx.sess.delay_span_bug( + body.span, + "No `move_errors` should be allowed in MIR borrowck", + ); + move_data + } }; let elaborate_patch = { let body = &*body; diff --git a/src/test/ui/mir/issue-67947.rs b/src/test/ui/mir/issue-67947.rs new file mode 100644 index 0000000000000..79e75e655ff1f --- /dev/null +++ b/src/test/ui/mir/issue-67947.rs @@ -0,0 +1,7 @@ +struct Bug { + A: [(); { *"" }.len()], + //~^ ERROR: cannot move a value of type str + //~| ERROR: cannot move out of a shared reference +} + +fn main() {} diff --git a/src/test/ui/mir/issue-67947.stderr b/src/test/ui/mir/issue-67947.stderr new file mode 100644 index 0000000000000..d526218162076 --- /dev/null +++ b/src/test/ui/mir/issue-67947.stderr @@ -0,0 +1,16 @@ +error[E0161]: cannot move a value of type str: the size of str cannot be statically determined + --> $DIR/issue-67947.rs:2:13 + | +LL | A: [(); { *"" }.len()], + | ^^^^^^^ + +error[E0507]: cannot move out of a shared reference + --> $DIR/issue-67947.rs:2:15 + | +LL | A: [(); { *"" }.len()], + | ^^^ move occurs because value has type `str`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. From 0d2f9825b5687470accfc2e25a73a0cd02c37e01 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 8 Jan 2020 13:57:01 -0800 Subject: [PATCH 0074/1253] Rebase LLVM onto 9.0.1 --- .gitmodules | 2 +- src/llvm-project | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 31db0772cfb6b..62cbbdd9a3a06 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,7 +40,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/9.0-2019-09-19 + branch = rustc/9.0-2019-12-19 [submodule "src/doc/embedded-book"] path = src/doc/embedded-book url = https://github.com/rust-embedded/book.git diff --git a/src/llvm-project b/src/llvm-project index 9330ec5a4c1df..cd87134ab77e6 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 9330ec5a4c1df5fc1fa62f993ed6a04da68cb040 +Subproject commit cd87134ab77e6bacb2128137065b328b9c35e0e5 From a5657dbc43d84133bd95e5de178d68634973b1b3 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Wed, 8 Jan 2020 23:13:56 +0100 Subject: [PATCH 0075/1253] perf: Avoid creating a SmallVec if nothing changes during a fold Not sure if this helps but in theory it should be less work than what the current micro optimization does for `ty::Predicate` lists. (It would explain the overhead I am seeing from `perf`.) --- src/librustc/ty/structural_impls.rs | 47 ++++++++++++++++++----------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index d87296c03dd2f..385c8eeb4b83c 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -803,8 +803,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter().map(|p| p.fold_with(folder)).collect::>(); - folder.tcx().intern_existential_predicates(&v) + fold_list(*self, folder, |tcx, v| tcx.intern_existential_predicates(v)) } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -814,8 +813,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); - folder.tcx().intern_type_list(&v) + fold_list(*self, folder, |tcx, v| tcx.intern_type_list(v)) } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -825,8 +823,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); - folder.tcx().intern_projs(&v) + fold_list(*self, folder, |tcx, v| tcx.intern_projs(v)) } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -990,17 +987,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { - // This code is hot enough that it's worth specializing for a list of - // length 0. (No other length is common enough to be worth singling - // out). - if self.len() == 0 { - self - } else { - // Don't bother interning if nothing changed, which is the common - // case. - let v = self.iter().map(|p| p.fold_with(folder)).collect::>(); - if v[..] == self[..] { self } else { folder.tcx().intern_predicates(&v) } - } + fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v)) } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -1073,3 +1060,29 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { false } } + +fn fold_list<'tcx, F, T>( + list: &'tcx ty::List, + folder: &mut F, + intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List, +) -> &'tcx ty::List +where + F: TypeFolder<'tcx>, + T: TypeFoldable<'tcx> + PartialEq + Copy, +{ + let mut iter = list.iter(); + // Look for the first element that changed + if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| { + let new_t = t.fold_with(folder); + if new_t == *t { None } else { Some((i, new_t)) } + }) { + // An element changed, prepare to intern the resulting list + let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len()); + new_list.copy_from_slice(&list[..i]); + new_list.push(new_t); + new_list.extend(iter.map(|t| t.fold_with(folder))); + intern(folder.tcx(), &new_list) + } else { + list + } +} From 084217af65b212c3c68f66d798faa19bcef5007a Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 8 Jan 2020 22:56:33 +0000 Subject: [PATCH 0076/1253] Don't use f64 shims for f32 cmath functions on none 32-bit x86 MSVC These shims are only needed on 32-bit x86. Additionally since https://reviews.llvm.org/rL268875 LLVM handles adding the shims itself for the intrinsics. --- src/libstd/f32.rs | 60 +++++---------------------------- src/libstd/sys/windows/cmath.rs | 10 +++--- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..acca4af85be01 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -44,23 +44,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn floor(self) -> f32 { - // On MSVC LLVM will lower many math intrinsics to a call to the - // corresponding function. On MSVC, however, many of these functions - // aren't actually available as symbols to call, but rather they are all - // `static inline` functions in header files. This means that from a C - // perspective it's "compatible", but not so much from an ABI - // perspective (which we're worried about). - // - // The inline header functions always just cast to a f64 and do their - // operation, so we do that here as well, but only for MSVC targets. - // - // Note that there are many MSVC-specific float operations which - // redirect to this comment, so `floorf` is just one case of a missing - // function on MSVC, but there are many others elsewhere. - #[cfg(target_env = "msvc")] - return (self as f64).floor() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::floorf32(self) }; + unsafe { intrinsics::floorf32(self) } } /// Returns the smallest integer greater than or equal to a number. @@ -78,11 +62,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ceil(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).ceil() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::ceilf32(self) }; + unsafe { intrinsics::ceilf32(self) } } /// Returns the nearest integer to a number. Round half-way cases away from @@ -348,11 +328,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn powf(self, n: f32) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).powf(n as f64) as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::powf32(self, n) }; + unsafe { intrinsics::powf32(self, n) } } /// Takes the square root of a number. @@ -399,11 +375,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).exp() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::expf32(self) }; + unsafe { intrinsics::expf32(self) } } /// Returns `2^(self)`. @@ -447,11 +419,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).ln() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::logf32(self) }; + unsafe { intrinsics::logf32(self) } } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -521,11 +489,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).log10() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::log10f32(self) }; + unsafe { intrinsics::log10f32(self) } } /// The positive difference of two numbers. @@ -625,11 +589,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn sin(self) -> f32 { - // see notes in `core::f32::Float::floor` - #[cfg(target_env = "msvc")] - return (self as f64).sin() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::sinf32(self) }; + unsafe { intrinsics::sinf32(self) } } /// Computes the cosine of a number (in radians). @@ -649,11 +609,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn cos(self) -> f32 { - // see notes in `core::f32::Float::floor` - #[cfg(target_env = "msvc")] - return (self as f64).cos() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::cosf32(self) }; + unsafe { intrinsics::cosf32(self) } } /// Computes the tangent of a number (in radians). diff --git a/src/libstd/sys/windows/cmath.rs b/src/libstd/sys/windows/cmath.rs index 6f5d40b494fbe..1a5421facd0c1 100644 --- a/src/libstd/sys/windows/cmath.rs +++ b/src/libstd/sys/windows/cmath.rs @@ -27,7 +27,7 @@ extern "C" { pub use self::shims::*; -#[cfg(not(target_env = "msvc"))] +#[cfg(not(all(target_env = "msvc", target_arch = "x86")))] mod shims { use libc::c_float; @@ -43,10 +43,10 @@ mod shims { } } -// On MSVC these functions aren't defined, so we just define shims which promote -// everything fo f64, perform the calculation, and then demote back to f32. -// While not precisely correct should be "correct enough" for now. -#[cfg(target_env = "msvc")] +// On 32-bit x86 MSVC these functions aren't defined, so we just define shims +// which promote everything fo f64, perform the calculation, and then demote +// back to f32. While not precisely correct should be "correct enough" for now. +#[cfg(all(target_env = "msvc", target_arch = "x86"))] mod shims { use libc::c_float; From 686d5f83efcd552465ce4ab236f2ffb66c055d90 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 8 Jan 2020 15:13:50 -0800 Subject: [PATCH 0077/1253] Comment on allowing only feature(test) in compiletest --- src/tools/compiletest/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index da1e3760e010d..0642823404aed 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,6 +1,8 @@ #![crate_name = "compiletest"] -#![feature(test)] #![deny(warnings)] +// The `test` crate is the only unstable feature +// allowed here, just to share similar code. +#![feature(test)] extern crate test; From 4ede63bee1c4ef6af808f1bdcd7439a88f23b096 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 16 Dec 2019 10:53:50 -0800 Subject: [PATCH 0078/1253] Add HashSet::get_or_insert_owned --- src/libstd/collections/hash/set.rs | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 566e5146cf857..b48700fb94420 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -631,6 +631,38 @@ where self.map.raw_entry_mut().from_key(&value).or_insert(value, ()).0 } + /// Inserts an owned copy of the given `value` into the set if it is not + /// present, then returns a reference to the value in the set. + /// + /// # Examples + /// + /// ``` + /// #![feature(hash_set_entry)] + /// + /// use std::collections::HashSet; + /// + /// let mut set: HashSet = ["cat", "dog", "horse"] + /// .iter().map(|&pet| pet.to_owned()).collect(); + /// + /// assert_eq!(set.len(), 3); + /// for &pet in &["cat", "dog", "fish"] { + /// let value = set.get_or_insert_owned(pet); + /// assert_eq!(value, pet); + /// } + /// assert_eq!(set.len(), 4); // a new "fish" was inserted + /// ``` + #[inline] + #[unstable(feature = "hash_set_entry", issue = "60896")] + pub fn get_or_insert_owned(&mut self, value: &Q) -> &T + where + T: Borrow, + Q: Hash + Eq + ToOwned, + { + // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with + // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`. + self.map.raw_entry_mut().from_key(value).or_insert_with(|| (value.to_owned(), ())).0 + } + /// Inserts a value computed from `f` into the set if the given `value` is /// not present, then returns a reference to the value in the set. /// From 1ffb9cf8d75e6f8b9aa27a25c7bc56c7bb3a1c43 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Tue, 7 Jan 2020 10:25:02 +0800 Subject: [PATCH 0079/1253] rustdoc: improve stability mark arrows --- src/librustdoc/html/static/rustdoc.css | 9 +++++---- src/librustdoc/html/static/themes/dark.css | 2 ++ src/librustdoc/html/static/themes/light.css | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 62fe23029d92f..870a99f362a73 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -542,11 +542,12 @@ h4 > code, h3 > code, .invisible > code { } .content .stability::before { - content: '˪'; - font-size: 30px; + content: '⤶'; + transform:rotate(90deg); + font-size: 25px; position: absolute; - top: -9px; - left: -13px; + top: -6px; + left: -17px; } .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index f46bd6d6a1005..9a0e7bbabcba9 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -105,6 +105,8 @@ pre { .content .highlighted.primitive { background-color: #00708a; } .content .highlighted.keyword { background-color: #884719; } +.content .stability::before { color: #ccc; } + .content span.enum, .content a.enum, .block a.current.enum { color: #82b089; } .content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; } .content span.type, .content a.type, .block a.current.type { color: #ff7f00; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index ca67b1c1f8241..ca8ea1c456a2c 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -105,6 +105,8 @@ pre { .content .highlighted.primitive { background-color: #9aecff; } .content .highlighted.keyword { background-color: #f99650; } +.content .stability::before { color: #ccc; } + .content span.enum, .content a.enum, .block a.current.enum { color: #508157; } .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; } .content span.type, .content a.type, .block a.current.type { color: #ba5d00; } From ae3a53ff58cec7aca1dfd17479fca44b7f91491f Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Thu, 9 Jan 2020 09:54:05 +0800 Subject: [PATCH 0080/1253] rustdoc: use another stability mark arrow, no rotate. --- src/librustdoc/html/static/rustdoc.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 870a99f362a73..a91fdb7a10e0d 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -542,12 +542,11 @@ h4 > code, h3 > code, .invisible > code { } .content .stability::before { - content: '⤶'; - transform:rotate(90deg); + content: '⬑'; font-size: 25px; position: absolute; top: -6px; - left: -17px; + left: -19px; } .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { From 826780772e3fdd8fa5f491647f849d0be4cb6356 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 8 Jan 2020 21:43:54 -0500 Subject: [PATCH 0081/1253] remove strip-hidden pass from compiler doc generation --- src/bootstrap/doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 8cd7fc2c17257..e98ac8d6f477c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -531,7 +531,7 @@ impl Step for Rustc { // Build cargo command. let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc"); - cargo.env("RUSTDOCFLAGS", "--document-private-items --passes strip-hidden"); + cargo.env("RUSTDOCFLAGS", "--document-private-items"); compile::rustc_cargo(builder, &mut cargo, target); // Only include compiler crates, no dependencies of those, such as `libc`. From dbcce10bb1c3e9651b83f1d9396813c0cd1054f6 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 9 Jan 2020 11:47:32 +0900 Subject: [PATCH 0082/1253] Remove unused `struct ClosureUpvar` --- src/librustc/ty/mod.rs | 7 ------- src/librustc/ty/structural_impls.rs | 6 ------ src/librustc_typeck/check/upvar.rs | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7cca12308e65f..0aacc5feec374 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -809,13 +809,6 @@ pub struct UpvarBorrow<'tcx> { pub type UpvarListMap = FxHashMap>; pub type UpvarCaptureMap<'tcx> = FxHashMap>; -#[derive(Copy, Clone, TypeFoldable)] -pub struct ClosureUpvar<'tcx> { - pub res: Res, - pub span: Span, - pub ty: Ty<'tcx>, -} - #[derive(Clone, Copy, PartialEq, Eq)] pub enum IntVarValue { IntType(ast::IntTy), diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index d87296c03dd2f..5e24c843025bf 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -45,12 +45,6 @@ impl fmt::Debug for ty::AdtDef { } } -impl fmt::Debug for ty::ClosureUpvar<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ClosureUpvar({:?},{:?})", self.res, self.ty) - } -} - impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index be912b6bcafc0..a1922166fe265 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // Returns a list of `ClosureUpvar`s for each upvar. + // Returns a list of `Ty`s for each upvar. fn final_upvar_tys(&self, closure_id: hir::HirId) -> Vec> { // Presently an unboxed closure type cannot "escape" out of a // function, so we will only encounter ones that originated in the From f443ae68c2d9bbe83e73c495572dc5d59b36e6ea Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 9 Jan 2020 11:52:03 +0900 Subject: [PATCH 0083/1253] Remove unused dependencies --- Cargo.lock | 10 ---------- src/librustc/Cargo.toml | 3 --- src/librustc_codegen_llvm/Cargo.toml | 1 - src/librustc_driver/Cargo.toml | 2 -- src/librustc_lint/Cargo.toml | 1 - src/libsyntax/Cargo.toml | 2 -- src/rustc/Cargo.toml | 1 - 7 files changed, 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 274c1eefbfb52..a18c3b896d3d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3079,8 +3079,6 @@ dependencies = [ "graphviz", "jobserver", "log", - "measureme", - "num_cpus", "parking_lot", "polonius-engine", "rustc-rayon", @@ -3090,7 +3088,6 @@ dependencies = [ "rustc_error_codes", "rustc_errors", "rustc_feature", - "rustc_fs_util", "rustc_hir", "rustc_index", "rustc_macros", @@ -3278,7 +3275,6 @@ dependencies = [ "jemalloc-sys", "rustc_codegen_ssa", "rustc_driver", - "rustc_target", ] [[package]] @@ -3409,7 +3405,6 @@ dependencies = [ "rustc_codegen_utils", "rustc_data_structures", "rustc_errors", - "rustc_expand", "rustc_feature", "rustc_fs_util", "rustc_hir", @@ -3497,7 +3492,6 @@ name = "rustc_driver" version = "0.0.0" dependencies = [ "env_logger 0.7.1", - "graphviz", "lazy_static 1.3.0", "log", "rustc", @@ -3513,7 +3507,6 @@ dependencies = [ "rustc_mir", "rustc_parse", "rustc_plugin_impl", - "rustc_resolve", "rustc_save_analysis", "rustc_span", "rustc_target", @@ -3660,7 +3653,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_feature", "rustc_hir", "rustc_index", @@ -4462,8 +4454,6 @@ dependencies = [ name = "syntax" version = "0.0.0" dependencies = [ - "bitflags", - "lazy_static 1.3.0", "log", "rustc_data_structures", "rustc_error_codes", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 2e882cfdafdf3..1a04a9d86b58b 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -15,7 +15,6 @@ bitflags = "1.2.1" fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } jobserver = "0.1" -num_cpus = "1.0" scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } rustc-rayon = "0.3.0" @@ -36,8 +35,6 @@ backtrace = "0.3.40" parking_lot = "0.9" byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } -rustc_fs_util = { path = "../librustc_fs_util" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -measureme = "0.5" rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 2d9232bc19255..3ff5495e29136 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -31,5 +31,4 @@ rustc_session = { path = "../librustc_session" } rustc_target = { path = "../librustc_target" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } -rustc_expand = { path = "../librustc_expand" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index ed742ed1ca0a3..5e0c853ed2473 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -10,7 +10,6 @@ path = "lib.rs" crate-type = ["dylib"] [dependencies] -graphviz = { path = "../libgraphviz" } lazy_static = "1.0" log = "0.4" env_logger = { version = "0.7", default-features = false } @@ -30,7 +29,6 @@ rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_error_codes = { path = "../librustc_error_codes" } rustc_interface = { path = "../librustc_interface" } rustc_serialize = { path = "../libserialize", package = "serialize" } -rustc_resolve = { path = "../librustc_resolve" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 820064cb5b6f8..5ca8fc97ac422 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -19,5 +19,4 @@ rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_index = { path = "../librustc_index" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 2098656db9822..e4f0398fb42d2 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -10,11 +10,9 @@ path = "lib.rs" doctest = false [dependencies] -bitflags = "1.2.1" rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" scoped-tls = "1.0" -lazy_static = "1.0.0" rustc_span = { path = "../librustc_span" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 86a93d7d0cbfe..5e0f167bb3801 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -9,7 +9,6 @@ name = "rustc_binary" path = "rustc.rs" [dependencies] -rustc_target = { path = "../librustc_target" } rustc_driver = { path = "../librustc_driver" } # Make sure rustc_codegen_ssa ends up in the sysroot, because this From 31938366d2da5434344011f20fc2564e03228cd1 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 9 Jan 2020 05:20:06 +0100 Subject: [PATCH 0084/1253] Keep plugging holes in the test to placate CI. If this happens again, I'm going to change tack and make this an `// only-linux` test or something along those lines. --- src/test/ui/non-ice-error-on-worker-io-fail.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.rs b/src/test/ui/non-ice-error-on-worker-io-fail.rs index deffb2969b60e..8af17742850da 100644 --- a/src/test/ui/non-ice-error-on-worker-io-fail.rs +++ b/src/test/ui/non-ice-error-on-worker-io-fail.rs @@ -24,6 +24,7 @@ // ignore-windows - this is a unix-specific test // ignore-emscripten - the file-system issues do not replicate here // ignore-wasm - the file-system issues do not replicate here +// ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu #![crate_type="lib"] From 898ed636a3f44e3aa0156c1bb5ebc86b08aef5fa Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 9 Jan 2020 07:45:29 +0100 Subject: [PATCH 0085/1253] Fix copy_from_slice which should be extend_from_slice --- src/librustc/ty/structural_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 385c8eeb4b83c..783164d2806c1 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1078,7 +1078,7 @@ where }) { // An element changed, prepare to intern the resulting list let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len()); - new_list.copy_from_slice(&list[..i]); + new_list.extend_from_slice(&list[..i]); new_list.push(new_t); new_list.extend(iter.map(|t| t.fold_with(folder))); intern(folder.tcx(), &new_list) From 78e7eeeaa1f93f40fa96c36194b1afdfbfdb7364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 6 Oct 2019 00:00:00 +0000 Subject: [PATCH 0086/1253] Remove sanitizer runtime crates --- Cargo.lock | 48 ---------------- src/bootstrap/dist.rs | 4 -- src/build_helper/lib.rs | 104 ----------------------------------- src/librustc_asan/Cargo.toml | 20 ------- src/librustc_asan/build.rs | 30 ---------- src/librustc_asan/lib.rs | 10 ---- src/librustc_lsan/Cargo.toml | 20 ------- src/librustc_lsan/build.rs | 29 ---------- src/librustc_lsan/lib.rs | 10 ---- src/librustc_msan/Cargo.toml | 20 ------- src/librustc_msan/build.rs | 29 ---------- src/librustc_msan/lib.rs | 10 ---- src/librustc_tsan/Cargo.toml | 20 ------- src/librustc_tsan/build.rs | 30 ---------- src/librustc_tsan/lib.rs | 10 ---- src/libstd/Cargo.toml | 10 ---- 16 files changed, 404 deletions(-) delete mode 100644 src/librustc_asan/Cargo.toml delete mode 100644 src/librustc_asan/build.rs delete mode 100644 src/librustc_asan/lib.rs delete mode 100644 src/librustc_lsan/Cargo.toml delete mode 100644 src/librustc_lsan/build.rs delete mode 100644 src/librustc_lsan/lib.rs delete mode 100644 src/librustc_msan/Cargo.toml delete mode 100644 src/librustc_msan/build.rs delete mode 100644 src/librustc_msan/lib.rs delete mode 100644 src/librustc_tsan/Cargo.toml delete mode 100644 src/librustc_tsan/build.rs delete mode 100644 src/librustc_tsan/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 4f60ea305196e..1470e2be75df8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3348,17 +3348,6 @@ dependencies = [ "smallvec 1.0.0", ] -[[package]] -name = "rustc_asan" -version = "0.0.0" -dependencies = [ - "alloc", - "build_helper", - "cmake", - "compiler_builtins", - "core", -] - [[package]] name = "rustc_ast_lowering" version = "0.0.0" @@ -3680,17 +3669,6 @@ dependencies = [ "libc", ] -[[package]] -name = "rustc_lsan" -version = "0.0.0" -dependencies = [ - "alloc", - "build_helper", - "cmake", - "compiler_builtins", - "core", -] - [[package]] name = "rustc_macros" version = "0.1.0" @@ -3752,17 +3730,6 @@ dependencies = [ "syntax", ] -[[package]] -name = "rustc_msan" -version = "0.0.0" -dependencies = [ - "alloc", - "build_helper", - "cmake", - "compiler_builtins", - "core", -] - [[package]] name = "rustc_parse" version = "0.0.0" @@ -3935,17 +3902,6 @@ dependencies = [ "syntax", ] -[[package]] -name = "rustc_tsan" -version = "0.0.0" -dependencies = [ - "alloc", - "build_helper", - "cmake", - "compiler_builtins", - "core", -] - [[package]] name = "rustc_typeck" version = "0.0.0" @@ -4307,10 +4263,6 @@ dependencies = [ "panic_unwind", "profiler_builtins", "rand 0.7.0", - "rustc_asan", - "rustc_lsan", - "rustc_msan", - "rustc_tsan", "unwind", "wasi 0.9.0+wasi-snapshot-preview1", ] diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e64d4c8637d55..8d13df3ee21a4 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -984,10 +984,6 @@ impl Step for Src { "src/libcore", "src/libpanic_abort", "src/libpanic_unwind", - "src/librustc_asan", - "src/librustc_lsan", - "src/librustc_msan", - "src/librustc_tsan", "src/libstd", "src/libunwind", "src/libtest", diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 3f42533238a89..43c3c5773ce5b 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,7 +1,5 @@ -use std::fs::File; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use std::thread; use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, fs}; @@ -181,108 +179,6 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool { } } -#[must_use] -pub struct NativeLibBoilerplate { - pub src_dir: PathBuf, - pub out_dir: PathBuf, -} - -impl NativeLibBoilerplate { - /// On macOS we don't want to ship the exact filename that compiler-rt builds. - /// This conflicts with the system and ours is likely a wildly different - /// version, so they can't be substituted. - /// - /// As a result, we rename it here but we need to also use - /// `install_name_tool` on macOS to rename the commands listed inside of it to - /// ensure it's linked against correctly. - pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) { - if env::var("TARGET").unwrap() != "x86_64-apple-darwin" { - return; - } - - let dir = self.out_dir.join("build/lib/darwin"); - let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name); - let src = dir.join(&format!("lib{}.dylib", name)); - let new_name = format!("lib__rustc__{}.dylib", name); - let dst = dir.join(&new_name); - - println!("{} => {}", src.display(), dst.display()); - fs::rename(&src, &dst).unwrap(); - let status = Command::new("install_name_tool") - .arg("-id") - .arg(format!("@rpath/{}", new_name)) - .arg(&dst) - .status() - .expect("failed to execute `install_name_tool`"); - assert!(status.success()); - } -} - -impl Drop for NativeLibBoilerplate { - fn drop(&mut self) { - if !thread::panicking() { - t!(File::create(self.out_dir.join("rustbuild.timestamp"))); - } - } -} - -// Perform standard preparations for native libraries that are build only once for all stages. -// Emit rerun-if-changed and linking attributes for Cargo, check if any source files are -// updated, calculate paths used later in actual build with CMake/make or C/C++ compiler. -// If Err is returned, then everything is up-to-date and further build actions can be skipped. -// Timestamps are created automatically when the result of `native_lib_boilerplate` goes out -// of scope, so all the build actions should be completed until then. -pub fn native_lib_boilerplate( - src_dir: &Path, - out_name: &str, - link_name: &str, - search_subdir: &str, -) -> Result { - rerun_if_changed_anything_in_dir(src_dir); - - let out_dir = - env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(|| env::var_os("OUT_DIR").unwrap()); - let out_dir = PathBuf::from(out_dir).join(out_name); - t!(fs::create_dir_all(&out_dir)); - if link_name.contains('=') { - println!("cargo:rustc-link-lib={}", link_name); - } else { - println!("cargo:rustc-link-lib=static={}", link_name); - } - println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display()); - - let timestamp = out_dir.join("rustbuild.timestamp"); - if !up_to_date(Path::new("build.rs"), ×tamp) || !up_to_date(src_dir, ×tamp) { - Ok(NativeLibBoilerplate { src_dir: src_dir.to_path_buf(), out_dir }) - } else { - Err(()) - } -} - -pub fn sanitizer_lib_boilerplate( - sanitizer_name: &str, -) -> Result<(NativeLibBoilerplate, String), ()> { - let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() { - "x86_64-unknown-linux-gnu" => { - (format!("clang_rt.{}-x86_64", sanitizer_name), "build/lib/linux", false) - } - "x86_64-apple-darwin" => { - (format!("clang_rt.{}_osx_dynamic", sanitizer_name), "build/lib/darwin", true) - } - _ => return Err(()), - }; - let to_link = if apple { - format!("dylib=__rustc__{}", link_name) - } else { - format!("static={}", link_name) - }; - // This env var is provided by rustbuild to tell us where `compiler-rt` - // lives. - let dir = env::var_os("RUST_COMPILER_RT_ROOT").unwrap(); - let lib = native_lib_boilerplate(dir.as_ref(), sanitizer_name, &to_link, search_path)?; - Ok((lib, link_name)) -} - fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool { t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| { let meta = t!(e.metadata()); diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml deleted file mode 100644 index df117de8720e0..0000000000000 --- a/src/librustc_asan/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -build = "build.rs" -name = "rustc_asan" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_asan" -path = "lib.rs" -test = false - -[build-dependencies] -build_helper = { path = "../build_helper" } -cmake = "0.1.38" - -[dependencies] -alloc = { path = "../liballoc" } -core = { path = "../libcore" } -compiler_builtins = "0.1.0" diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs deleted file mode 100644 index e276dc16c35ee..0000000000000 --- a/src/librustc_asan/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -use build_helper::sanitizer_lib_boilerplate; -use std::env; - -use cmake::Config; - -fn main() { - println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS"); - if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) { - return; - } - if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - build_helper::restore_library_path(); - - let (native, target) = match sanitizer_lib_boilerplate("asan") { - Ok(native) => native, - _ => return, - }; - - Config::new(&native.src_dir) - .define("COMPILER_RT_BUILD_SANITIZERS", "ON") - .define("COMPILER_RT_BUILD_BUILTINS", "OFF") - .define("COMPILER_RT_BUILD_XRAY", "OFF") - .define("LLVM_CONFIG_PATH", llvm_config) - .out_dir(&native.out_dir) - .build_target(&target) - .build(); - native.fixup_sanitizer_lib_name("asan"); - } - println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); -} diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs deleted file mode 100644 index bdbc154f4e861..0000000000000 --- a/src/librustc_asan/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![sanitizer_runtime] -#![feature(nll)] -#![feature(sanitizer_runtime)] -#![feature(staged_api)] -#![no_std] -#![unstable( - feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none" -)] diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml deleted file mode 100644 index 9a24361f44e64..0000000000000 --- a/src/librustc_lsan/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -build = "build.rs" -name = "rustc_lsan" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_lsan" -path = "lib.rs" -test = false - -[build-dependencies] -build_helper = { path = "../build_helper" } -cmake = "0.1.38" - -[dependencies] -alloc = { path = "../liballoc" } -core = { path = "../libcore" } -compiler_builtins = "0.1.0" diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs deleted file mode 100644 index 6201bc9356dce..0000000000000 --- a/src/librustc_lsan/build.rs +++ /dev/null @@ -1,29 +0,0 @@ -use build_helper::sanitizer_lib_boilerplate; -use std::env; - -use cmake::Config; - -fn main() { - println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS"); - if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) { - return; - } - if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - build_helper::restore_library_path(); - - let (native, target) = match sanitizer_lib_boilerplate("lsan") { - Ok(native) => native, - _ => return, - }; - - Config::new(&native.src_dir) - .define("COMPILER_RT_BUILD_SANITIZERS", "ON") - .define("COMPILER_RT_BUILD_BUILTINS", "OFF") - .define("COMPILER_RT_BUILD_XRAY", "OFF") - .define("LLVM_CONFIG_PATH", llvm_config) - .out_dir(&native.out_dir) - .build_target(&target) - .build(); - } - println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); -} diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs deleted file mode 100644 index bdbc154f4e861..0000000000000 --- a/src/librustc_lsan/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![sanitizer_runtime] -#![feature(nll)] -#![feature(sanitizer_runtime)] -#![feature(staged_api)] -#![no_std] -#![unstable( - feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none" -)] diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml deleted file mode 100644 index bda4078572501..0000000000000 --- a/src/librustc_msan/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -build = "build.rs" -name = "rustc_msan" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_msan" -path = "lib.rs" -test = false - -[build-dependencies] -build_helper = { path = "../build_helper" } -cmake = "0.1.38" - -[dependencies] -alloc = { path = "../liballoc" } -core = { path = "../libcore" } -compiler_builtins = "0.1.0" diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs deleted file mode 100644 index dc08d51b51cb0..0000000000000 --- a/src/librustc_msan/build.rs +++ /dev/null @@ -1,29 +0,0 @@ -use build_helper::sanitizer_lib_boilerplate; -use std::env; - -use cmake::Config; - -fn main() { - println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS"); - if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) { - return; - } - if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - build_helper::restore_library_path(); - - let (native, target) = match sanitizer_lib_boilerplate("msan") { - Ok(native) => native, - _ => return, - }; - - Config::new(&native.src_dir) - .define("COMPILER_RT_BUILD_SANITIZERS", "ON") - .define("COMPILER_RT_BUILD_BUILTINS", "OFF") - .define("COMPILER_RT_BUILD_XRAY", "OFF") - .define("LLVM_CONFIG_PATH", llvm_config) - .out_dir(&native.out_dir) - .build_target(&target) - .build(); - } - println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); -} diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs deleted file mode 100644 index bdbc154f4e861..0000000000000 --- a/src/librustc_msan/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![sanitizer_runtime] -#![feature(nll)] -#![feature(sanitizer_runtime)] -#![feature(staged_api)] -#![no_std] -#![unstable( - feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none" -)] diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml deleted file mode 100644 index 82045dd0cddc7..0000000000000 --- a/src/librustc_tsan/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -build = "build.rs" -name = "rustc_tsan" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_tsan" -path = "lib.rs" -test = false - -[build-dependencies] -build_helper = { path = "../build_helper" } -cmake = "0.1.38" - -[dependencies] -alloc = { path = "../liballoc" } -core = { path = "../libcore" } -compiler_builtins = "0.1.0" diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs deleted file mode 100644 index 570642a2eaa76..0000000000000 --- a/src/librustc_tsan/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -use build_helper::sanitizer_lib_boilerplate; -use std::env; - -use cmake::Config; - -fn main() { - println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS"); - if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) { - return; - } - if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - build_helper::restore_library_path(); - - let (native, target) = match sanitizer_lib_boilerplate("tsan") { - Ok(native) => native, - _ => return, - }; - - Config::new(&native.src_dir) - .define("COMPILER_RT_BUILD_SANITIZERS", "ON") - .define("COMPILER_RT_BUILD_BUILTINS", "OFF") - .define("COMPILER_RT_BUILD_XRAY", "OFF") - .define("LLVM_CONFIG_PATH", llvm_config) - .out_dir(&native.out_dir) - .build_target(&target) - .build(); - native.fixup_sanitizer_lib_name("tsan"); - } - println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); -} diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs deleted file mode 100644 index bdbc154f4e861..0000000000000 --- a/src/librustc_tsan/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![sanitizer_runtime] -#![feature(nll)] -#![feature(sanitizer_runtime)] -#![feature(staged_api)] -#![no_std] -#![unstable( - feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none" -)] diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index a22e162bbff48..c9ff93eac0295 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -34,16 +34,6 @@ features = [ "rustc-dep-of-std" ] # enable build support for integrating into li [dev-dependencies] rand = "0.7" -[target.x86_64-apple-darwin.dependencies] -rustc_asan = { path = "../librustc_asan" } -rustc_tsan = { path = "../librustc_tsan" } - -[target.x86_64-unknown-linux-gnu.dependencies] -rustc_asan = { path = "../librustc_asan" } -rustc_lsan = { path = "../librustc_lsan" } -rustc_msan = { path = "../librustc_msan" } -rustc_tsan = { path = "../librustc_tsan" } - [target.'cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] } From 36d08125705598aa12ceb092f34c332fbba12c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 7 Oct 2019 00:00:00 +0000 Subject: [PATCH 0087/1253] Remove sanitizer_runtime attribute --- .../src/library-features/sanitizer-runtime-lib.md | 5 ----- src/librustc/query/mod.rs | 4 ---- src/librustc_codegen_ssa/base.rs | 4 ---- src/librustc_codegen_ssa/lib.rs | 1 - src/librustc_feature/active.rs | 3 --- src/librustc_feature/builtin_attrs.rs | 5 ----- src/librustc_feature/removed.rs | 2 ++ src/librustc_metadata/rmeta/decoder.rs | 4 ---- src/librustc_metadata/rmeta/decoder/cstore_impl.rs | 1 - src/librustc_metadata/rmeta/encoder.rs | 1 - src/librustc_metadata/rmeta/mod.rs | 1 - .../feature-gates/feature-gate-sanitizer-runtime.rs | 3 --- .../feature-gate-sanitizer-runtime.stderr | 11 ----------- 13 files changed, 2 insertions(+), 43 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/sanitizer-runtime-lib.md delete mode 100644 src/test/ui/feature-gates/feature-gate-sanitizer-runtime.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr diff --git a/src/doc/unstable-book/src/library-features/sanitizer-runtime-lib.md b/src/doc/unstable-book/src/library-features/sanitizer-runtime-lib.md deleted file mode 100644 index 82ae67fc05ac3..0000000000000 --- a/src/doc/unstable-book/src/library-features/sanitizer-runtime-lib.md +++ /dev/null @@ -1,5 +0,0 @@ -# `sanitizer_runtime_lib` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 4a2ec9b9687f3..9de46f86200e1 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -686,10 +686,6 @@ rustc_queries! { fatal_cycle desc { "checking if the crate has_panic_handler" } } - query is_sanitizer_runtime(_: CrateNum) -> bool { - fatal_cycle - desc { "query a crate is `#![sanitizer_runtime]`" } - } query is_profiler_runtime(_: CrateNum) -> bool { fatal_cycle desc { "query a crate is `#![profiler_runtime]`" } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index ededb36c7127f..cb094079d6456 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -723,7 +723,6 @@ impl CrateInfo { panic_runtime: None, compiler_builtins: None, profiler_runtime: None, - sanitizer_runtime: None, is_no_builtins: Default::default(), native_libraries: Default::default(), used_libraries: tcx.native_libraries(LOCAL_CRATE), @@ -759,9 +758,6 @@ impl CrateInfo { if tcx.is_profiler_runtime(cnum) { info.profiler_runtime = Some(cnum); } - if tcx.is_sanitizer_runtime(cnum) { - info.sanitizer_runtime = Some(cnum); - } if tcx.is_no_builtins(cnum) { info.is_no_builtins.insert(cnum); } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index a8d051db8b478..ee527ecb509b2 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -122,7 +122,6 @@ pub struct CrateInfo { pub panic_runtime: Option, pub compiler_builtins: Option, pub profiler_runtime: Option, - pub sanitizer_runtime: Option, pub is_no_builtins: FxHashSet, pub native_libraries: FxHashMap>>, pub crate_name: FxHashMap, diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 8cb1684491bb8..3b894775e6973 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -192,9 +192,6 @@ declare_features! ( /// Allows using the `unadjusted` ABI; perma-unstable. (active, abi_unadjusted, "1.16.0", None, None), - /// Allows identifying crates that contain sanitizer runtimes. - (active, sanitizer_runtime, "1.17.0", None, None), - /// Used to identify crates that contain the profiler runtime. (active, profiler_runtime, "1.18.0", None, None), diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index 3cbf96b6d29a1..a38726e3de81f 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -409,11 +409,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ which contains compiler-rt intrinsics and will never be stable", ), - gated!( - sanitizer_runtime, Whitelisted, template!(Word), - "the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime \ - of a sanitizer and will never be stable", - ), gated!( profiler_runtime, Whitelisted, template!(Word), "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ diff --git a/src/librustc_feature/removed.rs b/src/librustc_feature/removed.rs index 1eeedd7721416..d5b6fe81c7be8 100644 --- a/src/librustc_feature/removed.rs +++ b/src/librustc_feature/removed.rs @@ -74,6 +74,8 @@ declare_features! ( (removed, pushpop_unsafe, "1.2.0", None, None, None), (removed, needs_allocator, "1.4.0", Some(27389), None, Some("subsumed by `#![feature(allocator_internals)]`")), + /// Allows identifying crates that contain sanitizer runtimes. + (removed, sanitizer_runtime, "1.17.0", None, None, None), (removed, proc_macro_mod, "1.27.0", Some(54727), None, Some("subsumed by `#![feature(proc_macro_hygiene)]`")), (removed, proc_macro_expr, "1.27.0", Some(54727), None, diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 77d143643b59e..4d3be00debaf9 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1587,10 +1587,6 @@ impl<'a, 'tcx> CrateMetadata { self.root.panic_runtime } - crate fn is_sanitizer_runtime(&self) -> bool { - self.root.sanitizer_runtime - } - crate fn is_profiler_runtime(&self) -> bool { self.root.profiler_runtime } diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index ba3c4e4aff443..b61ab8cc450fa 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -161,7 +161,6 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } has_panic_handler => { cdata.root.has_panic_handler } - is_sanitizer_runtime => { cdata.root.sanitizer_runtime } is_profiler_runtime => { cdata.root.profiler_runtime } panic_strategy => { cdata.root.panic_strategy } extern_crate => { diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 952d3bb858276..7f8791d0c34dc 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -514,7 +514,6 @@ impl<'tcx> EncodeContext<'tcx> { no_builtins: attr::contains_name(&attrs, sym::no_builtins), panic_runtime: attr::contains_name(&attrs, sym::panic_runtime), profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime), - sanitizer_runtime: attr::contains_name(&attrs, sym::sanitizer_runtime), symbol_mangling_version: tcx.sess.opts.debugging_opts.symbol_mangling_version, crate_deps, diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 6309f1c260e1c..426ea62b8cd4c 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -209,7 +209,6 @@ crate struct CrateRoot<'tcx> { no_builtins: bool, panic_runtime: bool, profiler_runtime: bool, - sanitizer_runtime: bool, symbol_mangling_version: SymbolManglingVersion, } diff --git a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.rs b/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.rs deleted file mode 100644 index 3b972c117a6ff..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr b/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr deleted file mode 100644 index b13ec215f8c08..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime of a sanitizer and will never be stable - --> $DIR/feature-gate-sanitizer-runtime.rs:1:1 - | -LL | #![sanitizer_runtime] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(sanitizer_runtime)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 0c6b1a7e3c54ff3a5ef6744073281b00368749c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 7 Nov 2019 00:00:00 +0000 Subject: [PATCH 0088/1253] Link sanitizer runtimes instead of injecting crate dependencies --- src/librustc_codegen_ssa/back/link.rs | 89 +++++++-------- src/librustc_metadata/creader.rs | 105 +----------------- src/librustc_session/session.rs | 26 +++++ .../sanitizer-address/Makefile | 2 +- .../sanitizer-invalid-cratetype/Makefile | 16 --- .../sanitizer-invalid-cratetype/hello.rs | 3 - .../sanitizer-invalid-target/Makefile | 2 +- .../run-make-fulldeps/sanitizer-leak/Makefile | 2 +- .../sanitizer-memory/Makefile | 4 +- 9 files changed, 74 insertions(+), 175 deletions(-) delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index a53402ebb5c7d..c91491fa54864 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -531,6 +531,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( { let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor, target_cpu); + link_sanitizer_runtime(sess, crate_type, &mut *linker); link_args::( &mut *linker, flavor, @@ -735,6 +736,47 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( } } +fn link_sanitizer_runtime(sess: &Session, crate_type: config::CrateType, linker: &mut dyn Linker) { + let sanitizer = match &sess.opts.debugging_opts.sanitizer { + Some(s) => s, + None => return, + }; + + if crate_type != config::CrateType::Executable { + return; + } + + let name = match sanitizer { + Sanitizer::Address => "asan", + Sanitizer::Leak => "lsan", + Sanitizer::Memory => "msan", + Sanitizer::Thread => "tsan", + }; + + let default_sysroot = filesearch::get_or_default_sysroot(); + let default_tlib = + filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.triple()); + + match sess.opts.target_triple.triple() { + "x86_64-apple-darwin" => { + // On Apple platforms, the sanitizer is always built as a dylib, and + // LLVM will link to `@rpath/*.dylib`, so we need to specify an + // rpath to the library as well (the rpath should be absolute, see + // PR #41352 for details). + let libname = format!("rustc_rt.{}", name); + let rpath = default_tlib.to_str().expect("non-utf8 component in path"); + linker.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]); + linker.link_dylib(Symbol::intern(&libname)); + } + "x86_64-unknown-linux-gnu" => { + let filename = format!("librustc_rt.{}.a", name); + let path = default_tlib.join(&filename); + linker.link_whole_rlib(&path); + } + _ => {} + } +} + /// Returns a boolean indicating whether the specified crate should be ignored /// during LTO. /// @@ -1415,12 +1457,6 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( _ if codegen_results.crate_info.profiler_runtime == Some(cnum) => { add_static_crate::(cmd, sess, codegen_results, tmpdir, crate_type, cnum); } - _ if codegen_results.crate_info.sanitizer_runtime == Some(cnum) - && crate_type == config::CrateType::Executable => - { - // Link the sanitizer runtimes only if we are actually producing an executable - link_sanitizer_runtime::(cmd, sess, codegen_results, tmpdir, cnum); - } // compiler-builtins are always placed last to ensure that they're // linked correctly. _ if codegen_results.crate_info.compiler_builtins == Some(cnum) => { @@ -1457,47 +1493,6 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( } } - // We must link the sanitizer runtime using -Wl,--whole-archive but since - // it's packed in a .rlib, it contains stuff that are not objects that will - // make the linker error. So we must remove those bits from the .rlib before - // linking it. - fn link_sanitizer_runtime<'a, B: ArchiveBuilder<'a>>( - cmd: &mut dyn Linker, - sess: &'a Session, - codegen_results: &CodegenResults, - tmpdir: &Path, - cnum: CrateNum, - ) { - let src = &codegen_results.crate_info.used_crate_source[&cnum]; - let cratepath = &src.rlib.as_ref().unwrap().0; - - if sess.target.target.options.is_like_osx { - // On Apple platforms, the sanitizer is always built as a dylib, and - // LLVM will link to `@rpath/*.dylib`, so we need to specify an - // rpath to the library as well (the rpath should be absolute, see - // PR #41352 for details). - // - // FIXME: Remove this logic into librustc_*san once Cargo supports it - let rpath = cratepath.parent().unwrap(); - let rpath = rpath.to_str().expect("non-utf8 component in path"); - cmd.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]); - } - - let dst = tmpdir.join(cratepath.file_name().unwrap()); - let mut archive = ::new(sess, &dst, Some(cratepath)); - archive.update_symbols(); - - for f in archive.src_files() { - if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME { - archive.remove_file(&f); - } - } - - archive.build(); - - cmd.link_whole_rlib(&dst); - } - // Adds the static "rlib" versions of all crates to the command line. // There's a bit of magic which happens here specifically related to LTO and // dynamic libraries. Specifically: diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index b21715fadfe6f..7ccc367be2560 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -6,7 +6,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob use rustc::hir::map::Definitions; use rustc::middle::cstore::DepKind; use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; -use rustc::session::config::{self, Sanitizer}; +use rustc::session::config; use rustc::session::search_paths::PathKind; use rustc::session::{CrateDisambiguator, Session}; use rustc::ty::TyCtxt; @@ -674,108 +674,6 @@ impl<'a> CrateLoader<'a> { self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } - fn inject_sanitizer_runtime(&mut self) { - if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { - // Sanitizers can only be used on some tested platforms with - // executables linked to `std` - const ASAN_SUPPORTED_TARGETS: &[&str] = - &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; - const TSAN_SUPPORTED_TARGETS: &[&str] = - &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; - const LSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; - const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; - - let supported_targets = match *sanitizer { - Sanitizer::Address => ASAN_SUPPORTED_TARGETS, - Sanitizer::Thread => TSAN_SUPPORTED_TARGETS, - Sanitizer::Leak => LSAN_SUPPORTED_TARGETS, - Sanitizer::Memory => MSAN_SUPPORTED_TARGETS, - }; - if !supported_targets.contains(&&*self.sess.opts.target_triple.triple()) { - self.sess.err(&format!( - "{:?}Sanitizer only works with the `{}` target", - sanitizer, - supported_targets.join("` or `") - )); - return; - } - - // firstyear 2017 - during testing I was unable to access an OSX machine - // to make this work on different crate types. As a result, today I have - // only been able to test and support linux as a target. - if self.sess.opts.target_triple.triple() == "x86_64-unknown-linux-gnu" { - if !self.sess.crate_types.borrow().iter().all(|ct| { - match *ct { - // Link the runtime - config::CrateType::Executable => true, - // This crate will be compiled with the required - // instrumentation pass - config::CrateType::Staticlib - | config::CrateType::Rlib - | config::CrateType::Dylib - | config::CrateType::Cdylib => false, - _ => { - self.sess.err(&format!( - "Only executables, staticlibs, \ - cdylibs, dylibs and rlibs can be compiled with \ - `-Z sanitizer`" - )); - false - } - } - }) { - return; - } - } else { - if !self.sess.crate_types.borrow().iter().all(|ct| { - match *ct { - // Link the runtime - config::CrateType::Executable => true, - // This crate will be compiled with the required - // instrumentation pass - config::CrateType::Rlib => false, - _ => { - self.sess.err(&format!( - "Only executables and rlibs can be \ - compiled with `-Z sanitizer`" - )); - false - } - } - }) { - return; - } - } - - let mut uses_std = false; - self.cstore.iter_crate_data(|_, data| { - if data.name() == sym::std { - uses_std = true; - } - }); - - if uses_std { - let name = Symbol::intern(match sanitizer { - Sanitizer::Address => "rustc_asan", - Sanitizer::Leak => "rustc_lsan", - Sanitizer::Memory => "rustc_msan", - Sanitizer::Thread => "rustc_tsan", - }); - info!("loading sanitizer: {}", name); - - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None); - let data = self.cstore.get_crate_data(cnum); - - // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime - if !data.is_sanitizer_runtime() { - self.sess.err(&format!("the crate `{}` is not a sanitizer runtime", name)); - } - } else { - self.sess.err("Must link std to be compiled with `-Z sanitizer`"); - } - } - } - fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { info!("loading profiler"); @@ -927,7 +825,6 @@ impl<'a> CrateLoader<'a> { } pub fn postprocess(&mut self, krate: &ast::Crate) { - self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index dba5b9f3f14c2..d979247b46d3a 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -1124,6 +1124,32 @@ fn validate_commandline_args_with_session_available(sess: &Session) { See https://github.com/rust-lang/rust/issues/61002 for details.", ); } + + // Sanitizers can only be used on some tested platforms. + if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer { + const ASAN_SUPPORTED_TARGETS: &[&str] = + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; + const TSAN_SUPPORTED_TARGETS: &[&str] = + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; + const LSAN_SUPPORTED_TARGETS: &[&str] = + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; + const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; + + let supported_targets = match *sanitizer { + Sanitizer::Address => ASAN_SUPPORTED_TARGETS, + Sanitizer::Thread => TSAN_SUPPORTED_TARGETS, + Sanitizer::Leak => LSAN_SUPPORTED_TARGETS, + Sanitizer::Memory => MSAN_SUPPORTED_TARGETS, + }; + + if !supported_targets.contains(&&*sess.opts.target_triple.triple()) { + sess.err(&format!( + "{:?}Sanitizer only works with the `{}` target", + sanitizer, + supported_targets.join("` or `") + )); + } + } } /// Hash value constructed out of all the `-C metadata` arguments passed to the diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile index 3a377c32993d5..7f5e9049b2f77 100644 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-address/Makefile @@ -23,7 +23,7 @@ endif endif all: - $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan + $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) rustc_rt.asan # Verify that stack buffer overflow is detected: $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow # Verify that variable name is included in address sanitizer report: diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile deleted file mode 100644 index 9581ac565ea02..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# needs-sanitizer-support - --include ../tools.mk - -# NOTE the address sanitizer only supports x86_64 linux and macOS - -ifeq ($(TARGET),x86_64-apple-darwin) -EXTRA_RUSTFLAG=-C rpath -else -ifeq ($(TARGET),x86_64-unknown-linux-gnu) -EXTRA_RUSTFLAG= -endif -endif - -all: - $(RUSTC) -Z sanitizer=address --crate-type proc-macro --target $(TARGET) hello.rs 2>&1 | $(CGREP) '-Z sanitizer' diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs deleted file mode 100644 index e7a11a969c037..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile index df8afee15ce07..2a23f0fe3d4ef 100644 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile @@ -2,4 +2,4 @@ all: $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | \ - $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` target' + $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target' diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile index 101e8272ab91e..d8598b8ac93f9 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-leak/Makefile @@ -7,5 +7,5 @@ # FIXME(#46126) ThinLTO for libstd broke this test all: - $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) librustc_lsan + $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile index f5787903a2b59..8bc9df1b4baeb 100644 --- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-memory/Makefile @@ -5,7 +5,7 @@ # only-x86_64 all: - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan + $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) rustc_rt.msan $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) librustc_msan + $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) rustc_rt.msan $(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value From ae57259403957ce31760b1fe83ec55343155696f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 7 Nov 2019 00:00:00 +0000 Subject: [PATCH 0089/1253] Add bootstrap step for building sanitizer runtimes --- src/bootstrap/builder.rs | 1 + src/bootstrap/check.rs | 2 +- src/bootstrap/compile.rs | 80 +++++++++++++-------------- src/bootstrap/doc.rs | 2 +- src/bootstrap/native.rs | 115 +++++++++++++++++++++++++++++++++++++++ src/bootstrap/test.rs | 2 +- 6 files changed, 159 insertions(+), 43 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 3a14b3e71c477..00c8e72a8f685 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -343,6 +343,7 @@ impl<'a> Builder<'a> { tool::Rustdoc, tool::Clippy, native::Llvm, + native::Sanitizers, tool::Rustfmt, tool::Miri, native::Lld diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index d4016f16fa9d3..b76515763fbdb 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -45,7 +45,7 @@ impl Step for Std { let compiler = builder.compiler(0, builder.config.build); let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind)); - std_cargo(builder, &compiler, target, &mut cargo); + std_cargo(builder, target, &mut cargo); builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target)); run_cargo( diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 7f0bb5813a4a0..eced03506ab9f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -87,7 +87,7 @@ impl Step for Std { target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter()); let mut cargo = builder.cargo(compiler, Mode::Std, target, "build"); - std_cargo(builder, &compiler, target, &mut cargo); + std_cargo(builder, target, &mut cargo); builder.info(&format!( "Building stage{} std artifacts ({} -> {})", @@ -153,17 +153,18 @@ fn copy_third_party_objects( copy_and_stamp(Path::new(&src), "libunwind.a"); } + if builder.config.sanitizers && compiler.stage != 0 { + // The sanitizers are only copied in stage1 or above, + // to avoid creating dependency on LLVM. + target_deps.extend(copy_sanitizers(builder, &compiler, target)); + } + target_deps } /// Configure cargo to compile the standard library, adding appropriate env vars /// and such. -pub fn std_cargo( - builder: &Builder<'_>, - compiler: &Compiler, - target: Interned, - cargo: &mut Cargo, -) { +pub fn std_cargo(builder: &Builder<'_>, target: Interned, cargo: &mut Cargo) { if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } @@ -206,19 +207,6 @@ pub fn std_cargo( let mut features = builder.std_features(); features.push_str(&compiler_builtins_c_feature); - if compiler.stage != 0 && builder.config.sanitizers { - // This variable is used by the sanitizer runtime crates, e.g. - // rustc_lsan, to build the sanitizer runtime from C code - // When this variable is missing, those crates won't compile the C code, - // so we don't set this variable during stage0 where llvm-config is - // missing - // We also only build the runtimes when --enable-sanitizers (or its - // config.toml equivalent) is used - let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); - cargo.env("LLVM_CONFIG", llvm_config); - cargo.env("RUSTC_BUILD_SANITIZERS", "1"); - } - cargo .arg("--features") .arg(features) @@ -276,31 +264,43 @@ impl Step for StdLink { let libdir = builder.sysroot_libdir(target_compiler, target); let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); - - if builder.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" { - // The sanitizers are only built in stage1 or above, so the dylibs will - // be missing in stage0 and causes panic. See the `std()` function above - // for reason why the sanitizers are not built in stage0. - copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir); - } } } -fn copy_apple_sanitizer_dylibs( +/// Copies sanitizer runtime libraries into target libdir. +fn copy_sanitizers( builder: &Builder<'_>, - native_dir: &Path, - platform: &str, - into: &Path, -) { - for &sanitizer in &["asan", "tsan"] { - let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform); - let mut src_path = native_dir.join(sanitizer); - src_path.push("build"); - src_path.push("lib"); - src_path.push("darwin"); - src_path.push(&filename); - builder.copy(&src_path, &into.join(filename)); + compiler: &Compiler, + target: Interned, +) -> Vec { + let runtimes: Vec = builder.ensure(native::Sanitizers { target }); + + if builder.config.dry_run { + return Vec::new(); + } + + let mut target_deps = Vec::new(); + let libdir = builder.sysroot_libdir(*compiler, target); + + for runtime in &runtimes { + let dst = libdir.join(&runtime.name); + builder.copy(&runtime.path, &dst); + + if target == "x86_64-apple-darwin" { + // Update the library install name reflect the fact it has been renamed. + let status = Command::new("install_name_tool") + .arg("-id") + .arg(format!("@rpath/{}", runtime.name)) + .arg(&dst) + .status() + .expect("failed to execute `install_name_tool`"); + assert!(status.success()); + } + + target_deps.push(dst); } + + target_deps } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 8cd7fc2c17257..4d18199dc8ac0 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -449,7 +449,7 @@ impl Step for Std { let run_cargo_rustdoc_for = |package: &str| { let mut cargo = builder.cargo(compiler, Mode::Std, target, "rustdoc"); - compile::std_cargo(builder, &compiler, target, &mut cargo); + compile::std_cargo(builder, target, &mut cargo); // Keep a whitelist so we do not build internal stdlib crates, these will be // build by the rustc step later if enabled. diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 2a4e9903e5527..ce977f1bbc44e 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -546,3 +546,118 @@ impl Step for TestHelpers { .compile("rust_test_helpers"); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct Sanitizers { + pub target: Interned, +} + +impl Step for Sanitizers { + type Output = Vec; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/llvm-project/compiler-rt").path("src/sanitizers") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Sanitizers { target: run.target }); + } + + /// Builds sanitizer runtime libraries. + fn run(self, builder: &Builder<'_>) -> Self::Output { + let compiler_rt_dir = builder.src.join("src/llvm-project/compiler-rt"); + if !compiler_rt_dir.exists() { + return Vec::new(); + } + + let out_dir = builder.native_dir(self.target).join("sanitizers"); + let runtimes = supported_sanitizers(&out_dir, self.target); + if runtimes.is_empty() { + return runtimes; + } + + let llvm_config = builder.ensure(Llvm { target: builder.config.build }); + if builder.config.dry_run { + return runtimes; + } + + let done_stamp = out_dir.join("sanitizers-finished-building"); + if done_stamp.exists() { + builder.info(&format!( + "Assuming that sanitizers rebuild is not necessary. \ + To force a rebuild, remove the file `{}`", + done_stamp.display() + )); + return runtimes; + } + + builder.info(&format!("Building sanitizers for {}", self.target)); + let _time = util::timeit(&builder); + + let mut cfg = cmake::Config::new(&compiler_rt_dir); + cfg.target(&self.target); + cfg.host(&builder.config.build); + cfg.profile("Release"); + + cfg.define("CMAKE_C_COMPILER_TARGET", self.target); + cfg.define("COMPILER_RT_BUILD_BUILTINS", "OFF"); + cfg.define("COMPILER_RT_BUILD_CRT", "OFF"); + cfg.define("COMPILER_RT_BUILD_LIBFUZZER", "OFF"); + cfg.define("COMPILER_RT_BUILD_PROFILE", "OFF"); + cfg.define("COMPILER_RT_BUILD_SANITIZERS", "ON"); + cfg.define("COMPILER_RT_BUILD_XRAY", "OFF"); + cfg.define("COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"); + cfg.define("COMPILER_RT_USE_LIBCXX", "OFF"); + cfg.define("LLVM_CONFIG_PATH", &llvm_config); + + t!(fs::create_dir_all(&out_dir)); + cfg.out_dir(out_dir); + + for runtime in &runtimes { + cfg.build_target(&runtime.cmake_target); + cfg.build(); + } + + t!(fs::write(&done_stamp, b"")); + + runtimes + } +} + +#[derive(Clone, Debug)] +pub struct SanitizerRuntime { + /// CMake target used to build the runtime. + pub cmake_target: String, + /// Path to the built runtime library. + pub path: PathBuf, + /// Library filename that will be used rustc. + pub name: String, +} + +/// Returns sanitizers available on a given target. +fn supported_sanitizers(out_dir: &Path, target: Interned) -> Vec { + let mut result = Vec::new(); + match &*target { + "x86_64-apple-darwin" => { + for s in &["asan", "lsan", "tsan"] { + result.push(SanitizerRuntime { + cmake_target: format!("clang_rt.{}_osx_dynamic", s), + path: out_dir + .join(&format!("build/lib/darwin/libclang_rt.{}_osx_dynamic.dylib", s)), + name: format!("librustc_rt.{}.dylib", s), + }); + } + } + "x86_64-unknown-linux-gnu" => { + for s in &["asan", "lsan", "msan", "tsan"] { + result.push(SanitizerRuntime { + cmake_target: format!("clang_rt.{}-x86_64", s), + path: out_dir.join(&format!("build/lib/linux/libclang_rt.{}-x86_64.a", s)), + name: format!("librustc_rt.{}.a", s), + }); + } + } + _ => {} + } + result +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b5c8de057d017..10e07489e1212 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1659,7 +1659,7 @@ impl Step for Crate { let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand()); match mode { Mode::Std => { - compile::std_cargo(builder, &compiler, target, &mut cargo); + compile::std_cargo(builder, target, &mut cargo); } Mode::Rustc => { builder.ensure(compile::Rustc { compiler, target }); From bcab59ed8341a585e7cac5475bc2a41e1f96defa Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 05:32:17 +0100 Subject: [PATCH 0090/1253] lowering: simplify HoFs --- src/librustc_ast_lowering/item.rs | 7 ++-- src/librustc_ast_lowering/lib.rs | 60 +++++++++++++------------------ 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index a5892a22d9dfa..7aef4b11ae3f9 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -26,12 +26,9 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { } impl<'a, 'lowering, 'hir> ItemLowerer<'a, 'lowering, 'hir> { - fn with_trait_impl_ref(&mut self, trait_impl_ref: &Option, f: F) - where - F: FnOnce(&mut Self), - { + fn with_trait_impl_ref(&mut self, impl_ref: &Option, f: impl FnOnce(&mut Self)) { let old = self.lctx.is_in_trait_impl; - self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { false } else { true }; + self.lctx.is_in_trait_impl = if let &None = impl_ref { false } else { true }; f(self); self.lctx.is_in_trait_impl = old; } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 385153b62ce82..5b68018683c47 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -433,10 +433,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn with_hir_id_owner(&mut self, owner: Option, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_hir_id_owner( + &mut self, + owner: Option, + f: impl FnOnce(&mut Self) -> T, + ) -> T { let old = mem::replace(&mut self.hir_id_owner, owner); let r = f(self); self.hir_id_owner = old; @@ -577,10 +578,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lowered } - fn lower_node_id_generic(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> hir::HirId - where - F: FnOnce(&mut Self) -> hir::HirId, - { + fn lower_node_id_generic( + &mut self, + ast_node_id: NodeId, + alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId, + ) -> hir::HirId { if ast_node_id == DUMMY_NODE_ID { return hir::DUMMY_HIR_ID; } @@ -604,10 +606,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn with_hir_id_owner(&mut self, owner: NodeId, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_hir_id_owner(&mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { let counter = self .item_local_id_counters .insert(owner, HIR_ID_COUNTER_LOCKED) @@ -736,15 +735,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Presuming that in-band lifetimes are enabled, then /// `self.anonymous_lifetime_mode` will be updated to match the /// parameter while `f` is running (and restored afterwards). - fn collect_in_band_defs( + fn collect_in_band_defs( &mut self, parent_id: DefId, anonymous_lifetime_mode: AnonymousLifetimeMode, - f: F, - ) -> (Vec>, T) - where - F: FnOnce(&mut Self) -> (Vec>, T), - { + f: impl FnOnce(&mut Self) -> (Vec>, T), + ) -> (Vec>, T) { assert!(!self.is_collecting_in_band_lifetimes); assert!(self.lifetimes_to_define.is_empty()); let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode; @@ -847,10 +843,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // This is used to track which lifetimes have already been defined, and // which are new in-band lifetimes that need to have a definition created // for them. - fn with_in_scope_lifetime_defs(&mut self, params: &[GenericParam], f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_in_scope_lifetime_defs( + &mut self, + params: &[GenericParam], + f: impl FnOnce(&mut Self) -> T, + ) -> T { let old_len = self.in_scope_lifetimes.len(); let lt_def_names = params.iter().filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => Some(ParamName::Plain(param.ident.modern())), @@ -870,16 +867,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Presuming that in-band lifetimes are enabled, then /// `self.anonymous_lifetime_mode` will be updated to match the /// parameter while `f` is running (and restored afterwards). - fn add_in_band_defs( + fn add_in_band_defs( &mut self, generics: &Generics, parent_id: DefId, anonymous_lifetime_mode: AnonymousLifetimeMode, - f: F, - ) -> (hir::Generics<'hir>, T) - where - F: FnOnce(&mut Self, &mut Vec>) -> T, - { + f: impl FnOnce(&mut Self, &mut Vec>) -> T, + ) -> (hir::Generics<'hir>, T) { let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(&generics.params, |this| { this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| { @@ -917,10 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (lowered_generics, res) } - fn with_dyn_type_scope(&mut self, in_scope: bool, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_dyn_type_scope(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T { let was_in_dyn_type = self.is_in_dyn_type; self.is_in_dyn_type = in_scope; @@ -931,10 +922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { result } - fn with_new_scopes(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_new_scopes(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; From 956265d55b7c2039eaa2476cfc3b370ead322ce4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 05:35:18 +0100 Subject: [PATCH 0091/1253] lowering: elide some lifetimes --- src/librustc_ast_lowering/item.rs | 4 ++-- src/librustc_ast_lowering/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 7aef4b11ae3f9..e8d6c65e8de7d 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -25,7 +25,7 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>, } -impl<'a, 'lowering, 'hir> ItemLowerer<'a, 'lowering, 'hir> { +impl ItemLowerer<'_, '_, '_> { fn with_trait_impl_ref(&mut self, impl_ref: &Option, f: impl FnOnce(&mut Self)) { let old = self.lctx.is_in_trait_impl; self.lctx.is_in_trait_impl = if let &None = impl_ref { false } else { true }; @@ -34,7 +34,7 @@ impl<'a, 'lowering, 'hir> ItemLowerer<'a, 'lowering, 'hir> { } } -impl<'a, 'lowering, 'hir> Visitor<'a> for ItemLowerer<'a, 'lowering, 'hir> { +impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) { let hir_id = self.lctx.lower_node_id(n); diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 5b68018683c47..c4b992243690f 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -445,7 +445,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - impl<'tcx, 'lowering, 'hir> Visitor<'tcx> for MiscCollector<'tcx, 'lowering, 'hir> { + impl<'tcx> Visitor<'tcx> for MiscCollector<'tcx, '_, '_> { fn visit_pat(&mut self, p: &'tcx Pat) { if let PatKind::Paren(..) | PatKind::Rest = p.kind { // Doesn't generate a HIR node From f75ccdef10148637165eec034d9346cbb82e0119 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 05:51:59 +0100 Subject: [PATCH 0092/1253] extract pattern lowering -> pat.rs --- src/librustc_ast_lowering/lib.rs | 249 +----------------------------- src/librustc_ast_lowering/pat.rs | 253 +++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 246 deletions(-) create mode 100644 src/librustc_ast_lowering/pat.rs diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index c4b992243690f..658bcb26ecfcd 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -33,6 +33,7 @@ //! in the HIR, especially for multiple identifiers. #![feature(array_value_iter)] +#![feature(crate_visibility_modifier)] use rustc::arena::Arena; use rustc::dep_graph::DepGraph; @@ -58,14 +59,13 @@ use rustc_session::config::nightly_options; use rustc_session::node_id::NodeMap; use rustc_session::Session; use rustc_span::hygiene::ExpnId; -use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind, Spanned}; +use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast; use syntax::ast::*; use syntax::attr; use syntax::print::pprust; -use syntax::ptr::P as AstP; use syntax::sess::ParseSess; use syntax::token::{self, Nonterminal, Token}; use syntax::tokenstream::{TokenStream, TokenTree}; @@ -86,6 +86,7 @@ macro_rules! arena_vec { mod expr; mod item; +mod pat; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; @@ -2636,250 +2637,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.expr_block(block, AttrVec::new()) } - fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { - let node = match p.kind { - PatKind::Wild => hir::PatKind::Wild, - PatKind::Ident(ref binding_mode, ident, ref sub) => { - let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); - let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub); - node - } - PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)), - PatKind::TupleStruct(ref path, ref pats) => { - let qpath = self.lower_qpath( - p.id, - &None, - path, - ParamMode::Optional, - ImplTraitContext::disallowed(), - ); - let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); - hir::PatKind::TupleStruct(qpath, pats, ddpos) - } - PatKind::Or(ref pats) => { - hir::PatKind::Or(self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x)))) - } - PatKind::Path(ref qself, ref path) => { - let qpath = self.lower_qpath( - p.id, - qself, - path, - ParamMode::Optional, - ImplTraitContext::disallowed(), - ); - hir::PatKind::Path(qpath) - } - PatKind::Struct(ref path, ref fields, etc) => { - let qpath = self.lower_qpath( - p.id, - &None, - path, - ParamMode::Optional, - ImplTraitContext::disallowed(), - ); - - let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat { - hir_id: self.next_id(), - ident: f.ident, - pat: self.lower_pat(&f.pat), - is_shorthand: f.is_shorthand, - span: f.span, - })); - hir::PatKind::Struct(qpath, fs, etc) - } - PatKind::Tuple(ref pats) => { - let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); - hir::PatKind::Tuple(pats, ddpos) - } - PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), - PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl), - PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range( - self.lower_expr(e1), - self.lower_expr(e2), - self.lower_range_end(end), - ), - PatKind::Slice(ref pats) => self.lower_pat_slice(pats), - PatKind::Rest => { - // If we reach here the `..` pattern is not semantically allowed. - self.ban_illegal_rest_pat(p.span) - } - PatKind::Paren(ref inner) => return self.lower_pat(inner), - PatKind::Mac(_) => panic!("Shouldn't exist here"), - }; - - self.pat_with_node_id_of(p, node) - } - - fn lower_pat_tuple( - &mut self, - pats: &[AstP], - ctx: &str, - ) -> (&'hir [&'hir hir::Pat<'hir>], Option) { - let mut elems = Vec::with_capacity(pats.len()); - let mut rest = None; - - let mut iter = pats.iter().enumerate(); - for (idx, pat) in iter.by_ref() { - // Interpret the first `..` pattern as a sub-tuple pattern. - // Note that unlike for slice patterns, - // where `xs @ ..` is a legal sub-slice pattern, - // it is not a legal sub-tuple pattern. - if pat.is_rest() { - rest = Some((idx, pat.span)); - break; - } - // It was not a sub-tuple pattern so lower it normally. - elems.push(self.lower_pat(pat)); - } - - for (_, pat) in iter { - // There was a previous sub-tuple pattern; make sure we don't allow more... - if pat.is_rest() { - // ...but there was one again, so error. - self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx); - } else { - elems.push(self.lower_pat(pat)); - } - } - - (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos)) - } - - /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into - /// `hir::PatKind::Slice(before, slice, after)`. - /// - /// When encountering `($binding_mode $ident @)? ..` (`slice`), - /// this is interpreted as a sub-slice pattern semantically. - /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. - fn lower_pat_slice(&mut self, pats: &[AstP]) -> hir::PatKind<'hir> { - let mut before = Vec::new(); - let mut after = Vec::new(); - let mut slice = None; - let mut prev_rest_span = None; - - let mut iter = pats.iter(); - // Lower all the patterns until the first occurence of a sub-slice pattern. - for pat in iter.by_ref() { - match pat.kind { - // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. - PatKind::Rest => { - prev_rest_span = Some(pat.span); - slice = Some(self.pat_wild_with_node_id_of(pat)); - break; - } - // Found a sub-slice pattern `$binding_mode $ident @ ..`. - // Record, lower it to `$binding_mode $ident @ _`, and stop here. - PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { - prev_rest_span = Some(sub.span); - let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); - let node = self.lower_pat_ident(pat, bm, ident, lower_sub); - slice = Some(self.pat_with_node_id_of(pat, node)); - break; - } - // It was not a subslice pattern so lower it normally. - _ => before.push(self.lower_pat(pat)), - } - } - - // Lower all the patterns after the first sub-slice pattern. - for pat in iter { - // There was a previous subslice pattern; make sure we don't allow more. - let rest_span = match pat.kind { - PatKind::Rest => Some(pat.span), - PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => { - // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs. - after.push(self.pat_wild_with_node_id_of(pat)); - Some(sub.span) - } - _ => None, - }; - if let Some(rest_span) = rest_span { - // We have e.g., `[a, .., b, ..]`. That's no good, error! - self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice"); - } else { - // Lower the pattern normally. - after.push(self.lower_pat(pat)); - } - } - - hir::PatKind::Slice( - self.arena.alloc_from_iter(before), - slice, - self.arena.alloc_from_iter(after), - ) - } - - fn lower_pat_ident( - &mut self, - p: &Pat, - binding_mode: &BindingMode, - ident: Ident, - lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>, - ) -> hir::PatKind<'hir> { - match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { - // `None` can occur in body-less function signatures - res @ None | res @ Some(Res::Local(_)) => { - let canonical_id = match res { - Some(Res::Local(id)) => id, - _ => p.id, - }; - - hir::PatKind::Binding( - self.lower_binding_mode(binding_mode), - self.lower_node_id(canonical_id), - ident, - lower_sub(self), - ) - } - Some(res) => hir::PatKind::Path(hir::QPath::Resolved( - None, - self.arena.alloc(hir::Path { - span: ident.span, - res: self.lower_res(res), - segments: arena_vec![self; hir::PathSegment::from_ident(ident)], - }), - )), - } - } - - fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { - self.pat_with_node_id_of(p, hir::PatKind::Wild) - } - - /// Construct a `Pat` with the `HirId` of `p.id` lowered. - fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { - self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span }) - } - - /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. - fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { - self.diagnostic() - .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) - .span_label(sp, &format!("can only be used once per {} pattern", ctx)) - .span_label(prev_sp, "previously used here") - .emit(); - } - - /// Used to ban the `..` pattern in places it shouldn't be semantically. - fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> { - self.diagnostic() - .struct_span_err(sp, "`..` patterns are not allowed here") - .note("only allowed in tuple, tuple struct, and slice patterns") - .emit(); - - // We're not in a list context so `..` can be reasonably treated - // as `_` because it should always be valid and roughly matches the - // intent of `..` (notice that the rest of a single slot is that slot). - hir::PatKind::Wild - } - - fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd { - match *e { - RangeEnd::Included(_) => hir::RangeEnd::Included, - RangeEnd::Excluded => hir::RangeEnd::Excluded, - } - } - fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { self.with_new_scopes(|this| hir::AnonConst { hir_id: this.lower_node_id(c.id), diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs new file mode 100644 index 0000000000000..3a3ffd7560bab --- /dev/null +++ b/src/librustc_ast_lowering/pat.rs @@ -0,0 +1,253 @@ +use super::{ImplTraitContext, LoweringContext, ParamMode}; + +use rustc::hir; +use rustc::hir::def::Res; +use rustc_span::{source_map::Spanned, Span}; +use syntax::ast::*; +use syntax::ptr::P; + +impl<'a, 'hir> LoweringContext<'a, 'hir> { + crate fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { + let node = match p.kind { + PatKind::Wild => hir::PatKind::Wild, + PatKind::Ident(ref binding_mode, ident, ref sub) => { + let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); + let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub); + node + } + PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)), + PatKind::TupleStruct(ref path, ref pats) => { + let qpath = self.lower_qpath( + p.id, + &None, + path, + ParamMode::Optional, + ImplTraitContext::disallowed(), + ); + let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); + hir::PatKind::TupleStruct(qpath, pats, ddpos) + } + PatKind::Or(ref pats) => { + hir::PatKind::Or(self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x)))) + } + PatKind::Path(ref qself, ref path) => { + let qpath = self.lower_qpath( + p.id, + qself, + path, + ParamMode::Optional, + ImplTraitContext::disallowed(), + ); + hir::PatKind::Path(qpath) + } + PatKind::Struct(ref path, ref fields, etc) => { + let qpath = self.lower_qpath( + p.id, + &None, + path, + ParamMode::Optional, + ImplTraitContext::disallowed(), + ); + + let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat { + hir_id: self.next_id(), + ident: f.ident, + pat: self.lower_pat(&f.pat), + is_shorthand: f.is_shorthand, + span: f.span, + })); + hir::PatKind::Struct(qpath, fs, etc) + } + PatKind::Tuple(ref pats) => { + let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); + hir::PatKind::Tuple(pats, ddpos) + } + PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), + PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl), + PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range( + self.lower_expr(e1), + self.lower_expr(e2), + self.lower_range_end(end), + ), + PatKind::Slice(ref pats) => self.lower_pat_slice(pats), + PatKind::Rest => { + // If we reach here the `..` pattern is not semantically allowed. + self.ban_illegal_rest_pat(p.span) + } + PatKind::Paren(ref inner) => return self.lower_pat(inner), + PatKind::Mac(_) => panic!("Shouldn't exist here"), + }; + + self.pat_with_node_id_of(p, node) + } + + fn lower_pat_tuple( + &mut self, + pats: &[P], + ctx: &str, + ) -> (&'hir [&'hir hir::Pat<'hir>], Option) { + let mut elems = Vec::with_capacity(pats.len()); + let mut rest = None; + + let mut iter = pats.iter().enumerate(); + for (idx, pat) in iter.by_ref() { + // Interpret the first `..` pattern as a sub-tuple pattern. + // Note that unlike for slice patterns, + // where `xs @ ..` is a legal sub-slice pattern, + // it is not a legal sub-tuple pattern. + if pat.is_rest() { + rest = Some((idx, pat.span)); + break; + } + // It was not a sub-tuple pattern so lower it normally. + elems.push(self.lower_pat(pat)); + } + + for (_, pat) in iter { + // There was a previous sub-tuple pattern; make sure we don't allow more... + if pat.is_rest() { + // ...but there was one again, so error. + self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx); + } else { + elems.push(self.lower_pat(pat)); + } + } + + (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos)) + } + + /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into + /// `hir::PatKind::Slice(before, slice, after)`. + /// + /// When encountering `($binding_mode $ident @)? ..` (`slice`), + /// this is interpreted as a sub-slice pattern semantically. + /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. + fn lower_pat_slice(&mut self, pats: &[P]) -> hir::PatKind<'hir> { + let mut before = Vec::new(); + let mut after = Vec::new(); + let mut slice = None; + let mut prev_rest_span = None; + + let mut iter = pats.iter(); + // Lower all the patterns until the first occurence of a sub-slice pattern. + for pat in iter.by_ref() { + match pat.kind { + // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. + PatKind::Rest => { + prev_rest_span = Some(pat.span); + slice = Some(self.pat_wild_with_node_id_of(pat)); + break; + } + // Found a sub-slice pattern `$binding_mode $ident @ ..`. + // Record, lower it to `$binding_mode $ident @ _`, and stop here. + PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { + prev_rest_span = Some(sub.span); + let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); + let node = self.lower_pat_ident(pat, bm, ident, lower_sub); + slice = Some(self.pat_with_node_id_of(pat, node)); + break; + } + // It was not a subslice pattern so lower it normally. + _ => before.push(self.lower_pat(pat)), + } + } + + // Lower all the patterns after the first sub-slice pattern. + for pat in iter { + // There was a previous subslice pattern; make sure we don't allow more. + let rest_span = match pat.kind { + PatKind::Rest => Some(pat.span), + PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => { + // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs. + after.push(self.pat_wild_with_node_id_of(pat)); + Some(sub.span) + } + _ => None, + }; + if let Some(rest_span) = rest_span { + // We have e.g., `[a, .., b, ..]`. That's no good, error! + self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice"); + } else { + // Lower the pattern normally. + after.push(self.lower_pat(pat)); + } + } + + hir::PatKind::Slice( + self.arena.alloc_from_iter(before), + slice, + self.arena.alloc_from_iter(after), + ) + } + + fn lower_pat_ident( + &mut self, + p: &Pat, + binding_mode: &BindingMode, + ident: Ident, + lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>, + ) -> hir::PatKind<'hir> { + match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { + // `None` can occur in body-less function signatures + res @ None | res @ Some(Res::Local(_)) => { + let canonical_id = match res { + Some(Res::Local(id)) => id, + _ => p.id, + }; + + hir::PatKind::Binding( + self.lower_binding_mode(binding_mode), + self.lower_node_id(canonical_id), + ident, + lower_sub(self), + ) + } + Some(res) => hir::PatKind::Path(hir::QPath::Resolved( + None, + self.arena.alloc(hir::Path { + span: ident.span, + res: self.lower_res(res), + segments: arena_vec![self; hir::PathSegment::from_ident(ident)], + }), + )), + } + } + + fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { + self.pat_with_node_id_of(p, hir::PatKind::Wild) + } + + /// Construct a `Pat` with the `HirId` of `p.id` lowered. + fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { + self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span }) + } + + /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. + fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { + self.diagnostic() + .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) + .span_label(sp, &format!("can only be used once per {} pattern", ctx)) + .span_label(prev_sp, "previously used here") + .emit(); + } + + /// Used to ban the `..` pattern in places it shouldn't be semantically. + fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> { + self.diagnostic() + .struct_span_err(sp, "`..` patterns are not allowed here") + .note("only allowed in tuple, tuple struct, and slice patterns") + .emit(); + + // We're not in a list context so `..` can be reasonably treated + // as `_` because it should always be valid and roughly matches the + // intent of `..` (notice that the rest of a single slot is that slot). + hir::PatKind::Wild + } + + fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd { + match *e { + RangeEnd::Included(_) => hir::RangeEnd::Included, + RangeEnd::Excluded => hir::RangeEnd::Excluded, + } + } +} From ae6e31b1a339903a92bb03ee085924e3da425356 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 06:54:48 +0100 Subject: [PATCH 0093/1253] move lower_binding_mode -> pat.rs --- src/librustc_ast_lowering/lib.rs | 9 --------- src/librustc_ast_lowering/pat.rs | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 658bcb26ecfcd..3431cf08b6d1e 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -2696,15 +2696,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation { - match *b { - BindingMode::ByValue(Mutability::Not) => hir::BindingAnnotation::Unannotated, - BindingMode::ByRef(Mutability::Not) => hir::BindingAnnotation::Ref, - BindingMode::ByValue(Mutability::Mut) => hir::BindingAnnotation::Mutable, - BindingMode::ByRef(Mutability::Mut) => hir::BindingAnnotation::RefMut, - } - } - fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource { match u { CompilerGenerated => hir::UnsafeSource::CompilerGenerated, diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index 3a3ffd7560bab..4d7d21abc8c94 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -213,6 +213,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation { + match *b { + BindingMode::ByValue(Mutability::Not) => hir::BindingAnnotation::Unannotated, + BindingMode::ByRef(Mutability::Not) => hir::BindingAnnotation::Ref, + BindingMode::ByValue(Mutability::Mut) => hir::BindingAnnotation::Mutable, + BindingMode::ByRef(Mutability::Mut) => hir::BindingAnnotation::RefMut, + } + } + fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { self.pat_with_node_id_of(p, hir::PatKind::Wild) } From 4e6329ec3a7d971972e0a876ae3e6b86ad506d82 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 06:28:43 +0100 Subject: [PATCH 0094/1253] extract path lowering -> path.rs --- src/librustc_ast_lowering/lib.rs | 404 +--------------------------- src/librustc_ast_lowering/pat.rs | 4 +- src/librustc_ast_lowering/path.rs | 421 ++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+), 403 deletions(-) create mode 100644 src/librustc_ast_lowering/path.rs diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 3431cf08b6d1e..3211c57f6bbb0 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! Lowers the AST to the HIR. //! //! Since the AST and HIR are fairly similar, this is mostly a simple procedure, @@ -40,7 +38,7 @@ use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; use rustc::lint; -use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS}; +use rustc::lint::builtin; use rustc::middle::cstore::CrateStore; use rustc::util::captures::Captures; use rustc::util::common::FN_OUTPUT_NAME; @@ -48,7 +46,7 @@ use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_error_codes::*; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIndex, CRATE_DEF_INDEX}; @@ -87,6 +85,7 @@ macro_rules! arena_vec { mod expr; mod item; mod pat; +mod path; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; @@ -1624,403 +1623,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } - fn lower_qpath( - &mut self, - id: NodeId, - qself: &Option, - p: &Path, - param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, - ) -> hir::QPath<'hir> { - let qself_position = qself.as_ref().map(|q| q.position); - let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow())); - - let partial_res = - self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); - - let proj_start = p.segments.len() - partial_res.unresolved_segments(); - let path = self.arena.alloc(hir::Path { - res: self.lower_res(partial_res.base_res()), - segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map( - |(i, segment)| { - let param_mode = match (qself_position, param_mode) { - (Some(j), ParamMode::Optional) if i < j => { - // This segment is part of the trait path in a - // qualified path - one of `a`, `b` or `Trait` - // in `::T::U::method`. - ParamMode::Explicit - } - _ => param_mode, - }; - - // Figure out if this is a type/trait segment, - // which may need lifetime elision performed. - let parent_def_id = |this: &mut Self, def_id: DefId| DefId { - krate: def_id.krate, - index: this.def_key(def_id).parent.expect("missing parent"), - }; - let type_def_id = match partial_res.base_res() { - Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => { - Some(parent_def_id(self, def_id)) - } - Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => { - Some(parent_def_id(self, def_id)) - } - Res::Def(DefKind::Struct, def_id) - | Res::Def(DefKind::Union, def_id) - | Res::Def(DefKind::Enum, def_id) - | Res::Def(DefKind::TyAlias, def_id) - | Res::Def(DefKind::Trait, def_id) - if i + 1 == proj_start => - { - Some(def_id) - } - _ => None, - }; - let parenthesized_generic_args = match partial_res.base_res() { - // `a::b::Trait(Args)` - Res::Def(DefKind::Trait, _) if i + 1 == proj_start => { - ParenthesizedGenericArgs::Ok - } - // `a::b::Trait(Args)::TraitItem` - Res::Def(DefKind::Method, _) - | Res::Def(DefKind::AssocConst, _) - | Res::Def(DefKind::AssocTy, _) - if i + 2 == proj_start => - { - ParenthesizedGenericArgs::Ok - } - // Avoid duplicated errors. - Res::Err => ParenthesizedGenericArgs::Ok, - // An error - _ => ParenthesizedGenericArgs::Err, - }; - - let num_lifetimes = type_def_id.map_or(0, |def_id| { - if let Some(&n) = self.type_def_lifetime_params.get(&def_id) { - return n; - } - assert!(!def_id.is_local()); - let item_generics = self - .resolver - .cstore() - .item_generics_cloned_untracked(def_id, self.sess); - let n = item_generics.own_counts().lifetimes; - self.type_def_lifetime_params.insert(def_id, n); - n - }); - self.lower_path_segment( - p.span, - segment, - param_mode, - num_lifetimes, - parenthesized_generic_args, - itctx.reborrow(), - None, - ) - }, - )), - span: p.span, - }); - - // Simple case, either no projections, or only fully-qualified. - // E.g., `std::mem::size_of` or `::Item`. - if partial_res.unresolved_segments() == 0 { - return hir::QPath::Resolved(qself, path); - } - - // Create the innermost type that we're projecting from. - let mut ty = if path.segments.is_empty() { - // If the base path is empty that means there exists a - // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`. - qself.expect("missing QSelf for ::...") - } else { - // Otherwise, the base path is an implicit `Self` type path, - // e.g., `Vec` in `Vec::new` or `::Item` in - // `::Item::default`. - let new_id = self.next_id(); - self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))) - }; - - // Anything after the base path are associated "extensions", - // out of which all but the last one are associated types, - // e.g., for `std::vec::Vec::::IntoIter::Item::clone`: - // * base path is `std::vec::Vec` - // * "extensions" are `IntoIter`, `Item` and `clone` - // * type nodes are: - // 1. `std::vec::Vec` (created above) - // 2. `>::IntoIter` - // 3. `<>::IntoIter>::Item` - // * final path is `<<>::IntoIter>::Item>::clone` - for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { - let segment = self.arena.alloc(self.lower_path_segment( - p.span, - segment, - param_mode, - 0, - ParenthesizedGenericArgs::Err, - itctx.reborrow(), - None, - )); - let qpath = hir::QPath::TypeRelative(ty, segment); - - // It's finished, return the extension of the right node type. - if i == p.segments.len() - 1 { - return qpath; - } - - // Wrap the associated extension in another type node. - let new_id = self.next_id(); - ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath)); - } - - // We should've returned in the for loop above. - span_bug!( - p.span, - "lower_qpath: no final extension segment in {}..{}", - proj_start, - p.segments.len() - ) - } - - fn lower_path_extra( - &mut self, - res: Res, - p: &Path, - param_mode: ParamMode, - explicit_owner: Option, - ) -> &'hir hir::Path<'hir> { - self.arena.alloc(hir::Path { - res, - segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| { - self.lower_path_segment( - p.span, - segment, - param_mode, - 0, - ParenthesizedGenericArgs::Err, - ImplTraitContext::disallowed(), - explicit_owner, - ) - })), - span: p.span, - }) - } - - fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> &'hir hir::Path<'hir> { - let res = self.expect_full_res(id); - let res = self.lower_res(res); - self.lower_path_extra(res, p, param_mode, None) - } - - fn lower_path_segment( - &mut self, - path_span: Span, - segment: &PathSegment, - param_mode: ParamMode, - expected_lifetimes: usize, - parenthesized_generic_args: ParenthesizedGenericArgs, - itctx: ImplTraitContext<'_, 'hir>, - explicit_owner: Option, - ) -> hir::PathSegment<'hir> { - let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { - let msg = "parenthesized type parameters may only be used with a `Fn` trait"; - match **generic_args { - GenericArgs::AngleBracketed(ref data) => { - self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) - } - GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), - ParenthesizedGenericArgs::Err => { - let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); - err.span_label(data.span, "only `Fn` traits may use parentheses"); - if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { - // Do not suggest going from `Trait()` to `Trait<>` - if data.inputs.len() > 0 { - if let Some(split) = snippet.find('(') { - let trait_name = &snippet[0..split]; - let args = &snippet[split + 1..snippet.len() - 1]; - err.span_suggestion( - data.span, - "use angle brackets instead", - format!("{}<{}>", trait_name, args), - Applicability::MaybeIncorrect, - ); - } - } - }; - err.emit(); - ( - self.lower_angle_bracketed_parameter_data( - &data.as_angle_bracketed_args(), - param_mode, - itctx, - ) - .0, - false, - ) - } - }, - } - } else { - self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx) - }; - - let has_lifetimes = generic_args.args.iter().any(|arg| match arg { - GenericArg::Lifetime(_) => true, - _ => false, - }); - let first_generic_span = generic_args - .args - .iter() - .map(|a| a.span()) - .chain(generic_args.bindings.iter().map(|b| b.span)) - .next(); - if !generic_args.parenthesized && !has_lifetimes { - generic_args.args = self - .elided_path_lifetimes(path_span, expected_lifetimes) - .map(|lt| GenericArg::Lifetime(lt)) - .chain(generic_args.args.into_iter()) - .collect(); - if expected_lifetimes > 0 && param_mode == ParamMode::Explicit { - let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", "); - let no_non_lt_args = generic_args.args.len() == expected_lifetimes; - let no_bindings = generic_args.bindings.is_empty(); - let (incl_angl_brckt, insertion_sp, suggestion) = if no_non_lt_args && no_bindings { - // If there are no (non-implicit) generic args or associated type - // bindings, our suggestion includes the angle brackets. - (true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion)) - } else { - // Otherwise (sorry, this is kind of gross) we need to infer the - // place to splice in the `'_, ` from the generics that do exist. - let first_generic_span = first_generic_span - .expect("already checked that non-lifetime args or bindings exist"); - (false, first_generic_span.shrink_to_lo(), format!("{}, ", anon_lt_suggestion)) - }; - match self.anonymous_lifetime_mode { - // In create-parameter mode we error here because we don't want to support - // deprecated impl elision in new features like impl elision and `async fn`, - // both of which work using the `CreateParameter` mode: - // - // impl Foo for std::cell::Ref // note lack of '_ - // async fn foo(_: std::cell::Ref) { ... } - AnonymousLifetimeMode::CreateParameter => { - let mut err = struct_span_err!( - self.sess, - path_span, - E0726, - "implicit elided lifetime not allowed here" - ); - crate::lint::builtin::add_elided_lifetime_in_path_suggestion( - &self.sess, - &mut err, - expected_lifetimes, - path_span, - incl_angl_brckt, - insertion_sp, - suggestion, - ); - err.emit(); - } - AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => { - self.resolver.lint_buffer().buffer_lint_with_diagnostic( - ELIDED_LIFETIMES_IN_PATHS, - CRATE_NODE_ID, - path_span, - "hidden lifetime parameters in types are deprecated", - builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths( - expected_lifetimes, - path_span, - incl_angl_brckt, - insertion_sp, - suggestion, - ), - ); - } - } - } - } - - let res = self.expect_full_res(segment.id); - let id = if let Some(owner) = explicit_owner { - self.lower_node_id_with_owner(segment.id, owner) - } else { - self.lower_node_id(segment.id) - }; - debug!( - "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", - segment.ident, segment.id, id, - ); - - hir::PathSegment { - ident: segment.ident, - hir_id: Some(id), - res: Some(self.lower_res(res)), - infer_args, - args: if generic_args.is_empty() { - None - } else { - Some(self.arena.alloc(generic_args.into_generic_args(self.arena))) - }, - } - } - - fn lower_angle_bracketed_parameter_data( - &mut self, - data: &AngleBracketedArgs, - param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, - ) -> (GenericArgsCtor<'hir>, bool) { - let &AngleBracketedArgs { ref args, ref constraints, .. } = data; - let has_non_lt_args = args.iter().any(|arg| match arg { - ast::GenericArg::Lifetime(_) => false, - ast::GenericArg::Type(_) => true, - ast::GenericArg::Const(_) => true, - }); - ( - GenericArgsCtor { - args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: self.arena.alloc_from_iter( - constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())), - ), - parenthesized: false, - }, - !has_non_lt_args && param_mode == ParamMode::Optional, - ) - } - - fn lower_parenthesized_parameter_data( - &mut self, - data: &ParenthesizedArgs, - ) -> (GenericArgsCtor<'hir>, bool) { - // Switch to `PassThrough` mode for anonymous lifetimes; this - // means that we permit things like `&Ref`, where `Ref` has - // a hidden lifetime parameter. This is needed for backwards - // compatibility, even in contexts like an impl header where - // we generally don't permit such things (see #51008). - self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| { - let &ParenthesizedArgs { ref inputs, ref output, span } = data; - let inputs = this.arena.alloc_from_iter( - inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())), - ); - let output_ty = match output { - FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()), - FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])), - }; - let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))]; - let binding = hir::TypeBinding { - hir_id: this.next_id(), - ident: Ident::with_dummy_span(FN_OUTPUT_NAME), - span: output_ty.span, - kind: hir::TypeBindingKind::Equality { ty: output_ty }, - }; - ( - GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true }, - false, - ) - }) - } - fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) { let mut ids = SmallVec::<[NodeId; 1]>::new(); if self.sess.features_untracked().impl_trait_in_bindings { diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index 4d7d21abc8c94..cd69646d0c53a 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -1,7 +1,7 @@ use super::{ImplTraitContext, LoweringContext, ParamMode}; -use rustc::hir; -use rustc::hir::def::Res; +use rustc_hir as hir; +use rustc_hir::def::Res; use rustc_span::{source_map::Spanned, Span}; use syntax::ast::*; use syntax::ptr::P; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs new file mode 100644 index 0000000000000..7209dbfdcc78f --- /dev/null +++ b/src/librustc_ast_lowering/path.rs @@ -0,0 +1,421 @@ +use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode}; +use super::{GenericArgsCtor, ParenthesizedGenericArgs}; + +use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS}; +use rustc::span_bug; +use rustc::util::common::FN_OUTPUT_NAME; +use rustc_error_codes::*; +use rustc_errors::{struct_span_err, Applicability}; +use rustc_hir as hir; +use rustc_hir::def::{DefKind, PartialRes, Res}; +use rustc_hir::def_id::DefId; +use rustc_hir::GenericArg; +use rustc_span::Span; +use syntax::ast::{self, *}; + +use log::debug; +use smallvec::smallvec; + +impl<'a, 'hir> LoweringContext<'a, 'hir> { + crate fn lower_qpath( + &mut self, + id: NodeId, + qself: &Option, + p: &Path, + param_mode: ParamMode, + mut itctx: ImplTraitContext<'_, 'hir>, + ) -> hir::QPath<'hir> { + let qself_position = qself.as_ref().map(|q| q.position); + let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow())); + + let partial_res = + self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); + + let proj_start = p.segments.len() - partial_res.unresolved_segments(); + let path = self.arena.alloc(hir::Path { + res: self.lower_res(partial_res.base_res()), + segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map( + |(i, segment)| { + let param_mode = match (qself_position, param_mode) { + (Some(j), ParamMode::Optional) if i < j => { + // This segment is part of the trait path in a + // qualified path - one of `a`, `b` or `Trait` + // in `::T::U::method`. + ParamMode::Explicit + } + _ => param_mode, + }; + + // Figure out if this is a type/trait segment, + // which may need lifetime elision performed. + let parent_def_id = |this: &mut Self, def_id: DefId| DefId { + krate: def_id.krate, + index: this.def_key(def_id).parent.expect("missing parent"), + }; + let type_def_id = match partial_res.base_res() { + Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => { + Some(parent_def_id(self, def_id)) + } + Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => { + Some(parent_def_id(self, def_id)) + } + Res::Def(DefKind::Struct, def_id) + | Res::Def(DefKind::Union, def_id) + | Res::Def(DefKind::Enum, def_id) + | Res::Def(DefKind::TyAlias, def_id) + | Res::Def(DefKind::Trait, def_id) + if i + 1 == proj_start => + { + Some(def_id) + } + _ => None, + }; + let parenthesized_generic_args = match partial_res.base_res() { + // `a::b::Trait(Args)` + Res::Def(DefKind::Trait, _) if i + 1 == proj_start => { + ParenthesizedGenericArgs::Ok + } + // `a::b::Trait(Args)::TraitItem` + Res::Def(DefKind::Method, _) + | Res::Def(DefKind::AssocConst, _) + | Res::Def(DefKind::AssocTy, _) + if i + 2 == proj_start => + { + ParenthesizedGenericArgs::Ok + } + // Avoid duplicated errors. + Res::Err => ParenthesizedGenericArgs::Ok, + // An error + _ => ParenthesizedGenericArgs::Err, + }; + + let num_lifetimes = type_def_id.map_or(0, |def_id| { + if let Some(&n) = self.type_def_lifetime_params.get(&def_id) { + return n; + } + assert!(!def_id.is_local()); + let item_generics = self + .resolver + .cstore() + .item_generics_cloned_untracked(def_id, self.sess); + let n = item_generics.own_counts().lifetimes; + self.type_def_lifetime_params.insert(def_id, n); + n + }); + self.lower_path_segment( + p.span, + segment, + param_mode, + num_lifetimes, + parenthesized_generic_args, + itctx.reborrow(), + None, + ) + }, + )), + span: p.span, + }); + + // Simple case, either no projections, or only fully-qualified. + // E.g., `std::mem::size_of` or `::Item`. + if partial_res.unresolved_segments() == 0 { + return hir::QPath::Resolved(qself, path); + } + + // Create the innermost type that we're projecting from. + let mut ty = if path.segments.is_empty() { + // If the base path is empty that means there exists a + // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`. + qself.expect("missing QSelf for ::...") + } else { + // Otherwise, the base path is an implicit `Self` type path, + // e.g., `Vec` in `Vec::new` or `::Item` in + // `::Item::default`. + let new_id = self.next_id(); + self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))) + }; + + // Anything after the base path are associated "extensions", + // out of which all but the last one are associated types, + // e.g., for `std::vec::Vec::::IntoIter::Item::clone`: + // * base path is `std::vec::Vec` + // * "extensions" are `IntoIter`, `Item` and `clone` + // * type nodes are: + // 1. `std::vec::Vec` (created above) + // 2. `>::IntoIter` + // 3. `<>::IntoIter>::Item` + // * final path is `<<>::IntoIter>::Item>::clone` + for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { + let segment = self.arena.alloc(self.lower_path_segment( + p.span, + segment, + param_mode, + 0, + ParenthesizedGenericArgs::Err, + itctx.reborrow(), + None, + )); + let qpath = hir::QPath::TypeRelative(ty, segment); + + // It's finished, return the extension of the right node type. + if i == p.segments.len() - 1 { + return qpath; + } + + // Wrap the associated extension in another type node. + let new_id = self.next_id(); + ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath)); + } + + // We should've returned in the for loop above. + span_bug!( + p.span, + "lower_qpath: no final extension segment in {}..{}", + proj_start, + p.segments.len() + ) + } + + crate fn lower_path_extra( + &mut self, + res: Res, + p: &Path, + param_mode: ParamMode, + explicit_owner: Option, + ) -> &'hir hir::Path<'hir> { + self.arena.alloc(hir::Path { + res, + segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| { + self.lower_path_segment( + p.span, + segment, + param_mode, + 0, + ParenthesizedGenericArgs::Err, + ImplTraitContext::disallowed(), + explicit_owner, + ) + })), + span: p.span, + }) + } + + crate fn lower_path( + &mut self, + id: NodeId, + p: &Path, + param_mode: ParamMode, + ) -> &'hir hir::Path<'hir> { + let res = self.expect_full_res(id); + let res = self.lower_res(res); + self.lower_path_extra(res, p, param_mode, None) + } + + crate fn lower_path_segment( + &mut self, + path_span: Span, + segment: &PathSegment, + param_mode: ParamMode, + expected_lifetimes: usize, + parenthesized_generic_args: ParenthesizedGenericArgs, + itctx: ImplTraitContext<'_, 'hir>, + explicit_owner: Option, + ) -> hir::PathSegment<'hir> { + let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { + let msg = "parenthesized type parameters may only be used with a `Fn` trait"; + match **generic_args { + GenericArgs::AngleBracketed(ref data) => { + self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) + } + GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { + ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), + ParenthesizedGenericArgs::Err => { + let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); + err.span_label(data.span, "only `Fn` traits may use parentheses"); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { + // Do not suggest going from `Trait()` to `Trait<>` + if data.inputs.len() > 0 { + if let Some(split) = snippet.find('(') { + let trait_name = &snippet[0..split]; + let args = &snippet[split + 1..snippet.len() - 1]; + err.span_suggestion( + data.span, + "use angle brackets instead", + format!("{}<{}>", trait_name, args), + Applicability::MaybeIncorrect, + ); + } + } + }; + err.emit(); + ( + self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + param_mode, + itctx, + ) + .0, + false, + ) + } + }, + } + } else { + self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx) + }; + + let has_lifetimes = generic_args.args.iter().any(|arg| match arg { + GenericArg::Lifetime(_) => true, + _ => false, + }); + let first_generic_span = generic_args + .args + .iter() + .map(|a| a.span()) + .chain(generic_args.bindings.iter().map(|b| b.span)) + .next(); + if !generic_args.parenthesized && !has_lifetimes { + generic_args.args = self + .elided_path_lifetimes(path_span, expected_lifetimes) + .map(|lt| GenericArg::Lifetime(lt)) + .chain(generic_args.args.into_iter()) + .collect(); + if expected_lifetimes > 0 && param_mode == ParamMode::Explicit { + let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", "); + let no_non_lt_args = generic_args.args.len() == expected_lifetimes; + let no_bindings = generic_args.bindings.is_empty(); + let (incl_angl_brckt, insertion_sp, suggestion) = if no_non_lt_args && no_bindings { + // If there are no (non-implicit) generic args or associated type + // bindings, our suggestion includes the angle brackets. + (true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion)) + } else { + // Otherwise (sorry, this is kind of gross) we need to infer the + // place to splice in the `'_, ` from the generics that do exist. + let first_generic_span = first_generic_span + .expect("already checked that non-lifetime args or bindings exist"); + (false, first_generic_span.shrink_to_lo(), format!("{}, ", anon_lt_suggestion)) + }; + match self.anonymous_lifetime_mode { + // In create-parameter mode we error here because we don't want to support + // deprecated impl elision in new features like impl elision and `async fn`, + // both of which work using the `CreateParameter` mode: + // + // impl Foo for std::cell::Ref // note lack of '_ + // async fn foo(_: std::cell::Ref) { ... } + AnonymousLifetimeMode::CreateParameter => { + let mut err = struct_span_err!( + self.sess, + path_span, + E0726, + "implicit elided lifetime not allowed here" + ); + crate::lint::builtin::add_elided_lifetime_in_path_suggestion( + &self.sess, + &mut err, + expected_lifetimes, + path_span, + incl_angl_brckt, + insertion_sp, + suggestion, + ); + err.emit(); + } + AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => { + self.resolver.lint_buffer().buffer_lint_with_diagnostic( + ELIDED_LIFETIMES_IN_PATHS, + CRATE_NODE_ID, + path_span, + "hidden lifetime parameters in types are deprecated", + builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths( + expected_lifetimes, + path_span, + incl_angl_brckt, + insertion_sp, + suggestion, + ), + ); + } + } + } + } + + let res = self.expect_full_res(segment.id); + let id = if let Some(owner) = explicit_owner { + self.lower_node_id_with_owner(segment.id, owner) + } else { + self.lower_node_id(segment.id) + }; + debug!( + "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", + segment.ident, segment.id, id, + ); + + hir::PathSegment { + ident: segment.ident, + hir_id: Some(id), + res: Some(self.lower_res(res)), + infer_args, + args: if generic_args.is_empty() { + None + } else { + Some(self.arena.alloc(generic_args.into_generic_args(self.arena))) + }, + } + } + + fn lower_angle_bracketed_parameter_data( + &mut self, + data: &AngleBracketedArgs, + param_mode: ParamMode, + mut itctx: ImplTraitContext<'_, 'hir>, + ) -> (GenericArgsCtor<'hir>, bool) { + let &AngleBracketedArgs { ref args, ref constraints, .. } = data; + let has_non_lt_args = args.iter().any(|arg| match arg { + ast::GenericArg::Lifetime(_) => false, + ast::GenericArg::Type(_) => true, + ast::GenericArg::Const(_) => true, + }); + ( + GenericArgsCtor { + args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), + bindings: self.arena.alloc_from_iter( + constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())), + ), + parenthesized: false, + }, + !has_non_lt_args && param_mode == ParamMode::Optional, + ) + } + + fn lower_parenthesized_parameter_data( + &mut self, + data: &ParenthesizedArgs, + ) -> (GenericArgsCtor<'hir>, bool) { + // Switch to `PassThrough` mode for anonymous lifetimes; this + // means that we permit things like `&Ref`, where `Ref` has + // a hidden lifetime parameter. This is needed for backwards + // compatibility, even in contexts like an impl header where + // we generally don't permit such things (see #51008). + self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| { + let &ParenthesizedArgs { ref inputs, ref output, span } = data; + let inputs = this.arena.alloc_from_iter( + inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())), + ); + let output_ty = match output { + FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()), + FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])), + }; + let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))]; + let binding = hir::TypeBinding { + hir_id: this.next_id(), + ident: Ident::with_dummy_span(FN_OUTPUT_NAME), + span: output_ty.span, + kind: hir::TypeBindingKind::Equality { ty: output_ty }, + }; + ( + GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true }, + false, + ) + }) + } +} From 2db97ede2702b64426d3209ce8ec787a16cbf4e7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 06:48:51 +0100 Subject: [PATCH 0095/1253] refactor 'Output = $ty' & reduce rustc dep --- src/librustc/traits/project.rs | 3 +-- src/librustc/util/common.rs | 5 ----- src/librustc_ast_lowering/lib.rs | 8 +------- src/librustc_ast_lowering/path.rs | 19 ++++++++++++------- src/librustc_hir/hir.rs | 3 +++ 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 79e1b6444a9b7..738bbd936fea4 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -17,7 +17,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; -use crate::util::common::FN_OUTPUT_NAME; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; @@ -1364,7 +1363,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( projection_ty: ty::ProjectionTy::from_ref_and_name( tcx, trait_ref, - Ident::with_dummy_span(FN_OUTPUT_NAME), + Ident::with_dummy_span(rustc_hir::FN_OUTPUT_NAME), ), ty: ret_type, }); diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 9574685215741..9324b26a09b6f 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -5,14 +5,9 @@ use rustc_data_structures::sync::Lock; use std::fmt::Debug; use std::time::{Duration, Instant}; -use rustc_span::symbol::{sym, Symbol}; - #[cfg(test)] mod tests; -// The name of the associated type for `Fn` return types. -pub const FN_OUTPUT_NAME: Symbol = sym::Output; - pub use errors::ErrorReported; pub fn to_readable_str(mut val: usize) -> String { diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 3211c57f6bbb0..062b093b8e68d 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -41,7 +41,6 @@ use rustc::lint; use rustc::lint::builtin; use rustc::middle::cstore::CrateStore; use rustc::util::captures::Captures; -use rustc::util::common::FN_OUTPUT_NAME; use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; @@ -1978,12 +1977,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // "" let future_params = self.arena.alloc(hir::GenericArgs { args: &[], - bindings: arena_vec![self; hir::TypeBinding { - ident: Ident::with_dummy_span(FN_OUTPUT_NAME), - kind: hir::TypeBindingKind::Equality { ty: output_ty }, - hir_id: self.next_id(), - span, - }], + bindings: arena_vec![self; self.output_ty_binding(span, output_ty)], parenthesized: false, }); diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 7209dbfdcc78f..4f71910b0bfe2 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -3,7 +3,6 @@ use super::{GenericArgsCtor, ParenthesizedGenericArgs}; use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS}; use rustc::span_bug; -use rustc::util::common::FN_OUTPUT_NAME; use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; @@ -406,16 +405,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])), }; let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))]; - let binding = hir::TypeBinding { - hir_id: this.next_id(), - ident: Ident::with_dummy_span(FN_OUTPUT_NAME), - span: output_ty.span, - kind: hir::TypeBindingKind::Equality { ty: output_ty }, - }; + let binding = this.output_ty_binding(output_ty.span, output_ty); ( GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true }, false, ) }) } + + /// An associated type binding `Output = $ty`. + crate fn output_ty_binding( + &mut self, + span: Span, + ty: &'hir hir::Ty<'hir>, + ) -> hir::TypeBinding<'hir> { + let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME); + let kind = hir::TypeBindingKind::Equality { ty }; + hir::TypeBinding { hir_id: self.next_id(), span, ident, kind } + } } diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 2303a85df4acf..603c21188e3ac 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1875,6 +1875,9 @@ pub enum ImplItemKind<'hir> { OpaqueTy(GenericBounds<'hir>), } +// The name of the associated type for `Fn` return types. +pub const FN_OUTPUT_NAME: Symbol = sym::Output; + /// Bind a type to an associated type (i.e., `A = Foo`). /// /// Bindings like `A: Debug` are represented as a special type `A = From 69b1e5cc3d3aea6cccd8567d89cc75288f596c2e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 07:03:46 +0100 Subject: [PATCH 0096/1253] {rustc::util -> rustc_data_structures}::captures --- src/librustc/infer/canonical/query_response.rs | 2 +- src/librustc/infer/outlives/verify.rs | 2 +- src/librustc/lib.rs | 1 - src/librustc/ty/mod.rs | 2 +- src/librustc/ty/sty.rs | 5 ++--- src/librustc_ast_lowering/lib.rs | 4 +++- src/{librustc/util => librustc_data_structures}/captures.rs | 0 src/librustc_data_structures/lib.rs | 1 + src/librustc_metadata/rmeta/decoder.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- 12 files changed, 13 insertions(+), 12 deletions(-) rename src/{librustc/util => librustc_data_structures}/captures.rs (100%) diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 5e402dc79a1ad..012900f8af51b 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -22,7 +22,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use crate::ty::fold::TypeFoldable; use crate::ty::subst::{GenericArg, GenericArgKind}; use crate::ty::{self, BoundVar, Ty, TyCtxt}; -use crate::util::captures::Captures; +use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; use rustc_index::vec::IndexVec; use rustc_span::DUMMY_SP; diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 0380d0e35e78d..8ee8482e79dbc 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -3,7 +3,7 @@ use crate::infer::{GenericKind, VerifyBound}; use crate::traits; use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, Ty, TyCtxt}; -use crate::util::captures::Captures; +use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 37761c17f5243..cf424ffe7b293 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -100,7 +100,6 @@ pub mod ty; pub mod util { pub mod bug; - pub mod captures; pub mod common; } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 747e6e8da99af..518c0c75a3b51 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -26,8 +26,8 @@ use crate::ty::layout::VariantIdx; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; use crate::ty::walk::TypeWalker; -use crate::util::captures::Captures; use arena::SyncDroplessArena; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index aeda2eb1a15c0..c89d045cebb73 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -13,11 +13,10 @@ use crate::ty::layout::VariantIdx; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable}; use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS}; -use crate::util::captures::Captures; +use polonius_engine::Atom; +use rustc_data_structures::captures::Captures; use rustc_hir as hir; use rustc_hir::def_id::DefId; - -use polonius_engine::Atom; use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, Symbol}; diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 062b093b8e68d..68f24f2396174 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -40,8 +40,10 @@ use rustc::hir::map::Map; use rustc::lint; use rustc::lint::builtin; use rustc::middle::cstore::CrateStore; -use rustc::util::captures::Captures; +use rustc::session::config::nightly_options; +use rustc::session::Session; use rustc::{bug, span_bug}; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_error_codes::*; diff --git a/src/librustc/util/captures.rs b/src/librustc_data_structures/captures.rs similarity index 100% rename from src/librustc/util/captures.rs rename to src/librustc_data_structures/captures.rs diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index d1b7ee9e83e76..51a38a7d2ab9c 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -67,6 +67,7 @@ macro_rules! unlikely { pub mod base_n; pub mod binary_search_util; pub mod box_region; +pub mod captures; pub mod const_cstr; pub mod flock; pub mod fx; diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 77d143643b59e..f5a05751f4c40 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -16,8 +16,8 @@ use rustc::mir::{self, interpret, BodyAndCache, Promoted}; use rustc::session::Session; use rustc::ty::codec::TyDecoder; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::util::captures::Captures; use rustc::util::common::record_time; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 03120e8009f0a..2bf1efd4441e9 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -229,6 +229,7 @@ use self::SliceKind::*; use self::Usefulness::*; use self::WitnessPreference::*; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::Idx; @@ -243,7 +244,6 @@ use rustc_hir::{HirId, RangeEnd}; use rustc::lint; use rustc::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar}; use rustc::mir::Field; -use rustc::util::captures::Captures; use rustc::util::common::ErrorReported; use rustc_span::{Span, DUMMY_SP}; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f10edc1a468b4..8ff9bdf22bb3b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -114,6 +114,7 @@ use rustc::ty::{ self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, UserType, }; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -146,7 +147,6 @@ use crate::lint; use crate::require_c_abi_if_c_variadic; use crate::session::config::EntryFnType; use crate::session::Session; -use crate::util::captures::Captures; use crate::util::common::{indenter, ErrorReported}; use crate::TypeAndSubsts; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 84f2e186eaa35..3ec09e5f19af5 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -32,7 +32,7 @@ use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{ReprOptions, ToPredicate}; -use rustc::util::captures::Captures; +use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; From 402907f27390edd0d6c8b73c3521f18a1e2c76d5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 07:05:04 +0100 Subject: [PATCH 0097/1253] lowering: rustc::session -> rustc_session --- src/librustc_ast_lowering/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 68f24f2396174..f5d051618e2df 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -40,8 +40,6 @@ use rustc::hir::map::Map; use rustc::lint; use rustc::lint::builtin; use rustc::middle::cstore::CrateStore; -use rustc::session::config::nightly_options; -use rustc::session::Session; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; From 7472f9ef134465c8d077269236f09e8ef5767772 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 6 Jan 2020 07:34:52 +0100 Subject: [PATCH 0098/1253] lowering: remove dep on CrateStore --- src/librustc_ast_lowering/lib.rs | 13 +++---------- src/librustc_ast_lowering/path.rs | 8 +++----- src/librustc_resolve/lib.rs | 10 +++++++--- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index f5d051618e2df..d2a51c5d9cc22 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -39,7 +39,6 @@ use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; use rustc::lint; use rustc::lint::builtin; -use rustc::middle::cstore::CrateStore; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -172,7 +171,9 @@ struct LoweringContext<'a, 'hir: 'a> { } pub trait Resolver { - fn cstore(&self) -> &dyn CrateStore; + fn def_key(&mut self, id: DefId) -> DefKey; + + fn item_generics_cloned_untracked_liftimes(&self, def: DefId, sess: &Session) -> usize; /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; @@ -936,14 +937,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ret } - fn def_key(&mut self, id: DefId) -> DefKey { - if id.is_local() { - self.resolver.definitions().def_key(id.index) - } else { - self.resolver.cstore().def_key(id) - } - } - fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] { self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a))) } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 4f71910b0bfe2..b4c196a254e4c 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -49,7 +49,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // which may need lifetime elision performed. let parent_def_id = |this: &mut Self, def_id: DefId| DefId { krate: def_id.krate, - index: this.def_key(def_id).parent.expect("missing parent"), + index: this.resolver.def_key(def_id).parent.expect("missing parent"), }; let type_def_id = match partial_res.base_res() { Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => { @@ -93,11 +93,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return n; } assert!(!def_id.is_local()); - let item_generics = self + let n = self .resolver - .cstore() - .item_generics_cloned_untracked(def_id, self.sess); - let n = item_generics.own_counts().lifetimes; + .item_generics_cloned_untracked_liftimes(def_id, self.sess); self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f8e42724df72b..8a6248aba866a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -22,7 +22,7 @@ use Determinacy::*; use errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc::hir::exports::ExportMap; -use rustc::hir::map::Definitions; +use rustc::hir::map::{DefKey, Definitions}; use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::session::Session; @@ -1027,8 +1027,12 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. impl rustc_ast_lowering::Resolver for Resolver<'_> { - fn cstore(&self) -> &dyn CrateStore { - self.cstore() + fn def_key(&mut self, id: DefId) -> DefKey { + if id.is_local() { self.definitions().def_key(id.index) } else { self.cstore().def_key(id) } + } + + fn item_generics_cloned_untracked_liftimes(&self, def_id: DefId, sess: &Session) -> usize { + self.cstore().item_generics_cloned_untracked(def_id, sess).own_counts().lifetimes } fn resolve_str_path( From b743af6a241edbe8700ce084000f4d3cf7c1182e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 8 Jan 2020 23:16:58 +0100 Subject: [PATCH 0099/1253] rename a method in Resolver trait --- src/librustc_ast_lowering/lib.rs | 2 +- src/librustc_ast_lowering/path.rs | 4 +--- src/librustc_resolve/lib.rs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index d2a51c5d9cc22..2064a3c92f22c 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -173,7 +173,7 @@ struct LoweringContext<'a, 'hir: 'a> { pub trait Resolver { fn def_key(&mut self, id: DefId) -> DefKey; - fn item_generics_cloned_untracked_liftimes(&self, def: DefId, sess: &Session) -> usize; + fn item_generics_num_liftimes(&self, def: DefId, sess: &Session) -> usize; /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index b4c196a254e4c..f6b33de83a2b9 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -93,9 +93,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return n; } assert!(!def_id.is_local()); - let n = self - .resolver - .item_generics_cloned_untracked_liftimes(def_id, self.sess); + let n = self.resolver.item_generics_num_liftimes(def_id, self.sess); self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8a6248aba866a..0a4011fe3f404 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1031,7 +1031,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> { if id.is_local() { self.definitions().def_key(id.index) } else { self.cstore().def_key(id) } } - fn item_generics_cloned_untracked_liftimes(&self, def_id: DefId, sess: &Session) -> usize { + fn item_generics_num_liftimes(&self, def_id: DefId, sess: &Session) -> usize { self.cstore().item_generics_cloned_untracked(def_id, sess).own_counts().lifetimes } From 5dafa6a46466ab26b7cd7c38f965d37af045af5d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 09:23:44 +0100 Subject: [PATCH 0100/1253] add CStore::item_generics_num_lifetimes --- src/librustc/middle/cstore.rs | 5 ++--- src/librustc_ast_lowering/lib.rs | 2 +- src/librustc_ast_lowering/path.rs | 2 +- src/librustc_metadata/creader.rs | 3 +-- src/librustc_metadata/rmeta/decoder/cstore_impl.rs | 8 ++++---- src/librustc_resolve/lib.rs | 4 ++-- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index ee43c35c1d05b..5b1e7673629b1 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -5,8 +5,8 @@ use crate::hir::map as hir_map; use crate::hir::map::definitions::{DefKey, DefPathTable}; use crate::session::search_paths::PathKind; -use crate::session::{CrateDisambiguator, Session}; -use crate::ty::{self, TyCtxt}; +use crate::session::CrateDisambiguator; +use crate::ty::TyCtxt; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, MetadataRef}; @@ -208,7 +208,6 @@ pub trait CrateStore { fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool; fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator; fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh; - fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics; // This is basically a 1-based range of ints, which is a little // silly - I may fix that. diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 2064a3c92f22c..0edc51f1aa4ec 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -173,7 +173,7 @@ struct LoweringContext<'a, 'hir: 'a> { pub trait Resolver { fn def_key(&mut self, id: DefId) -> DefKey; - fn item_generics_num_liftimes(&self, def: DefId, sess: &Session) -> usize; + fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize; /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index f6b33de83a2b9..9b504704ae06c 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -93,7 +93,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return n; } assert!(!def_id.is_local()); - let n = self.resolver.item_generics_num_liftimes(def_id, self.sess); + let n = self.resolver.item_generics_num_lifetimes(def_id, self.sess); self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index b21715fadfe6f..30d049d143eab 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,8 +12,7 @@ use rustc::session::{CrateDisambiguator, Session}; use rustc::ty::TyCtxt; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_hir::def_id::CrateNum; -use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_index::vec::IndexVec; use rustc_target::spec::{PanicStrategy, TargetTriple}; diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index ba3c4e4aff443..eb5754bf99bfb 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -478,6 +478,10 @@ impl CStore { pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource { self.get_crate_data(cnum).source.clone() } + + pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize { + self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes + } } impl CrateStore for CStore { @@ -485,10 +489,6 @@ impl CrateStore for CStore { self } - fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { - self.get_crate_data(def.krate).get_generics(def.index, sess) - } - fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { self.get_crate_data(cnum).root.name } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0a4011fe3f404..9e4486e16f2cc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1031,8 +1031,8 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> { if id.is_local() { self.definitions().def_key(id.index) } else { self.cstore().def_key(id) } } - fn item_generics_num_liftimes(&self, def_id: DefId, sess: &Session) -> usize { - self.cstore().item_generics_cloned_untracked(def_id, sess).own_counts().lifetimes + fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize { + self.cstore().item_generics_num_lifetimes(def_id, sess) } fn resolve_str_path( From e88f071ed373f1eb572dee6bc6898508425126e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 16 Oct 2019 00:00:00 +0000 Subject: [PATCH 0101/1253] Document sanitizers in unstable-book --- .../src/compiler-flags/sanitizer.md | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/sanitizer.md diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md new file mode 100644 index 0000000000000..cbb90bd3bb331 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -0,0 +1,163 @@ +# `sanitizer` + +The tracking issue for this feature is: [#39699](https://github.com/rust-lang/rust/issues/39699). + +------------------------ + +This feature allows for use of one of following sanitizers: + +* [AddressSanitizer][clang-asan] a faster memory error detector. Can + detect out-of-bounds access to heap, stack, and globals, use after free, use + after return, double free, invalid free, memory leaks. +* [LeakSanitizer][clang-lsan] a run-time memory leak detector. +* [MemorySanitizer][clang-msan] a detector of uninitialized reads. +* [ThreadSanitizer][clang-tsan] a fast data race detector. + +To enable a sanitizer compile with `-Zsanitizer=...` option, where value is one +of `address`, `leak`, `memory` or `thread`. + +# Examples + +This sections show various issues that can be detected with sanitizers. For +simplicity, the examples are prepared under assumption that optimization level +used is zero. + +## AddressSanitizer + +Stack buffer overflow: + +```shell +$ cat a.rs +fn main() { + let xs = [0, 1, 2, 3]; + let _y = unsafe { *xs.as_ptr().offset(4) }; +} +$ rustc -Zsanitizer=address a.rs +$ ./a +================================================================= +==10029==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcc15f43d0 at pc 0x55f77dc015c5 bp 0x7ffcc15f4390 sp 0x7ffcc15f4388 +READ of size 4 at 0x7ffcc15f43d0 thread T0 + #0 0x55f77dc015c4 in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa5c4) + #1 0x55f77dc01cdb in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::haa8c76d1faa7b7ca (/tmp/a+0xacdb) + #2 0x55f77dc90f02 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hfeb9a1aef9ac820d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:48:12 + #3 0x55f77dc90f02 in std::panicking::try::do_call::h12f0919717b8e0a6 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:288:39 + #4 0x55f77dc926c9 in __rust_maybe_catch_panic /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libpanic_unwind/lib.rs:80:7 + #5 0x55f77dc9197c in std::panicking::try::h413b21cdcd6cfd86 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:267:12 + #6 0x55f77dc9197c in std::panic::catch_unwind::hc5cc8ef2fd73424d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panic.rs:396:8 + #7 0x55f77dc9197c in std::rt::lang_start_internal::h2039f418ab92218f /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:47:24 + #8 0x55f77dc01c61 in std::rt::lang_start::ha905d28f6b61d691 (/tmp/a+0xac61) + #9 0x55f77dc0163a in main (/tmp/a+0xa63a) + #10 0x7f9b3cf5bbba in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26bba) + #11 0x55f77dc01289 in _start (/tmp/a+0xa289) + +Address 0x7ffcc15f43d0 is located in stack of thread T0 at offset 48 in frame + #0 0x55f77dc0135f in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa35f) + + This frame has 1 object(s): + [32, 48) 'xs' <== Memory access at offset 48 overflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork + (longjmp and C++ exceptions *are* supported) +SUMMARY: AddressSanitizer: stack-buffer-overflow (/tmp/a+0xa5c4) in a::main::hab3bd2a745c2d0ac +Shadow bytes around the buggy address: + 0x1000182b6820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b6840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b6850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +=>0x1000182b6870: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00 + 0x1000182b6880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b68a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b68b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x1000182b68c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb + Shadow gap: cc +==10029==ABORTING +``` + +## MemorySanitizer + +Use of uninitialized memory. Note that we are using `-Zbuild-std` to instrument +standard library, and passing `-msan-track-origins=2` to the LLVM to track +origins of uninitialized memory: + +```shell +$ cat src/main.rs +use std::mem::MaybeUninit; + +fn main() { + unsafe { + let a = MaybeUninit::<[usize; 4]>::uninit(); + let a = a.assume_init(); + println!("{}", a[2]); + } +} + +$ env RUSTFLAGS="-Zsanitizer=memory -Cllvm-args=-msan-track-origins=2" cargo -Zbuild-std run --target x86_64-unknown-linux-gnu +==9416==WARNING: MemorySanitizer: use-of-uninitialized-value + #0 0x560c04f7488a in core::fmt::num::imp::fmt_u64::haa293b0b098501ca $RUST/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/src/libcore/fmt/num.rs:202:16 +... + Uninitialized value was stored to memory at + #0 0x560c04ae898a in __msan_memcpy.part.0 $RUST/src/llvm-project/compiler-rt/lib/msan/msan_interceptors.cc:1558:3 + #1 0x560c04b2bf88 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:6:16 + + Uninitialized value was created by an allocation of 'a' in the stack frame of function '_ZN6memory4main17hd2333c1899d997f5E' + #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3 +``` + + +# Instrumentation of external dependencies and std + +The sanitizers to varying degrees work correctly with partially instrumented +code. On the one extreme is LeakSanitizer that doesn't use any compile time +instrumentation, on the other is MemorySanitizer that requires that all program +code to be instrumented (failing to achieve that will inevitably result in +false positives). + +It is strongly recommended to combine sanitizers with recompiled and +instrumented standard library, for example using [cargo `-Zbuild-std` +functionality][build-std]. + +[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std + +# Build scripts and procedural macros + +Use of sanitizers together with build scripts and procedural macros is +technically possible, but in almost all cases it would be best avoided. This +is especially true for procedural macros which would require an instrumented +version of rustc. + +In more practical terms when using cargo always remember to pass `--target` +flag, so that rustflags will not be applied to build scripts and procedural +macros. + +# Additional Information + +* [Sanitizers project page](https://github.com/google/sanitizers/wiki/) +* [AddressSanitizer in Clang][clang-asan] +* [LeakSanitizer in Clang][clang-lsan] +* [MemorySanitizer in Clang][clang-msan] +* [ThreadSanitizer in Clang][clang-tsan] + +[clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html +[clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html +[clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html +[clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html From e632940a41fe6d65bd677da85d87046dc5da5022 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 10:56:05 +0100 Subject: [PATCH 0102/1253] Update src/librustc_mir/interpret/place.rs Co-Authored-By: Ralf Jung --- src/librustc_mir/interpret/place.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 6428caa8fb0ed..87bb4c04b73ac 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -182,6 +182,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { let align = layout.align.abi; let ptr = Scalar::from_uint(align.bytes(), cx.pointer_size()); + // `Poison` this to make sure that the pointer value `ptr` is never observable by the program. MPlaceTy { mplace: MemPlace { ptr, align, meta: MemPlaceMeta::Poison }, layout } } From 37b5cca3d58413fafdf40aa231bcc5ababaaa0fe Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 2 Jan 2020 12:42:31 +0100 Subject: [PATCH 0103/1253] Simplify into_key_slice_mut and document bits and bobs --- src/liballoc/collections/btree/node.rs | 22 +++++++++------------- src/liballoc/collections/btree/search.rs | 11 +++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 260e51d635dbb..03cb54ebce782 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -397,6 +397,7 @@ impl NodeRef { /// Borrows a view into the values stored in the node. /// The caller must ensure that the node is not the shared root. + /// This function is not public, so doesn't have to support shared roots like `keys` does. fn vals(&self) -> &[V] { self.reborrow().into_val_slice() } @@ -514,6 +515,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { } /// The caller must ensure that the node is not the shared root. + /// This function is not public, so doesn't have to support shared roots like `keys` does. fn keys_mut(&mut self) -> &mut [K] { unsafe { self.reborrow_mut().into_key_slice_mut() } } @@ -590,19 +592,13 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } fn into_key_slice_mut(mut self) -> &'a mut [K] { - // Same as for `into_key_slice` above, we try to avoid a run-time check. - if (mem::align_of::>() > mem::align_of::>() - || mem::size_of::>() != mem::size_of::>()) - && self.is_shared_root() - { - &mut [] - } else { - unsafe { - slice::from_raw_parts_mut( - MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), - self.len(), - ) - } + debug_assert!(!self.is_shared_root()); + // We cannot be the shared root, so `as_leaf_mut` is okay. + unsafe { + slice::from_raw_parts_mut( + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), + self.len(), + ) } } diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 3f3c49a2ef875..bdca4d186cfbd 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -46,6 +46,11 @@ where } } +/// Returns the index in the node at which the key (or an equivalent) exists +/// or could exist, and whether it exists in the node itself. If it doesn't +/// exist in the node itself, it may exist in the subtree with that index +/// (if the node has subtrees). If the key doesn't exist in node or subtree, +/// the returned index is the position or subtree to insert at. pub fn search_linear( node: &NodeRef, key: &Q, @@ -54,6 +59,12 @@ where Q: Ord, K: Borrow, { + // This function is defined over all borrow types (immutable, mutable, owned), + // and may be called on the shared root in each case. + // Crucially, we use `keys()` here, i.e., we work with immutable data. + // We do not need to make `keys_mut()` public and require support for the shared root. + // Using `keys()` is fine here even if BorrowType is mutable, as all we return + // is an index -- not a reference. for (i, k) in node.keys().iter().enumerate() { match key.cmp(k.borrow()) { Ordering::Greater => {} From 9b92bf83156fbe4892fd7a1aa186ce15cce3b770 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 9 Jan 2020 12:03:49 +0100 Subject: [PATCH 0104/1253] Apply suggestions from code review Co-Authored-By: Ralf Jung --- src/liballoc/collections/btree/node.rs | 1 + src/liballoc/collections/btree/search.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 03cb54ebce782..f40e0b0c30479 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -591,6 +591,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { unsafe { &mut *(self.root as *mut Root) } } + /// The caller must ensure that the node is not the shared root. fn into_key_slice_mut(mut self) -> &'a mut [K] { debug_assert!(!self.is_shared_root()); // We cannot be the shared root, so `as_leaf_mut` is okay. diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index bdca4d186cfbd..48cbf67eea254 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -62,7 +62,7 @@ where // This function is defined over all borrow types (immutable, mutable, owned), // and may be called on the shared root in each case. // Crucially, we use `keys()` here, i.e., we work with immutable data. - // We do not need to make `keys_mut()` public and require support for the shared root. + // `keys_mut()` does not support the shared root, so we cannot use it. // Using `keys()` is fine here even if BorrowType is mutable, as all we return // is an index -- not a reference. for (i, k) in node.keys().iter().enumerate() { From a4fa5bb6a0396b54a4519a20cd61c321905b5ac2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 12:02:44 +0100 Subject: [PATCH 0105/1253] Rename `Unsized` to `Meta` --- src/librustc_mir/interpret/eval_context.rs | 6 ++--- src/librustc_mir/interpret/intern.rs | 4 ++-- src/librustc_mir/interpret/place.rs | 28 +++++++++++----------- src/librustc_mir/interpret/snapshot.rs | 2 +- src/librustc_mir/interpret/validity.rs | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index c5c2a6769e44a..864f4f9487c88 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -465,13 +465,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Some((size, align))) } ty::Dynamic(..) => { - let vtable = metadata.unwrap_unsized(); + let vtable = metadata.unwrap_meta(); // Read size and align from vtable (already checks size). Ok(Some(self.read_size_and_align_from_vtable(vtable)?)) } ty::Slice(_) | ty::Str => { - let len = metadata.unwrap_unsized().to_machine_usize(self)?; + let len = metadata.unwrap_meta().to_machine_usize(self)?; let elem = layout.field(self, 0)?; // Make sure the slice is not too big. @@ -817,7 +817,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { " by align({}){} ref:", mplace.align.bytes(), match mplace.meta { - MemPlaceMeta::Unsized(meta) => format!(" meta({:?})", meta), + MemPlaceMeta::Meta(meta) => format!(" meta({:?})", meta), MemPlaceMeta::Poison | MemPlaceMeta::None => String::new(), } ) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 56e489d0bd590..9b3a2fa36f794 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -193,7 +193,7 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx { // Validation has already errored on an invalid vtable pointer so we can safely not // do anything if this is not a real pointer. - if let Scalar::Ptr(vtable) = mplace.meta.unwrap_unsized() { + if let Scalar::Ptr(vtable) = mplace.meta.unwrap_meta() { // Explicitly choose `Immutable` here, since vtables are immutable, even // if the reference of the fat pointer is mutable. self.intern_shallow(vtable.alloc_id, Mutability::Not, None)?; @@ -227,7 +227,7 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx ty::Array(_, n) if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {} ty::Slice(_) - if mplace.meta.unwrap_unsized().to_machine_usize(self.ecx)? == 0 => {} + if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)? == 0 => {} _ => bug!("const qualif failed to prevent mutable references"), }, } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 87bb4c04b73ac..890627a54543a 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -24,7 +24,7 @@ use super::{ /// Information required for the sound usage of a `MemPlace`. pub enum MemPlaceMeta { /// The unsized payload (e.g. length for slices or vtable pointer for trait objects). - Unsized(Scalar), + Meta(Scalar), /// `Sized` types or unsized `extern type` None, /// The address of this place may not be taken. This protects the `MemPlace` from coming from @@ -35,17 +35,17 @@ pub enum MemPlaceMeta { } impl MemPlaceMeta { - pub fn unwrap_unsized(self) -> Scalar { + pub fn unwrap_meta(self) -> Scalar { match self { - Self::Unsized(s) => s, + Self::Meta(s) => s, Self::None | Self::Poison => { bug!("expected wide pointer extra data (e.g. slice length or trait object vtable)") } } } - fn is_unsized(self) -> bool { + fn has_meta(self) -> bool { match self { - Self::Unsized(_) => true, + Self::Meta(_) => true, Self::None | Self::Poison => false, } } @@ -54,7 +54,7 @@ impl MemPlaceMeta { impl MemPlaceMeta { pub fn erase_tag(self) -> MemPlaceMeta<()> { match self { - Self::Unsized(s) => MemPlaceMeta::Unsized(s.erase_tag()), + Self::Meta(s) => MemPlaceMeta::Meta(s.erase_tag()), Self::None => MemPlaceMeta::None, Self::Poison => MemPlaceMeta::Poison, } @@ -154,7 +154,7 @@ impl MemPlace { pub fn to_ref(self) -> Immediate { match self.meta { MemPlaceMeta::None => Immediate::Scalar(self.ptr.into()), - MemPlaceMeta::Unsized(meta) => Immediate::ScalarPair(self.ptr.into(), meta.into()), + MemPlaceMeta::Meta(meta) => Immediate::ScalarPair(self.ptr.into(), meta.into()), MemPlaceMeta::Poison => bug!( "MPlaceTy::dangling may never be used to produce a \ place that will have the address of its pointee taken" @@ -214,7 +214,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { // We need to consult `meta` metadata match self.layout.ty.kind { ty::Slice(..) | ty::Str => { - return self.mplace.meta.unwrap_unsized().to_machine_usize(cx); + return self.mplace.meta.unwrap_meta().to_machine_usize(cx); } _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } @@ -231,7 +231,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { #[inline] pub(super) fn vtable(self) -> Scalar { match self.layout.ty.kind { - ty::Dynamic(..) => self.mplace.meta.unwrap_unsized(), + ty::Dynamic(..) => self.mplace.meta.unwrap_meta(), _ => bug!("vtable not supported on type {:?}", self.layout.ty), } } @@ -312,7 +312,7 @@ where let (ptr, meta) = match *val { Immediate::Scalar(ptr) => (ptr.not_undef()?, MemPlaceMeta::None), Immediate::ScalarPair(ptr, meta) => { - (ptr.not_undef()?, MemPlaceMeta::Unsized(meta.not_undef()?)) + (ptr.not_undef()?, MemPlaceMeta::Meta(meta.not_undef()?)) } }; @@ -354,7 +354,7 @@ where ) -> InterpResult<'tcx, Option>> { let size = size.unwrap_or_else(|| { assert!(!place.layout.is_unsized()); - assert!(!place.meta.is_unsized()); + assert!(!place.meta.has_meta()); place.layout.size }); self.memory.check_ptr_access(place.ptr, size, place.align) @@ -505,7 +505,7 @@ where ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(inner, inner_len)), ty::Slice(..) => { let len = Scalar::from_uint(inner_len, self.pointer_size()); - (MemPlaceMeta::Unsized(len), base.layout.ty) + (MemPlaceMeta::Meta(len), base.layout.ty) } _ => bug!("cannot subslice non-array type: `{:?}`", base.layout.ty), }; @@ -519,7 +519,7 @@ where variant: VariantIdx, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { // Downcasts only change the layout - assert!(!base.meta.is_unsized()); + assert!(!base.meta.has_meta()); Ok(MPlaceTy { layout: base.layout.for_variant(self, variant), ..base }) } @@ -1081,7 +1081,7 @@ where let mplace = MemPlace { ptr: ptr.into(), align: Align::from_bytes(1).unwrap(), - meta: MemPlaceMeta::Unsized(meta), + meta: MemPlaceMeta::Meta(meta), }; let layout = self.layout_of(self.tcx.mk_static_str()).unwrap(); diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 120baaf3be68a..a8e67c8f208a9 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -209,7 +209,7 @@ impl_snapshot_for!( impl_snapshot_for!( enum MemPlaceMeta { - Unsized(s), + Meta(s), None, Poison, } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 7a7f431402075..12e8cb6071d92 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -252,7 +252,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env); match tail.kind { ty::Dynamic(..) => { - let vtable = meta.unwrap_unsized(); + let vtable = meta.unwrap_meta(); try_validation!( self.ecx.memory.check_ptr_access( vtable, @@ -276,7 +276,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M } ty::Slice(..) | ty::Str => { let _len = try_validation!( - meta.unwrap_unsized().to_machine_usize(self.ecx), + meta.unwrap_meta().to_machine_usize(self.ecx), "non-integer slice length in wide pointer", self.path ); From c5c4fa8e7633c28464e3b27a57f2f175cc6700fd Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 12:03:37 +0100 Subject: [PATCH 0106/1253] Switch assertion order to be more helpful to ppl that encounter them --- src/librustc_mir/const_eval/eval_queries.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index d2a0798249ad9..53f3b539bdaa0 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -124,13 +124,13 @@ pub(super) fn op_to_const<'tcx>( ConstValue::ByRef { alloc, offset: ptr.offset } } Scalar::Raw { data, .. } => { + assert!(mplace.layout.is_zst()); assert_eq!( data, mplace.layout.align.abi.bytes().into(), "this MPlaceTy must come from `try_as_mplace` being used on a zst, so we know what value this integer address must have", ); - assert!(mplace.layout.is_zst()); ConstValue::Scalar(Scalar::zst()) } }; From f8428cf8d8193c1a6268a046afea9bea85d4d9fe Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Thu, 9 Jan 2020 14:51:58 +0100 Subject: [PATCH 0107/1253] doc: add Null-unchecked version section to mut pointer as_mut method The as_ref method already has a Null-unchecked version section, its example is a modification of the example in the main as_ref section. Similarly the example in this commit is a modification of the example in main as_mut section. --- src/libcore/ptr/mut_ptr.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index b3bb2f179b17e..4bc0a3e9faa60 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -250,6 +250,20 @@ impl *mut T { /// *first_value = 4; /// println!("{:?}", s); // It'll print: "[4, 2, 3]". /// ``` + /// + /// # Null-unchecked version + /// + /// If you are sure the pointer can never be null and are looking for some kind of + /// `as_mut_unchecked` that returns the `&mut T` instead of `Option<&mut T>`, know that + /// you can dereference the pointer directly. + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// let first_value = unsafe { &mut *ptr }; + /// *first_value = 4; + /// println!("{:?}", s); // It'll print: "[4, 2, 3]". + /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] #[inline] pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> { From 4840cd8117010e057109e0233f403e526d309d9f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 9 Jan 2020 10:01:20 -0500 Subject: [PATCH 0108/1253] Don't discard marker trait impls when inference variables are present Fixes #61651 Previously, we would unconditionally discard impl candidates for marker traits during trait selection. However, if the predicate had inference variables, this could have the effect of constrainting inference variables (due to a successful trait selection) when we would have otherwise failed due to mutliple applicable impls, This commit prevents marker trait impls from being discarded while the obligation predicate has any inference variables, ensuring that discarding impls will never cause us to incorrectly constraint inference variables. --- src/librustc/traits/select.rs | 62 +++++++++++++++++-- .../traits/specialize/specialization_graph.rs | 2 +- src/librustc/ty/mod.rs | 13 ++-- .../issue-61651-type-mismatch.rs | 17 +++++ 4 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 1b1cb1b36e09a..491496e2c62b3 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1412,6 +1412,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("winnowed to {} candidates for {:?}: {:?}", candidates.len(), stack, candidates); + let needs_infer = stack.obligation.predicate.needs_infer(); + // If there are STILL multiple candidates, we can further // reduce the list by dropping duplicates -- including // resolving specializations. @@ -1419,7 +1421,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut i = 0; while i < candidates.len() { let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { - self.candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j]) + self.candidate_should_be_dropped_in_favor_of( + &candidates[i], + &candidates[j], + needs_infer, + ) }); if is_dup { debug!("Dropping candidate #{}/{}: {:?}", i, candidates.len(), candidates[i]); @@ -2253,6 +2259,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, victim: &EvaluatedCandidate<'tcx>, other: &EvaluatedCandidate<'tcx>, + needs_infer: bool, ) -> bool { if victim.candidate == other.candidate { return true; @@ -2334,10 +2341,55 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match victim.candidate { ImplCandidate(victim_def) => { let tcx = self.tcx(); - return tcx.specializes((other_def, victim_def)) - || tcx - .impls_are_allowed_to_overlap(other_def, victim_def) - .is_some(); + if tcx.specializes((other_def, victim_def)) { + return true; + } + return match tcx.impls_are_allowed_to_overlap(other_def, victim_def) { + Some(ty::ImplOverlapKind::Permitted { marker: true }) => { + // Subtle: If the predicate we are evaluating has inference + // variables, do *not* allow discarding candidates due to + // marker trait impls. + // + // Without this restriction, we could end up accidentally + // constrainting inference variables based on an arbitrarily + // chosen trait impl. + // + // Imagine we have the following code: + // + // ```rust + // #[marker] trait MyTrait {} + // impl MyTrait for u8 {} + // impl MyTrait for bool {} + // ``` + // + // And we are evaluating the predicate `<_#0t as MyTrait>`. + // + // During selection, we will end up with one candidate for each + // impl of `MyTrait`. If we were to discard one impl in favor + // of the other, we would be left with one candidate, causing + // us to "successfully" select the predicate, unifying + // _#0t with (for example) `u8`. + // + // However, we have no reason to believe that this unification + // is correct - we've essentially just picked an arbitrary + // *possibility* for _#0t, and required that this be the *only* + // possibility. + // + // Eventually, we will either: + // 1) Unify all inference variables in the predicate through + // some other means (e.g. type-checking of a function). We will + // then be in a position to drop marker trait candidates + // without constraining inference variables (since there are + // none left to constrin) + // 2) Be left with some unconstrained inference variables. We + // will then correctly report an inference error, since the + // existence of multiple marker trait impls tells us nothing + // about which one should actually apply. + !needs_infer + } + Some(_) => true, + None => false, + }; } ParamCandidate(ref cand) => { // Prefer the impl to a global where clause candidate. diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index c176f139bf868..9509b6220eb0e 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -163,7 +163,7 @@ impl<'tcx> Children { tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { match overlap_kind { - ty::ImplOverlapKind::Permitted => {} + ty::ImplOverlapKind::Permitted { marker: _ } => {} ty::ImplOverlapKind::Issue33140 => { last_lint = Some(FutureCompatOverlapError { error: overlap_error(overlap), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 747e6e8da99af..d27a29d31c0c3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2662,7 +2662,12 @@ impl<'tcx> ::std::ops::Deref for Attributes<'tcx> { #[derive(Debug, PartialEq, Eq)] pub enum ImplOverlapKind { /// These impls are always allowed to overlap. - Permitted, + Permitted { + /// Whether or not the impl is permitted due to the trait being + /// a marker trait (a trait with #[marker], or a trait with + /// no associated items and #![feature(overlapping_marker_traits)] enabled) + marker: bool, + }, /// These impls are allowed to overlap, but that raises /// an issue #33140 future-compatibility warning. /// @@ -2833,7 +2838,7 @@ impl<'tcx> TyCtxt<'tcx> { if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) { - return Some(ImplOverlapKind::Permitted); + return Some(ImplOverlapKind::Permitted { marker: false }); } match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { @@ -2843,7 +2848,7 @@ impl<'tcx> TyCtxt<'tcx> { "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", def_id1, def_id2 ); - return Some(ImplOverlapKind::Permitted); + return Some(ImplOverlapKind::Permitted { marker: false }); } (ImplPolarity::Positive, ImplPolarity::Negative) | (ImplPolarity::Negative, ImplPolarity::Positive) => { @@ -2879,7 +2884,7 @@ impl<'tcx> TyCtxt<'tcx> { "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", def_id1, def_id2 ); - Some(ImplOverlapKind::Permitted) + Some(ImplOverlapKind::Permitted { marker: true }) } else { if let Some(self_ty1) = self.issue33140_self_ty(def_id1) { if let Some(self_ty2) = self.issue33140_self_ty(def_id2) { diff --git a/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs new file mode 100644 index 0000000000000..0af706615e31f --- /dev/null +++ b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs @@ -0,0 +1,17 @@ +// check-pass +// Regression test for issue #61651 +// Verifies that we don't try to constrain inference +// variables due to the presence of multiple applicable +// marker trait impls + +#![feature(marker_trait_attr)] + +#[marker] // Remove this line and it works?!? +trait Foo {} +impl Foo for u8 {} +impl Foo<[u8; 1]> for u8 {} +fn foo, U>(_: T) -> U { unimplemented!() } + +fn main() { + let _: u16 = foo(0_u8); +} From 41318e9a267024fb36162382e26944d235aa71cd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 8 Jan 2020 15:07:26 +0300 Subject: [PATCH 0109/1253] compiletest: Do not deduplicate diagnostics in UI tests --- src/tools/compiletest/src/runtest.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 226a12c6734b7..1912c9ef5baeb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1864,12 +1864,14 @@ impl<'test> TestCx<'test> { rustc.args(&["--error-format", "json"]); } rustc.arg("-Zui-testing"); + rustc.arg("-Zdeduplicate-diagnostics=no"); } Ui => { if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { rustc.args(&["--error-format", "json"]); } rustc.arg("-Zui-testing"); + rustc.arg("-Zdeduplicate-diagnostics=no"); } MirOpt => { rustc.args(&[ From 642669c74d97b79a9a9f7300dfac3bb86bb75d97 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 8 Jan 2020 20:02:10 +0300 Subject: [PATCH 0110/1253] Update tests --- .../compile-fail/consts/const-fn-error.rs | 1 + src/test/compile-fail/issue-52443.rs | 1 + .../ui-fulldeps/lint-plugin-forbid-attrs.rs | 2 + .../lint-plugin-forbid-attrs.stderr | 20 +- .../ui-fulldeps/lint-plugin-forbid-cmdline.rs | 2 + .../lint-plugin-forbid-cmdline.stderr | 18 +- .../lint-tool-cmdline-allow.stderr | 12 + src/test/ui-fulldeps/lint-tool-test.rs | 7 +- src/test/ui-fulldeps/lint-tool-test.stderr | 44 +++- .../ui/associated-type-bounds/duplicate.rs | 3 + .../associated-type-bounds/duplicate.stderr | 54 ++-- .../ret-impl-trait-no-fg.rs | 1 + .../ret-impl-trait-no-fg.stderr | 10 +- .../ui/async-await/unresolved_type_param.rs | 8 + .../async-await/unresolved_type_param.stderr | 26 +- .../attributes/register-attr-tool-import.rs | 1 + .../register-attr-tool-import.stderr | 14 +- .../regions-bound-missing-bound-in-impl.rs | 1 + ...regions-bound-missing-bound-in-impl.stderr | 25 +- .../const-eval/const-eval-overflow-2.rs | 1 + .../const-eval/const-eval-overflow-2.stderr | 8 +- .../ui/consts/const-eval/ref_to_int_match.rs | 1 + .../consts/const-eval/ref_to_int_match.stderr | 10 +- src/test/ui/consts/enum-discr-type-err.rs | 1 + src/test/ui/consts/enum-discr-type-err.stderr | 19 +- src/test/ui/consts/match_ice.rs | 1 + src/test/ui/consts/match_ice.stderr | 10 +- .../miri_unleashed/const_refers_to_static.rs | 1 + .../const_refers_to_static.stderr | 10 +- .../transmute-size-mismatch-before-typeck.rs | 1 + ...ansmute-size-mismatch-before-typeck.stderr | 12 +- .../cycle-trait-default-type-trait.rs | 1 + .../cycle-trait-default-type-trait.stderr | 15 +- src/test/ui/deduplicate-diagnostics.rs | 2 +- ...ves-span-PartialOrd-enum-struct-variant.rs | 6 +- ...span-PartialOrd-enum-struct-variant.stderr | 38 ++- .../derives/derives-span-PartialOrd-enum.rs | 6 +- .../derives-span-PartialOrd-enum.stderr | 38 ++- .../derives/derives-span-PartialOrd-struct.rs | 6 +- .../derives-span-PartialOrd-struct.stderr | 38 ++- .../derives-span-PartialOrd-tuple-struct.rs | 6 +- ...erives-span-PartialOrd-tuple-struct.stderr | 38 ++- src/test/ui/derives/deriving-bounds.rs | 2 + src/test/ui/derives/deriving-bounds.stderr | 30 ++- .../ui/derives/deriving-meta-unknown-trait.rs | 1 + .../deriving-meta-unknown-trait.stderr | 8 +- src/test/ui/derives/deriving-primitive.rs | 1 + src/test/ui/derives/deriving-primitive.stderr | 8 +- .../issue-54109-and_instead_of_ampersands.rs | 8 + ...sue-54109-and_instead_of_ampersands.stderr | 82 +++++- src/test/ui/error-codes/E0030.rs | 1 + src/test/ui/error-codes/E0030.stderr | 8 +- src/test/ui/error-codes/E0452.rs | 6 +- src/test/ui/error-codes/E0452.stderr | 32 ++- src/test/ui/error-codes/E0453.rs | 2 + src/test/ui/error-codes/E0453.stderr | 20 +- src/test/ui/error-codes/E0565.rs | 1 + src/test/ui/error-codes/E0565.stderr | 8 +- src/test/ui/error-codes/E0602.stderr | 10 +- .../issue-43106-gating-of-derive-2.rs | 3 + .../issue-43106-gating-of-derive-2.stderr | 24 +- .../issue-43106-gating-of-rustc_deprecated.rs | 1 + ...ue-43106-gating-of-rustc_deprecated.stderr | 12 +- .../issue-43106-gating-of-stable.rs | 1 + .../issue-43106-gating-of-stable.stderr | 12 +- .../issue-43106-gating-of-unstable.rs | 1 + .../issue-43106-gating-of-unstable.stderr | 12 +- .../feature-gate-external_doc.rs | 1 + .../feature-gate-external_doc.stderr | 11 +- .../feature-gate-lint-reasons.rs | 2 + .../feature-gate-lint-reasons.stderr | 20 +- src/test/ui/generator/auto-trait-regions.rs | 2 + .../ui/generator/auto-trait-regions.stderr | 28 ++- src/test/ui/hrtb/hrtb-perfect-forwarding.rs | 1 + .../ui/hrtb/hrtb-perfect-forwarding.stderr | 11 +- src/test/ui/hrtb/issue-30786.nll.stderr | 40 ++- src/test/ui/hrtb/issue-30786.rs | 7 +- src/test/ui/impl-trait/auto-trait-leak.rs | 1 + src/test/ui/impl-trait/auto-trait-leak.stderr | 47 +++- src/test/ui/imports/issue-55457.rs | 2 + src/test/ui/imports/issue-55457.stderr | 18 +- .../local-modularized-tricky-fail-1.rs | 1 + .../local-modularized-tricky-fail-1.stderr | 29 ++- src/test/ui/imports/macros.rs | 1 + src/test/ui/imports/macros.stderr | 28 ++- .../ui/issues/issue-17718-const-bad-values.rs | 1 + .../issue-17718-const-bad-values.stderr | 8 +- src/test/ui/issues/issue-20831-debruijn.rs | 1 + .../ui/issues/issue-20831-debruijn.stderr | 44 +++- src/test/ui/issues/issue-32963.rs | 1 + src/test/ui/issues/issue-32963.stderr | 13 +- src/test/ui/issues/issue-33571.rs | 1 + src/test/ui/issues/issue-33571.stderr | 14 +- src/test/ui/issues/issue-34229.rs | 4 + src/test/ui/issues/issue-34229.stderr | 38 ++- src/test/ui/issues/issue-36617.rs | 1 + src/test/ui/issues/issue-36617.stderr | 10 +- src/test/ui/issues/issue-41255.rs | 16 ++ src/test/ui/issues/issue-41255.stderr | 88 ++++++- src/test/ui/issues/issue-43105.rs | 1 + src/test/ui/issues/issue-43105.stderr | 8 +- src/test/ui/issues/issue-46101.rs | 1 + src/test/ui/issues/issue-46101.stderr | 8 +- src/test/ui/issues/issue-50480.rs | 1 + src/test/ui/issues/issue-50480.stderr | 8 +- src/test/ui/issues/issue-53251.rs | 1 + src/test/ui/issues/issue-53251.stderr | 11 +- src/test/ui/issues/issue-59029-1.rs | 1 + src/test/ui/issues/issue-59029-1.stderr | 8 +- src/test/ui/issues/issue-62554.rs | 5 +- src/test/ui/issues/issue-62554.stderr | 60 ++++- src/test/ui/issues/issue-6804.rs | 4 +- src/test/ui/issues/issue-6804.stderr | 11 +- src/test/ui/lint/lint-forbid-attr.rs | 2 + src/test/ui/lint/lint-forbid-attr.stderr | 20 +- src/test/ui/lint/lint-forbid-cmdline.rs | 2 + src/test/ui/lint/lint-forbid-cmdline.stderr | 18 +- src/test/ui/lint/lint-malformed.rs | 6 +- src/test/ui/lint/lint-malformed.stderr | 32 ++- src/test/ui/lint/lint-removed-cmdline.stderr | 12 + src/test/ui/lint/lint-renamed-cmdline.stderr | 12 + src/test/ui/lint/lint-stability-deprecated.rs | 3 + .../ui/lint/lint-stability-deprecated.stderr | 162 ++++++------ .../ui/lint/lint-unexported-no-mangle.stderr | 24 ++ .../ui/lint/lint-unknown-lint-cmdline.stderr | 20 +- src/test/ui/lint/outer-forbid.rs | 6 + src/test/ui/lint/outer-forbid.stderr | 60 ++++- src/test/ui/lint/reasons-erroneous.rs | 46 ++++ src/test/ui/lint/reasons-erroneous.stderr | 154 +++++++++++- src/test/ui/lint/reasons-forbidden.rs | 8 + src/test/ui/lint/reasons-forbidden.stderr | 26 +- src/test/ui/macros/builtin-std-paths-fail.rs | 4 + .../ui/macros/builtin-std-paths-fail.stderr | 48 +++- src/test/ui/macros/meta-item-absolute-path.rs | 1 + .../ui/macros/meta-item-absolute-path.stderr | 8 +- src/test/ui/match/match-range-fail-2.rs | 3 + src/test/ui/match/match-range-fail-2.stderr | 24 +- src/test/ui/parser/issue-62973.rs | 2 +- src/test/ui/parser/issue-62973.stderr | 13 +- src/test/ui/parser/issue-63135.rs | 2 +- src/test/ui/parser/issue-63135.stderr | 11 +- src/test/ui/parser/missing_right_paren.rs | 2 +- src/test/ui/parser/missing_right_paren.stderr | 11 +- .../borrowck-pat-ref-mut-and-ref.rs | 2 + .../borrowck-pat-ref-mut-and-ref.stderr | 40 ++- .../ui/pattern/patkind-litrange-no-expr.rs | 3 +- .../pattern/patkind-litrange-no-expr.stderr | 8 +- .../usefulness/match-range-fail-dominate.rs | 4 + .../match-range-fail-dominate.stderr | 22 +- src/test/ui/privacy/privacy1.rs | 1 + src/test/ui/privacy/privacy1.stderr | 14 +- .../ui/privacy/private-in-public-assoc-ty.rs | 3 + .../privacy/private-in-public-assoc-ty.stderr | 32 ++- src/test/ui/proc-macro/issue-50493.rs | 1 + src/test/ui/proc-macro/issue-50493.stderr | 10 +- .../proc-macro/macro-namespace-reserved-2.rs | 1 + .../macro-namespace-reserved-2.stderr | 18 +- src/test/ui/proc-macro/resolve-error.rs | 4 + src/test/ui/proc-macro/resolve-error.stderr | 44 +++- src/test/ui/range/range_traits-1.rs | 24 ++ src/test/ui/range/range_traits-1.stderr | 238 +++++++++++++++++- .../regions-close-object-into-object-5.rs | 1 + .../regions-close-object-into-object-5.stderr | 17 +- .../regions-normalize-in-where-clause-list.rs | 2 + ...ions-normalize-in-where-clause-list.stderr | 74 +++++- src/test/ui/repr/repr-align-assign.fixed | 2 + src/test/ui/repr/repr-align-assign.rs | 2 + src/test/ui/repr/repr-align-assign.stderr | 16 +- src/test/ui/repr/repr-align.rs | 6 + src/test/ui/repr/repr-align.stderr | 46 +++- .../ui/rfc-2497-if-let-chains/feature-gate.rs | 2 + .../feature-gate.stderr | 28 ++- ...cant-hide-behind-direct-struct-embedded.rs | 1 + ...-hide-behind-direct-struct-embedded.stderr | 8 +- .../cant-hide-behind-direct-struct-param.rs | 1 + ...ant-hide-behind-direct-struct-param.stderr | 8 +- .../ui/rfc1445/match-forbidden-without-eq.rs | 1 + .../rfc1445/match-forbidden-without-eq.stderr | 12 +- ...tch-nonempty-array-forbidden-without-eq.rs | 1 + ...nonempty-array-forbidden-without-eq.stderr | 8 +- .../match-requires-both-partialeq-and-eq.rs | 1 + ...atch-requires-both-partialeq-and-eq.stderr | 8 +- .../ui/rust-2018/uniform-paths/cross-crate.rs | 1 + .../uniform-paths/cross-crate.stderr | 14 +- .../rust-2018/uniform-paths/prelude-fail-2.rs | 2 + .../uniform-paths/prelude-fail-2.stderr | 28 ++- .../ui/span/issue-43927-non-ADT-derive.rs | 3 + .../ui/span/issue-43927-non-ADT-derive.stderr | 26 +- src/test/ui/suffixed-literal-meta.rs | 12 + src/test/ui/suffixed-literal-meta.stderr | 118 ++++++++- .../tool-attributes-misplaced-1.rs | 1 + .../tool-attributes-misplaced-1.stderr | 16 +- src/test/ui/tool_lints.rs | 2 + src/test/ui/tool_lints.stderr | 14 +- .../ui/tuple/tuple-struct-fields/test2.rs | 1 + .../ui/tuple/tuple-struct-fields/test2.stderr | 8 +- .../ui/tuple/tuple-struct-fields/test3.rs | 1 + .../ui/tuple/tuple-struct-fields/test3.stderr | 8 +- src/test/ui/union/union-const-pat.rs | 1 + src/test/ui/union/union-const-pat.stderr | 8 +- src/test/ui/unknown-lint-tool-name.rs | 4 + src/test/ui/unknown-lint-tool-name.stderr | 28 ++- src/test/ui/use/use-super-global-path.rs | 1 + src/test/ui/use/use-super-global-path.stderr | 12 +- 204 files changed, 2841 insertions(+), 355 deletions(-) diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/compile-fail/consts/const-fn-error.rs index 5d26059644d17..9db595af63efb 100644 --- a/src/test/compile-fail/consts/const-fn-error.rs +++ b/src/test/compile-fail/consts/const-fn-error.rs @@ -6,6 +6,7 @@ const fn f(x: usize) -> usize { let mut sum = 0; for i in 0..x { //~^ ERROR E0015 + //~| ERROR E0015 //~| ERROR E0658 //~| ERROR E0080 //~| ERROR E0744 diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index ee37aaa5e13b9..597fbbf00d53c 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -8,6 +8,7 @@ fn main() { //~| WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; //~^ ERROR calls in constants are limited to constant functions + //~| ERROR calls in constants are limited to constant functions //~| ERROR `for` is not allowed in a `const` //~| ERROR references in constants may only refer to immutable values //~| ERROR evaluation of constant value failed diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs index 569f04d18ffd1..35ddab95831db 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs @@ -10,6 +10,8 @@ fn lintme() { } //~ ERROR item is named 'lintme' #[allow(test_lint)] //~^ ERROR allow(test_lint) overruled by outer forbid(test_lint) +//~| ERROR allow(test_lint) overruled by outer forbid(test_lint) +//~| ERROR allow(test_lint) overruled by outer forbid(test_lint) pub fn main() { lintme(); } diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr index c0de1feee7d46..f93a0a0de5377 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr @@ -7,6 +7,15 @@ LL | #![forbid(test_lint)] LL | #[allow(test_lint)] | ^^^^^^^^^ overruled by previous forbid +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-attrs.rs:11:9 + | +LL | #![forbid(test_lint)] + | --------- `forbid` level set here +... +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-plugin-forbid-attrs.rs:5:1 | @@ -27,6 +36,15 @@ note: lint level defined here LL | #![forbid(test_lint)] | ^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-attrs.rs:11:9 + | +LL | #![forbid(test_lint)] + | --------- `forbid` level set here +... +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs index 82313f6912067..695d3aef16905 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs @@ -8,6 +8,8 @@ fn lintme() { } //~ ERROR item is named 'lintme' #[allow(test_lint)] //~ ERROR allow(test_lint) overruled by outer forbid(test_lint) + //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) + //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) pub fn main() { lintme(); } diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr index f189efbf61d85..0302ec84d5620 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr @@ -6,6 +6,14 @@ LL | #[allow(test_lint)] | = note: `forbid` lint level was set on command line +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-cmdline.rs:10:9 + | +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-plugin-forbid-cmdline.rs:6:1 | @@ -22,6 +30,14 @@ LL | fn lintme() { } | = note: requested on the command line with `-F test-lint` -error: aborting due to 2 previous errors +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-cmdline.rs:10:9 + | +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr index 825a341c5d327..2f1c29ea7b832 100644 --- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr +++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr @@ -2,6 +2,10 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore | = note: requested on the command line with `-A test_lint` +warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint + | + = note: requested on the command line with `-A test_lint` + warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-tool-cmdline-allow.rs:7:1 | @@ -10,6 +14,10 @@ LL | #![plugin(lint_tool_test)] | = note: `#[warn(deprecated)]` on by default +warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint + | + = note: requested on the command line with `-A test_lint` + warning: item is named 'lintme' --> $DIR/lint-tool-cmdline-allow.rs:9:1 | @@ -18,3 +26,7 @@ LL | fn lintme() {} | = note: `#[warn(clippy::test_lint)]` on by default +warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint + | + = note: requested on the command line with `-A test_lint` + diff --git a/src/test/ui-fulldeps/lint-tool-test.rs b/src/test/ui-fulldeps/lint-tool-test.rs index 216a8cb95e31e..f92bcd213b844 100644 --- a/src/test/ui-fulldeps/lint-tool-test.rs +++ b/src/test/ui-fulldeps/lint-tool-test.rs @@ -8,9 +8,12 @@ #![allow(dead_code)] #![cfg_attr(foo, warn(test_lint))] //~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future -//~^^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future #![deny(clippy_group)] //~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future fn lintme() { } //~ ERROR item is named 'lintme' @@ -25,6 +28,8 @@ pub fn main() { #[allow(test_group)] //~^ WARNING lint name `test_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future #[deny(this_lint_does_not_exist)] //~ WARNING unknown lint: `this_lint_does_not_exist` fn hello() { fn lintmetoo() { } diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr index d4031a780c3d4..809b9ac16205d 100644 --- a/src/test/ui-fulldeps/lint-tool-test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr @@ -7,19 +7,19 @@ LL | #![cfg_attr(foo, warn(test_lint))] = note: `#[warn(renamed_and_removed_lints)]` on by default warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:12:9 + --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:26:9 + --> $DIR/lint-tool-test.rs:29:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` warning: unknown lint: `this_lint_does_not_exist` - --> $DIR/lint-tool-test.rs:28:8 + --> $DIR/lint-tool-test.rs:33:8 | LL | #[deny(this_lint_does_not_exist)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,6 +32,18 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` +warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:13:9 + | +LL | #![deny(clippy_group)] + | ^^^^^^^^^^^^ help: change it to: `clippy::group` + +warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:29:9 + | +LL | #[allow(test_group)] + | ^^^^^^^^^^ help: change it to: `clippy::test_group` + warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-tool-test.rs:6:1 | @@ -40,31 +52,49 @@ LL | #![plugin(lint_tool_test)] | = note: `#[warn(deprecated)]` on by default +warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:9:23 + | +LL | #![cfg_attr(foo, warn(test_lint))] + | ^^^^^^^^^ help: change it to: `clippy::test_lint` + +warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:13:9 + | +LL | #![deny(clippy_group)] + | ^^^^^^^^^^^^ help: change it to: `clippy::group` + error: item is named 'lintme' - --> $DIR/lint-tool-test.rs:15:1 + --> $DIR/lint-tool-test.rs:18:1 | LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint-tool-test.rs:12:9 + --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]` error: item is named 'lintmetoo' - --> $DIR/lint-tool-test.rs:23:5 + --> $DIR/lint-tool-test.rs:26:5 | LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint-tool-test.rs:12:9 + --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]` +warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:29:9 + | +LL | #[allow(test_group)] + | ^^^^^^^^^^ help: change it to: `clippy::test_group` + error: aborting due to 2 previous errors diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 64bc9eeec2529..65ca017e2f269 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -157,10 +157,13 @@ trait TRW3 where T: Iterator {} //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] trait TRSW1 where Self: Iterator {} //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] trait TRSW2 where Self: Iterator {} //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] trait TRSW3 where Self: Iterator {} //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] trait TRA1 { type A: Iterator; } //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] trait TRA2 { type A: Iterator; } diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index caecc5e85f6e7..defa62994e9e1 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -531,7 +531,23 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:160:46 + --> $DIR/duplicate.rs:158:46 + | +LL | trait TRSW1 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:161:46 + | +LL | trait TRSW2 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:161:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -539,7 +555,15 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:162:49 + --> $DIR/duplicate.rs:164:49 + | +LL | trait TRSW3 where Self: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:164:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -547,7 +571,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:164:43 + --> $DIR/duplicate.rs:167:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -555,7 +579,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:166:43 + --> $DIR/duplicate.rs:169:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -563,7 +587,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:168:46 + --> $DIR/duplicate.rs:171:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -571,7 +595,7 @@ LL | trait TRA3 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:171:40 + --> $DIR/duplicate.rs:174:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -579,7 +603,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:175:44 + --> $DIR/duplicate.rs:178:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -587,7 +611,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:179:43 + --> $DIR/duplicate.rs:182:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -667,40 +691,40 @@ LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:171:28 + --> $DIR/duplicate.rs:174:28 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:171:40 + --> $DIR/duplicate.rs:174:40 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:175:32 + --> $DIR/duplicate.rs:178:32 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:175:44 + --> $DIR/duplicate.rs:178:44 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:179:28 + --> $DIR/duplicate.rs:182:28 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:179:43 + --> $DIR/duplicate.rs:182:43 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ -error: aborting due to 93 previous errors +error: aborting due to 96 previous errors diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs index 2c7a5cd378fc2..b12d7bccecead 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs @@ -8,6 +8,7 @@ impl Trait<'_, '_> for T { } async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { //~^ ERROR ambiguous lifetime bound + //~| ERROR ambiguous lifetime bound (a, b) } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr index 59d7728d41c4c..f9a1b4b3394c1 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr @@ -6,5 +6,13 @@ LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<' | = help: add #![feature(member_constraints)] to the crate attributes to enable -error: aborting due to previous error +error: ambiguous lifetime bound in `impl Trait` + --> $DIR/ret-impl-trait-no-fg.rs:9:64 + | +LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other + | + = help: add #![feature(member_constraints)] to the crate attributes to enable + +error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs index 79c043b701ddb..d313691b38857 100644 --- a/src/test/ui/async-await/unresolved_type_param.rs +++ b/src/test/ui/async-await/unresolved_type_param.rs @@ -8,8 +8,16 @@ async fn bar() -> () {} async fn foo() { bar().await; //~^ ERROR type inside `async fn` body must be known in this context + //~| ERROR type inside `async fn` body must be known in this context + //~| ERROR type inside `async fn` body must be known in this context //~| NOTE cannot infer type for type parameter `T` + //~| NOTE cannot infer type for type parameter `T` + //~| NOTE cannot infer type for type parameter `T` + //~| NOTE the type is part of the `async fn` body because of this `await` //~| NOTE the type is part of the `async fn` body because of this `await` + //~| NOTE the type is part of the `async fn` body because of this `await` + //~| NOTE in this expansion of desugaring of `await` + //~| NOTE in this expansion of desugaring of `await` //~| NOTE in this expansion of desugaring of `await` } fn main() {} diff --git a/src/test/ui/async-await/unresolved_type_param.stderr b/src/test/ui/async-await/unresolved_type_param.stderr index 3ffdb8ce6b9a1..6b9e960ca1ae6 100644 --- a/src/test/ui/async-await/unresolved_type_param.stderr +++ b/src/test/ui/async-await/unresolved_type_param.stderr @@ -10,6 +10,30 @@ note: the type is part of the `async fn` body because of this `await` LL | bar().await; | ^^^^^^^^^^^ -error: aborting due to previous error +error[E0698]: type inside `async fn` body must be known in this context + --> $DIR/unresolved_type_param.rs:9:5 + | +LL | bar().await; + | ^^^ cannot infer type for type parameter `T` declared on the function `bar` + | +note: the type is part of the `async fn` body because of this `await` + --> $DIR/unresolved_type_param.rs:9:5 + | +LL | bar().await; + | ^^^^^^^^^^^ + +error[E0698]: type inside `async fn` body must be known in this context + --> $DIR/unresolved_type_param.rs:9:5 + | +LL | bar().await; + | ^^^ cannot infer type for type parameter `T` declared on the function `bar` + | +note: the type is part of the `async fn` body because of this `await` + --> $DIR/unresolved_type_param.rs:9:5 + | +LL | bar().await; + | ^^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0698`. diff --git a/src/test/ui/attributes/register-attr-tool-import.rs b/src/test/ui/attributes/register-attr-tool-import.rs index 3d0cf9154fbca..e01dc4dfa49be 100644 --- a/src/test/ui/attributes/register-attr-tool-import.rs +++ b/src/test/ui/attributes/register-attr-tool-import.rs @@ -11,4 +11,5 @@ use tool as renamed_tool; // OK #[renamed_attr] //~ ERROR cannot use an explicitly registered attribute through an import #[renamed_tool::attr] //~ ERROR cannot use a tool module through an import + //~| ERROR cannot use a tool module through an import fn main() {} diff --git a/src/test/ui/attributes/register-attr-tool-import.stderr b/src/test/ui/attributes/register-attr-tool-import.stderr index 6f280c8e0d931..59f5a8620ab11 100644 --- a/src/test/ui/attributes/register-attr-tool-import.stderr +++ b/src/test/ui/attributes/register-attr-tool-import.stderr @@ -22,5 +22,17 @@ note: the tool module imported here LL | use tool as renamed_tool; // OK | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: cannot use a tool module through an import + --> $DIR/register-attr-tool-import.rs:13:3 + | +LL | #[renamed_tool::attr] + | ^^^^^^^^^^^^ + | +note: the tool module imported here + --> $DIR/register-attr-tool-import.rs:10:5 + | +LL | use tool as renamed_tool; // OK + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs index da918ba92b863..141ad5bd2c482 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs @@ -26,6 +26,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize { fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { //~^ ERROR method not compatible with trait + //~| ERROR method not compatible with trait // // Note: This is a terrible error message. It is caused // because, in the trait, 'b is early bound, and in the impl, diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 4f86ffb2b79af..ad39b3601bffb 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -35,8 +35,27 @@ note: ...does not necessarily outlive the lifetime `'c` as defined on the method LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^ +error[E0308]: method not compatible with trait + --> $DIR/regions-bound-missing-bound-in-impl.rs:27:5 + | +LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)` + found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)` +note: the lifetime `'c` as defined on the method body at 27:24... + --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 + | +LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { + | ^^ +note: ...does not necessarily outlive the lifetime `'c` as defined on the method body at 27:24 + --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 + | +LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { + | ^^ + error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:41:20 + --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20 | LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); | ---------------- lifetimes in impl do not match this method in trait @@ -45,7 +64,7 @@ LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { | ^ lifetimes do not match method in trait error[E0276]: impl has stricter requirements than trait - --> $DIR/regions-bound-missing-bound-in-impl.rs:48:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:49:5 | LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); | ------------------------------------------------------- definition of `another_bound` from trait @@ -53,7 +72,7 @@ LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0195, E0276, E0308. For more information about an error, try `rustc --explain E0195`. diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-2.rs b/src/test/ui/consts/const-eval/const-eval-overflow-2.rs index 9369702f1721c..9300d9576de1d 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-2.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.rs @@ -14,6 +14,7 @@ fn main() { match -128i8 { NEG_NEG_128 => println!("A"), //~^ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern _ => println!("B"), } } diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr index 13f00c47f6c1b..26728cf541582 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr @@ -4,5 +4,11 @@ error: could not evaluate constant pattern LL | NEG_NEG_128 => println!("A"), | ^^^^^^^^^^^ -error: aborting due to previous error +error: could not evaluate constant pattern + --> $DIR/const-eval-overflow-2.rs:15:9 + | +LL | NEG_NEG_128 => println!("A"), + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.rs b/src/test/ui/consts/const-eval/ref_to_int_match.rs index 45ce040fb9eef..87136a109db35 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.rs +++ b/src/test/ui/consts/const-eval/ref_to_int_match.rs @@ -5,6 +5,7 @@ fn main() { match n { 0..=10 => {}, 10..=BAR => {}, //~ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern _ => {}, } } diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.stderr index b72a5b80afa8d..17f8744ed9fd7 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ref_to_int_match.rs:24:1 + --> $DIR/ref_to_int_match.rs:25:1 | LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes @@ -12,6 +12,12 @@ error: could not evaluate constant pattern LL | 10..=BAR => {}, | ^^^ -error: aborting due to 2 previous errors +error: could not evaluate constant pattern + --> $DIR/ref_to_int_match.rs:7:14 + | +LL | 10..=BAR => {}, + | ^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/enum-discr-type-err.rs b/src/test/ui/consts/enum-discr-type-err.rs index d66c4f47d03ee..5adb2fa54edc4 100644 --- a/src/test/ui/consts/enum-discr-type-err.rs +++ b/src/test/ui/consts/enum-discr-type-err.rs @@ -17,6 +17,7 @@ macro_rules! mac { enum E { $( $v = $s::V, )* //~^ ERROR mismatched types + //~| ERROR mismatched types } } } diff --git a/src/test/ui/consts/enum-discr-type-err.stderr b/src/test/ui/consts/enum-discr-type-err.stderr index 848ccf94da2b6..9935f88e5b577 100644 --- a/src/test/ui/consts/enum-discr-type-err.stderr +++ b/src/test/ui/consts/enum-discr-type-err.stderr @@ -15,6 +15,23 @@ help: you can convert an `i32` to `isize` and panic if the converted value would LL | $( $v = $s::V.try_into().unwrap(), )* | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/enum-discr-type-err.rs:18:21 + | +LL | $( $v = $s::V, )* + | ^^^^^ expected `isize`, found `i32` +... +LL | / mac! { +LL | | A = F, +LL | | B = T, +LL | | } + | |_- in this macro invocation + | +help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit + | +LL | $( $v = $s::V.try_into().unwrap(), )* + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs index 1c13bfceb6cc2..1e495438e836c 100644 --- a/src/test/ui/consts/match_ice.rs +++ b/src/test/ui/consts/match_ice.rs @@ -10,6 +10,7 @@ fn main() { match C { C => {} //~^ ERROR to use a constant of type `S` in a pattern, `S` must be annotated with + //~| ERROR to use a constant of type `S` in a pattern, `S` must be annotated with } const K: &T = &T; match K { //~ ERROR non-exhaustive patterns: `&T` not covered diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr index bf0bd3aca97a4..b25ac09ab1211 100644 --- a/src/test/ui/consts/match_ice.stderr +++ b/src/test/ui/consts/match_ice.stderr @@ -5,7 +5,7 @@ LL | C => {} | ^ error[E0004]: non-exhaustive patterns: `&T` not covered - --> $DIR/match_ice.rs:15:11 + --> $DIR/match_ice.rs:16:11 | LL | struct T; | --------- `T` defined here @@ -15,6 +15,12 @@ LL | match K { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to 2 previous errors +error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match_ice.rs:11:9 + | +LL | C => {} + | ^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs index e07db3ffba25e..edbf0e02d8de2 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -28,6 +28,7 @@ const READ_INTERIOR_MUT: usize = { static mut MUTABLE: u32 = 0; const READ_MUT: u32 = unsafe { MUTABLE }; //~ WARN any use of this value will cause an error //~^ WARN skipping const checks +//~| WARN skipping const checks // ok some day perhaps const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index eae76c1389b62..243efbbaa76af 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -29,7 +29,13 @@ LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:35:6 + --> $DIR/const_refers_to_static.rs:29:32 + | +LL | const READ_MUT: u32 = unsafe { MUTABLE }; + | ^^^^^^^ + +warning: skipping const checks + --> $DIR/const_refers_to_static.rs:36:6 | LL | &FOO | ^^^ @@ -84,7 +90,7 @@ LL | const READ_MUT: u32 = unsafe { MUTABLE }; | constant accesses static error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:33:1 + --> $DIR/const_refers_to_static.rs:34:1 | LL | / const READ_IMMUT: &usize = { LL | | static FOO: usize = 0; diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs b/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs index b5d2b4396f9a9..2817abfcaa8de 100644 --- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs +++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -8,6 +8,7 @@ fn main() { match &b""[..] { ZST => {} //~ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern } } diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr index 5f84204f4086a..296a55ef16076 100644 --- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr +++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/transmute-size-mismatch-before-typeck.rs:14:29 + --> $DIR/transmute-size-mismatch-before-typeck.rs:15:29 | LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -15,7 +15,7 @@ LL | ZST => {} | ^^^ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-size-mismatch-before-typeck.rs:14:29 + --> $DIR/transmute-size-mismatch-before-typeck.rs:15:29 | LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^ @@ -23,6 +23,12 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; = note: source type: `usize` (word size) = note: target type: `&'static [u8]` (2 * word size) -error: aborting due to 3 previous errors +error: could not evaluate constant pattern + --> $DIR/transmute-size-mismatch-before-typeck.rs:10:9 + | +LL | ZST => {} + | ^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs index 6175b7df1107a..b2edc1a1f66ca 100644 --- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs +++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs @@ -3,6 +3,7 @@ trait Foo> { //~^ ERROR cycle detected + //~| ERROR cycle detected } fn main() { } diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr index e89d25742a0ac..6b38d85302e66 100644 --- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr +++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr @@ -11,6 +11,19 @@ note: cycle used when collecting item types in top-level module LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0391]: cycle detected when processing `Foo::X` + --> $DIR/cycle-trait-default-type-trait.rs:4:23 + | +LL | trait Foo> { + | ^^^ + | + = note: ...which again requires processing `Foo::X`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cycle-trait-default-type-trait.rs:4:1 + | +LL | trait Foo> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/deduplicate-diagnostics.rs b/src/test/ui/deduplicate-diagnostics.rs index 4a1f503d757a5..90ed344c11a26 100644 --- a/src/test/ui/deduplicate-diagnostics.rs +++ b/src/test/ui/deduplicate-diagnostics.rs @@ -1,5 +1,5 @@ // revisions: duplicate deduplicate -//[duplicate] compile-flags: -Z deduplicate-diagnostics=no +//[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes #[derive(Unresolved)] //~ ERROR cannot find derive macro `Unresolved` in this scope //[duplicate]~| ERROR cannot find derive macro `Unresolved` in this scope diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs index 2a5d09d4bb7ee..beef639462ed3 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs +++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs @@ -10,7 +10,11 @@ struct Error; #[derive(PartialOrd,PartialEq)] enum Enum { A { - x: Error //~ ERROR + x: Error //~ ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` } } diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr index 3f669c20176aa..80b896f4f043e 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr @@ -7,6 +7,42 @@ LL | x: Error = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` -error: aborting due to previous error +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.rs b/src/test/ui/derives/derives-span-PartialOrd-enum.rs index e69c18200d138..b02828da0d276 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum.rs +++ b/src/test/ui/derives/derives-span-PartialOrd-enum.rs @@ -10,7 +10,11 @@ struct Error; #[derive(PartialOrd,PartialEq)] enum Enum { A( - Error //~ ERROR + Error //~ ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` ) } diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr index a78af9e9cf8e4..f12038fb867a7 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr @@ -7,6 +7,42 @@ LL | Error = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` -error: aborting due to previous error +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum.rs:13:6 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum.rs:13:6 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum.rs:13:6 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-enum.rs:13:6 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-struct.rs index b5d1df932c539..bfcfc3d5dfdd7 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-struct.rs +++ b/src/test/ui/derives/derives-span-PartialOrd-struct.rs @@ -9,7 +9,11 @@ struct Error; #[derive(PartialOrd,PartialEq)] struct Struct { - x: Error //~ ERROR + x: Error //~ ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` } fn main() {} diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr index 8e85f1a01ffe6..dbb014752ec01 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr @@ -7,6 +7,42 @@ LL | x: Error = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` -error: aborting due to previous error +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-struct.rs:12:5 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-struct.rs:12:5 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-struct.rs:12:5 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-struct.rs:12:5 + | +LL | x: Error + | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs index 7dfb33b78e545..c8bdd6423a023 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs +++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs @@ -9,7 +9,11 @@ struct Error; #[derive(PartialOrd,PartialEq)] struct Struct( - Error //~ ERROR + Error //~ ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` + //~| ERROR can't compare `Error` with `Error` ); fn main() {} diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr index bf915781aa5ce..f6f1694bbf01e 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr @@ -7,6 +7,42 @@ LL | Error = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` -error: aborting due to previous error +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Error` with `Error` + --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 + | +LL | Error + | ^^^^^ no implementation for `Error < Error` and `Error > Error` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/derives/deriving-bounds.rs b/src/test/ui/derives/deriving-bounds.rs index 52659bd11e080..95d440420b065 100644 --- a/src/test/ui/derives/deriving-bounds.rs +++ b/src/test/ui/derives/deriving-bounds.rs @@ -1,9 +1,11 @@ #[derive(Send)] //~^ ERROR cannot find derive macro `Send` in this scope +//~| ERROR cannot find derive macro `Send` in this scope struct Test; #[derive(Sync)] //~^ ERROR cannot find derive macro `Sync` in this scope +//~| ERROR cannot find derive macro `Sync` in this scope struct Test1; pub fn main() {} diff --git a/src/test/ui/derives/deriving-bounds.stderr b/src/test/ui/derives/deriving-bounds.stderr index b18df3511817d..74ca37287d232 100644 --- a/src/test/ui/derives/deriving-bounds.stderr +++ b/src/test/ui/derives/deriving-bounds.stderr @@ -1,15 +1,39 @@ error: cannot find derive macro `Sync` in this scope - --> $DIR/deriving-bounds.rs:5:10 + --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] | ^^^^ | note: unsafe traits like `Sync` should be implemented explicitly - --> $DIR/deriving-bounds.rs:5:10 + --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] | ^^^^ +error: cannot find derive macro `Sync` in this scope + --> $DIR/deriving-bounds.rs:6:10 + | +LL | #[derive(Sync)] + | ^^^^ + | +note: unsafe traits like `Sync` should be implemented explicitly + --> $DIR/deriving-bounds.rs:6:10 + | +LL | #[derive(Sync)] + | ^^^^ + +error: cannot find derive macro `Send` in this scope + --> $DIR/deriving-bounds.rs:1:10 + | +LL | #[derive(Send)] + | ^^^^ + | +note: unsafe traits like `Send` should be implemented explicitly + --> $DIR/deriving-bounds.rs:1:10 + | +LL | #[derive(Send)] + | ^^^^ + error: cannot find derive macro `Send` in this scope --> $DIR/deriving-bounds.rs:1:10 | @@ -22,5 +46,5 @@ note: unsafe traits like `Send` should be implemented explicitly LL | #[derive(Send)] | ^^^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.rs b/src/test/ui/derives/deriving-meta-unknown-trait.rs index f4a6f3fd62a05..6463a7664de93 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.rs +++ b/src/test/ui/derives/deriving-meta-unknown-trait.rs @@ -1,5 +1,6 @@ #[derive(Eqr)] //~^ ERROR cannot find derive macro `Eqr` in this scope +//~| ERROR cannot find derive macro `Eqr` in this scope struct Foo; pub fn main() {} diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index 1b8e689c753f3..8d0f9e9fc89a8 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -4,5 +4,11 @@ error: cannot find derive macro `Eqr` in this scope LL | #[derive(Eqr)] | ^^^ help: a derive macro with a similar name exists: `Eq` -error: aborting due to previous error +error: cannot find derive macro `Eqr` in this scope + --> $DIR/deriving-meta-unknown-trait.rs:1:10 + | +LL | #[derive(Eqr)] + | ^^^ help: a derive macro with a similar name exists: `Eq` + +error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/deriving-primitive.rs b/src/test/ui/derives/deriving-primitive.rs index c7098d4b563bb..1173eca640fc3 100644 --- a/src/test/ui/derives/deriving-primitive.rs +++ b/src/test/ui/derives/deriving-primitive.rs @@ -1,4 +1,5 @@ #[derive(FromPrimitive)] //~ ERROR cannot find derive macro `FromPrimitive` in this scope + //~| ERROR cannot find derive macro `FromPrimitive` in this scope enum Foo {} fn main() {} diff --git a/src/test/ui/derives/deriving-primitive.stderr b/src/test/ui/derives/deriving-primitive.stderr index d1b444976ddcc..ca64c9ee732cb 100644 --- a/src/test/ui/derives/deriving-primitive.stderr +++ b/src/test/ui/derives/deriving-primitive.stderr @@ -4,5 +4,11 @@ error: cannot find derive macro `FromPrimitive` in this scope LL | #[derive(FromPrimitive)] | ^^^^^^^^^^^^^ -error: aborting due to previous error +error: cannot find derive macro `FromPrimitive` in this scope + --> $DIR/deriving-primitive.rs:1:10 + | +LL | #[derive(FromPrimitive)] + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs index 44421b077fa26..467daef63f6a6 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -5,8 +5,10 @@ fn test_and() { let b = false; let _ = a and b; //~ ERROR `and` is not a logical operator + //~| ERROR `and` is not a logical operator if a and b { //~ ERROR `and` is not a logical operator + //~| ERROR `and` is not a logical operator println!("both"); } @@ -18,8 +20,10 @@ fn test_or() { let b = false; let _ = a or b; //~ ERROR `or` is not a logical operator + //~| ERROR `or` is not a logical operator if a or b { //~ ERROR `or` is not a logical operator + //~| ERROR `or` is not a logical operator println!("both"); } } @@ -28,6 +32,7 @@ fn test_and_par() { let a = true; let b = false; if (a and b) { //~ ERROR `and` is not a logical operator + //~| ERROR `and` is not a logical operator println!("both"); } } @@ -36,6 +41,7 @@ fn test_or_par() { let a = true; let b = false; if (a or b) { //~ ERROR `or` is not a logical operator + //~| ERROR `or` is not a logical operator println!("both"); } } @@ -44,6 +50,7 @@ fn test_while_and() { let a = true; let b = false; while a and b { //~ ERROR `and` is not a logical operator + //~| ERROR `and` is not a logical operator println!("both"); } } @@ -52,6 +59,7 @@ fn test_while_or() { let a = true; let b = false; while a or b { //~ ERROR `or` is not a logical operator + //~| ERROR `or` is not a logical operator println!("both"); } } diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr index 528c62f501e0d..e8731cf238ec4 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -7,7 +7,23 @@ LL | let _ = a and b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15 + | +LL | let _ = a and b; + | ^^^ help: use `&&` to perform logical conjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `and` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10 + | +LL | if a and b { + | ^^^ help: use `&&` to perform logical conjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `and` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10 | LL | if a and b { | ^^^ help: use `&&` to perform logical conjunction @@ -15,7 +31,7 @@ LL | if a and b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 | LL | let _ = a or b; | ^^ help: use `||` to perform logical disjunction @@ -23,7 +39,23 @@ LL | let _ = a or b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 + | +LL | let _ = a or b; + | ^^ help: use `||` to perform logical disjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `or` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10 + | +LL | if a or b { + | ^^ help: use `||` to perform logical disjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `or` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10 | LL | if a or b { | ^^ help: use `||` to perform logical disjunction @@ -31,15 +63,31 @@ LL | if a or b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11 | LL | if (a and b) { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators +error: `and` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11 + | +LL | if (a and b) { + | ^^^ help: use `&&` to perform logical conjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `or` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11 + | +LL | if (a or b) { + | ^^ help: use `||` to perform logical disjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11 | LL | if (a or b) { | ^^ help: use `||` to perform logical disjunction @@ -47,15 +95,31 @@ LL | if (a or b) { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13 | LL | while a and b { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators +error: `and` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13 + | +LL | while a and b { + | ^^^ help: use `&&` to perform logical conjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + +error: `or` is not a logical operator + --> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13 + | +LL | while a or b { + | ^^ help: use `||` to perform logical disjunction + | + = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13 | LL | while a or b { | ^^ help: use `||` to perform logical disjunction @@ -63,13 +127,13 @@ LL | while a or b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error[E0308]: mismatched types - --> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:15:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer | | | expected due to this -error: aborting due to 9 previous errors +error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0030.rs b/src/test/ui/error-codes/E0030.rs index 58d856b7c9d23..a5d8f87261b2b 100644 --- a/src/test/ui/error-codes/E0030.rs +++ b/src/test/ui/error-codes/E0030.rs @@ -2,5 +2,6 @@ fn main() { match 5u32 { 1000 ..= 5 => {} //~^ ERROR lower range bound must be less than or equal to upper + //~| ERROR lower range bound must be less than or equal to upper } } diff --git a/src/test/ui/error-codes/E0030.stderr b/src/test/ui/error-codes/E0030.stderr index db8161d8fd5d8..8a6114024b630 100644 --- a/src/test/ui/error-codes/E0030.stderr +++ b/src/test/ui/error-codes/E0030.stderr @@ -4,6 +4,12 @@ error[E0030]: lower range bound must be less than or equal to upper LL | 1000 ..= 5 => {} | ^^^^ lower bound larger than upper bound -error: aborting due to previous error +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/E0030.rs:3:9 + | +LL | 1000 ..= 5 => {} + | ^^^^ lower bound larger than upper bound + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0030`. diff --git a/src/test/ui/error-codes/E0452.rs b/src/test/ui/error-codes/E0452.rs index 940b9f693cade..4e5a6c9301467 100644 --- a/src/test/ui/error-codes/E0452.rs +++ b/src/test/ui/error-codes/E0452.rs @@ -1,4 +1,8 @@ #![allow(foo = "")] //~ ERROR E0452 - + //~| ERROR E0452 + //~| ERROR E0452 + //~| ERROR E0452 + //~| ERROR E0452 + //~| ERROR E0452 fn main() { } diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr index 7f074168f8e02..30c11e3274e1c 100644 --- a/src/test/ui/error-codes/E0452.stderr +++ b/src/test/ui/error-codes/E0452.stderr @@ -4,6 +4,36 @@ error[E0452]: malformed lint attribute input LL | #![allow(foo = "")] | ^^^^^^^^ bad attribute argument -error: aborting due to previous error +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/error-codes/E0453.rs b/src/test/ui/error-codes/E0453.rs index 46fa04843ea03..69155b0688bc0 100644 --- a/src/test/ui/error-codes/E0453.rs +++ b/src/test/ui/error-codes/E0453.rs @@ -2,5 +2,7 @@ #[allow(non_snake_case)] //~^ ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) +//~| ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) +//~| ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) fn main() { } diff --git a/src/test/ui/error-codes/E0453.stderr b/src/test/ui/error-codes/E0453.stderr index 03cc756d6ac00..138e8483461c9 100644 --- a/src/test/ui/error-codes/E0453.stderr +++ b/src/test/ui/error-codes/E0453.stderr @@ -7,6 +7,24 @@ LL | LL | #[allow(non_snake_case)] | ^^^^^^^^^^^^^^ overruled by previous forbid -error: aborting due to previous error +error[E0453]: allow(non_snake_case) overruled by outer forbid(non_snake_case) + --> $DIR/E0453.rs:3:9 + | +LL | #![forbid(non_snake_case)] + | -------------- `forbid` level set here +LL | +LL | #[allow(non_snake_case)] + | ^^^^^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(non_snake_case) overruled by outer forbid(non_snake_case) + --> $DIR/E0453.rs:3:9 + | +LL | #![forbid(non_snake_case)] + | -------------- `forbid` level set here +LL | +LL | #[allow(non_snake_case)] + | ^^^^^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/error-codes/E0565.rs b/src/test/ui/error-codes/E0565.rs index b09f5df5201b1..3bf428676105d 100644 --- a/src/test/ui/error-codes/E0565.rs +++ b/src/test/ui/error-codes/E0565.rs @@ -1,5 +1,6 @@ // repr currently doesn't support literals #[repr("C")] //~ ERROR E0565 + //~| ERROR E0565 struct A { } fn main() { } diff --git a/src/test/ui/error-codes/E0565.stderr b/src/test/ui/error-codes/E0565.stderr index 6ed90c0ae4ffe..aa0951528e1ed 100644 --- a/src/test/ui/error-codes/E0565.stderr +++ b/src/test/ui/error-codes/E0565.stderr @@ -4,6 +4,12 @@ error[E0565]: meta item in `repr` must be an identifier LL | #[repr("C")] | ^^^ -error: aborting due to previous error +error[E0565]: meta item in `repr` must be an identifier + --> $DIR/E0565.rs:2:8 + | +LL | #[repr("C")] + | ^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/error-codes/E0602.stderr b/src/test/ui/error-codes/E0602.stderr index 8636004102618..70137cb166206 100644 --- a/src/test/ui/error-codes/E0602.stderr +++ b/src/test/ui/error-codes/E0602.stderr @@ -2,6 +2,14 @@ error[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` -error: aborting due to previous error +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0602`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.rs b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.rs index 5f276f6b65ebc..3276309f745c2 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.rs @@ -3,14 +3,17 @@ mod derive { #[derive(x3300)] //~^ ERROR cannot find derive macro `x3300` in this scope + //~| ERROR cannot find derive macro `x3300` in this scope union U { f: i32 } #[derive(x3300)] //~^ ERROR cannot find derive macro `x3300` in this scope + //~| ERROR cannot find derive macro `x3300` in this scope enum E { } #[derive(x3300)] //~^ ERROR cannot find derive macro `x3300` in this scope + //~| ERROR cannot find derive macro `x3300` in this scope struct S; } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr index f14591c85e62e..ab16591734471 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr @@ -1,11 +1,29 @@ error: cannot find derive macro `x3300` in this scope - --> $DIR/issue-43106-gating-of-derive-2.rs:12:14 + --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] | ^^^^^ error: cannot find derive macro `x3300` in this scope - --> $DIR/issue-43106-gating-of-derive-2.rs:8:14 + --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 + | +LL | #[derive(x3300)] + | ^^^^^ + +error: cannot find derive macro `x3300` in this scope + --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 + | +LL | #[derive(x3300)] + | ^^^^^ + +error: cannot find derive macro `x3300` in this scope + --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 + | +LL | #[derive(x3300)] + | ^^^^^ + +error: cannot find derive macro `x3300` in this scope + --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] | ^^^^^ @@ -16,5 +34,5 @@ error: cannot find derive macro `x3300` in this scope LL | #[derive(x3300)] | ^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs index 60873f9cc7581..a01d85515a8b7 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs @@ -18,6 +18,7 @@ mod rustc_deprecated { #[rustc_deprecated()] struct S; //~^ ERROR stability attributes may not be used outside of the standard library + //~| ERROR stability attributes may not be used outside of the standard library #[rustc_deprecated()] type T = S; //~^ ERROR stability attributes may not be used outside of the standard library diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr index 8c6c26f7b2d81..3c4dcfec02b12 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr @@ -29,17 +29,23 @@ LL | #[rustc_deprecated()] struct S; | ^^^^^^^^^^^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:22:5 + --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:19:5 + | +LL | #[rustc_deprecated()] struct S; + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:23:5 | LL | #[rustc_deprecated()] type T = S; | ^^^^^^^^^^^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:25:5 + --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:26:5 | LL | #[rustc_deprecated()] impl S { } | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs b/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs index e3ac2749306ab..73ff965307fd7 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs @@ -18,6 +18,7 @@ mod stable { #[stable()] struct S; //~^ ERROR stability attributes may not be used outside of the standard library + //~| ERROR stability attributes may not be used outside of the standard library #[stable()] type T = S; //~^ ERROR stability attributes may not be used outside of the standard library diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr index 09dabd293ff97..2573db1d684d9 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr @@ -29,17 +29,23 @@ LL | #[stable()] struct S; | ^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-stable.rs:22:5 + --> $DIR/issue-43106-gating-of-stable.rs:19:5 + | +LL | #[stable()] struct S; + | ^^^^^^^^^^^ + +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/issue-43106-gating-of-stable.rs:23:5 | LL | #[stable()] type T = S; | ^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-stable.rs:25:5 + --> $DIR/issue-43106-gating-of-stable.rs:26:5 | LL | #[stable()] impl S { } | ^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs index 8d519c3106c5e..d8339b00c12d2 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs @@ -18,6 +18,7 @@ mod unstable { #[unstable()] struct S; //~^ ERROR stability attributes may not be used outside of the standard library + //~| ERROR stability attributes may not be used outside of the standard library #[unstable()] type T = S; //~^ ERROR stability attributes may not be used outside of the standard library diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr index 49da2c59580e7..500675e054c3f 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr @@ -29,17 +29,23 @@ LL | #[unstable()] struct S; | ^^^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-unstable.rs:22:5 + --> $DIR/issue-43106-gating-of-unstable.rs:19:5 + | +LL | #[unstable()] struct S; + | ^^^^^^^^^^^^^ + +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/issue-43106-gating-of-unstable.rs:23:5 | LL | #[unstable()] type T = S; | ^^^^^^^^^^^^^ error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-unstable.rs:25:5 + --> $DIR/issue-43106-gating-of-unstable.rs:26:5 | LL | #[unstable()] impl S { } | ^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.rs b/src/test/ui/feature-gates/feature-gate-external_doc.rs index 9d68d3ec4f52a..4e6e293846c6e 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.rs +++ b/src/test/ui/feature-gates/feature-gate-external_doc.rs @@ -1,2 +1,3 @@ #[doc(include="asdf.md")] //~ ERROR: `#[doc(include)]` is experimental + //~| ERROR: `#[doc(include)]` is experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.stderr b/src/test/ui/feature-gates/feature-gate-external_doc.stderr index 683c0ad217426..05340184033e9 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.stderr +++ b/src/test/ui/feature-gates/feature-gate-external_doc.stderr @@ -7,6 +7,15 @@ LL | #[doc(include="asdf.md")] = note: for more information, see https://github.com/rust-lang/rust/issues/44732 = help: add `#![feature(external_doc)]` to the crate attributes to enable -error: aborting due to previous error +error[E0658]: `#[doc(include)]` is experimental + --> $DIR/feature-gate-external_doc.rs:1:1 + | +LL | #[doc(include="asdf.md")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44732 + = help: add `#![feature(external_doc)]` to the crate attributes to enable + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs index 1a7b9c990fa64..b124e9b2f4d71 100644 --- a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs +++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs @@ -1,4 +1,6 @@ #![warn(nonstandard_style, reason = "the standard should be respected")] //~^ ERROR lint reasons are experimental +//~| ERROR lint reasons are experimental +//~| ERROR lint reasons are experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr index 390a1bf580f6f..08ba9d0d3a313 100644 --- a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr +++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr @@ -7,6 +7,24 @@ LL | #![warn(nonstandard_style, reason = "the standard should be respected")] = note: for more information, see https://github.com/rust-lang/rust/issues/54503 = help: add `#![feature(lint_reasons)]` to the crate attributes to enable -error: aborting due to previous error +error[E0658]: lint reasons are experimental + --> $DIR/feature-gate-lint-reasons.rs:1:28 + | +LL | #![warn(nonstandard_style, reason = "the standard should be respected")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/54503 + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + +error[E0658]: lint reasons are experimental + --> $DIR/feature-gate-lint-reasons.rs:1:28 + | +LL | #![warn(nonstandard_style, reason = "the standard should be respected")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/54503 + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/generator/auto-trait-regions.rs b/src/test/ui/generator/auto-trait-regions.rs index 46d7289943857..dbd8965dcf0d0 100644 --- a/src/test/ui/generator/auto-trait-regions.rs +++ b/src/test/ui/generator/auto-trait-regions.rs @@ -29,6 +29,7 @@ fn main() { }; assert_foo(gen); //~^ ERROR implementation of `Foo` is not general enough + //~| ERROR implementation of `Foo` is not general enough // Allow impls which matches any lifetime let x = &OnlyFooIfRef(No); @@ -47,4 +48,5 @@ fn main() { }; assert_foo(gen); //~^ ERROR not general enough + //~| ERROR not general enough } diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index dab4d348ceb60..29a3907d93c84 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -11,7 +11,31 @@ LL | assert_foo(gen); = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:48:5 + --> $DIR/auto-trait-regions.rs:30:5 + | +LL | auto trait Foo {} + | ----------------- trait `Foo` defined here +... +LL | assert_foo(gen); + | ^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`... + = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` + +error: implementation of `Foo` is not general enough + --> $DIR/auto-trait-regions.rs:49:5 + | +LL | auto trait Foo {} + | ----------------- trait `Foo` defined here +... +LL | assert_foo(gen); + | ^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` + +error: implementation of `Foo` is not general enough + --> $DIR/auto-trait-regions.rs:49:5 | LL | auto trait Foo {} | ----------------- trait `Foo` defined here @@ -22,5 +46,5 @@ LL | assert_foo(gen); = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs index 63db695f7e67c..0303a764c12de 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs @@ -44,6 +44,7 @@ fn foo_hrtb_bar_not<'b,T>(mut t: T) // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where // clause only specifies `T : Bar<&'b isize>`. foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types + //~| ERROR mismatched types } fn foo_hrtb_bar_hrtb(mut t: T) diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index 9bc8cd67a82af..1ceb0c99e90e9 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -7,6 +7,15 @@ LL | foo_hrtb_bar_not(&mut t); = note: expected type `Bar<&'a isize>` found type `Bar<&'b isize>` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/hrtb-perfect-forwarding.rs:46:5 + | +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `Bar<&'a isize>` + found type `Bar<&'b isize>` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index cd1272da2a66e..c736c5479f848 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -11,10 +11,46 @@ LL | let filter = map.filter(|x: &_| true); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:116:17 + --> $DIR/issue-30786.rs:114:18 + | +LL | let filter = map.filter(|x: &_| true); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:114:18 + | +LL | let filter = map.filter(|x: &_| true); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:114:18 + | +LL | let filter = map.filter(|x: &_| true); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:119:17 + | +LL | let count = filter.count(); // Assert that we still have a valid stream. + | ^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:119:17 + | +LL | let count = filter.count(); // Assert that we still have a valid stream. + | ^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:119:17 + | +LL | let count = filter.count(); // Assert that we still have a valid stream. + | ^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:119:17 | LL | let count = filter.count(); // Assert that we still have a valid stream. | ^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index 34d6b19f602f7..c656f84306536 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -113,7 +113,12 @@ fn main() { //[migrate]~| NOTE implementation of `Stream` is not general enough let filter = map.filter(|x: &_| true); //[nll]~^ ERROR higher-ranked subtype error + //[nll]~| ERROR higher-ranked subtype error + //[nll]~| ERROR higher-ranked subtype error + //[nll]~| ERROR higher-ranked subtype error let count = filter.count(); // Assert that we still have a valid stream. //[nll]~^ ERROR higher-ranked subtype error - + //[nll]~| ERROR higher-ranked subtype error + //[nll]~| ERROR higher-ranked subtype error + //[nll]~| ERROR higher-ranked subtype error } diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index 1c601bc3c34ea..a6012835f441e 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -12,6 +12,7 @@ fn main() { fn cycle1() -> impl Clone { //~^ ERROR cycle detected //~| ERROR cycle detected + //~| ERROR cycle detected send(cycle2().clone()); //~^ ERROR cannot be sent between threads safely diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index d11941fee1824..f5e4820feb2d2 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -11,12 +11,12 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires processing `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:21:16 + --> $DIR/auto-trait-leak.rs:22:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:21:1 + --> $DIR/auto-trait-leak.rs:22:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,12 +47,47 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires processing `cycle2::{{opaque}}#0`... - --> $DIR/auto-trait-leak.rs:21:16 + --> $DIR/auto-trait-leak.rs:22:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:21:1 + --> $DIR/auto-trait-leak.rs:22:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/auto-trait-leak.rs:1:1 + | +LL | / use std::cell::Cell; +LL | | use std::rc::Rc; +LL | | +LL | | fn send(_: T) {} +... | +LL | | Rc::new(String::from("foo")) +LL | | } + | |_^ + +error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0` + --> $DIR/auto-trait-leak.rs:12:16 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^ + | +note: ...which requires processing `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... +note: ...which requires processing `cycle2::{{opaque}}#0`... + --> $DIR/auto-trait-leak.rs:22:16 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^ +note: ...which requires processing `cycle2`... + --> $DIR/auto-trait-leak.rs:22:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +105,7 @@ LL | | } | |_^ error[E0277]: `std::rc::Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leak.rs:15:5 + --> $DIR/auto-trait-leak.rs:16:5 | LL | fn send(_: T) {} | ---- ---- required by this bound in `send` @@ -81,7 +116,7 @@ LL | send(cycle2().clone()); = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc` = note: required because it appears within the type `impl std::clone::Clone` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0391. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/imports/issue-55457.rs b/src/test/ui/imports/issue-55457.rs index 9c6750fd48c26..c1f048897d9ea 100644 --- a/src/test/ui/imports/issue-55457.rs +++ b/src/test/ui/imports/issue-55457.rs @@ -3,6 +3,8 @@ use non_existent::non_existent; //~ ERROR unresolved import `non_existent` #[non_existent] //~ ERROR cannot determine resolution for the attribute macro `non_existent` #[derive(NonExistent)] //~ ERROR cannot determine resolution for the derive macro `NonExistent` + //~| ERROR cannot determine resolution for the derive macro `NonExistent` + //~| ERROR cannot determine resolution for the derive macro `NonExistent` struct S; fn main() {} diff --git a/src/test/ui/imports/issue-55457.stderr b/src/test/ui/imports/issue-55457.stderr index aa103ba01e34e..07de3d95902ef 100644 --- a/src/test/ui/imports/issue-55457.stderr +++ b/src/test/ui/imports/issue-55457.stderr @@ -29,6 +29,22 @@ LL | #[non_existent] | = note: import resolution is stuck, try simplifying macro imports -error: aborting due to 4 previous errors +error: cannot determine resolution for the derive macro `NonExistent` + --> $DIR/issue-55457.rs:5:10 + | +LL | #[derive(NonExistent)] + | ^^^^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `NonExistent` + --> $DIR/issue-55457.rs:5:10 + | +LL | #[derive(NonExistent)] + | ^^^^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.rs b/src/test/ui/imports/local-modularized-tricky-fail-1.rs index 29e9b8ec841f5..37fe0eceed6b8 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.rs +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.rs @@ -26,6 +26,7 @@ mod inner1 { } exported!(); //~ ERROR `exported` is ambiguous + //~| ERROR `exported` is ambiguous mod inner2 { define_exported!(); diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index 7d013828bd908..c9498fed6a58e 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -21,8 +21,31 @@ LL | use inner1::*; | ^^^^^^^^^ = help: consider adding an explicit import of `exported` to disambiguate +error[E0659]: `exported` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution) + --> $DIR/local-modularized-tricky-fail-1.rs:28:1 + | +LL | exported!(); + | ^^^^^^^^ ambiguous name + | +note: `exported` could refer to the macro defined here + --> $DIR/local-modularized-tricky-fail-1.rs:5:5 + | +LL | / macro_rules! exported { +LL | | () => () +LL | | } + | |_____^ +... +LL | define_exported!(); + | ------------------- in this macro invocation +note: `exported` could also refer to the macro imported here + --> $DIR/local-modularized-tricky-fail-1.rs:22:5 + | +LL | use inner1::*; + | ^^^^^^^^^ + = help: consider adding an explicit import of `exported` to disambiguate + error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:35:5 + --> $DIR/local-modularized-tricky-fail-1.rs:36:5 | LL | panic!(); | ^^^^^ ambiguous name @@ -41,7 +64,7 @@ LL | define_panic!(); = help: use `crate::panic` to refer to this macro unambiguously error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:46:1 + --> $DIR/local-modularized-tricky-fail-1.rs:47:1 | LL | include!(); | ^^^^^^^ ambiguous name @@ -59,6 +82,6 @@ LL | define_include!(); | ------------------ in this macro invocation = help: use `crate::include` to refer to this macro unambiguously -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/imports/macros.rs b/src/test/ui/imports/macros.rs index f2a22ad620b11..f39711898cdf0 100644 --- a/src/test/ui/imports/macros.rs +++ b/src/test/ui/imports/macros.rs @@ -14,6 +14,7 @@ mod m1 { mod m2 { use two_macros::*; m! { //~ ERROR ambiguous + //~| ERROR ambiguous use foo::m; } } diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index 3b9e6feebd7e3..27b34fe0c01fa 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -5,7 +5,25 @@ LL | m! { | ^ ambiguous name | note: `m` could refer to the macro imported here - --> $DIR/macros.rs:17:13 + --> $DIR/macros.rs:18:13 + | +LL | use foo::m; + | ^^^^^^ +note: `m` could also refer to the macro imported here + --> $DIR/macros.rs:15:9 + | +LL | use two_macros::*; + | ^^^^^^^^^^^^^ + = help: consider adding an explicit import of `m` to disambiguate + +error[E0659]: `m` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution) + --> $DIR/macros.rs:16:5 + | +LL | m! { + | ^ ambiguous name + | +note: `m` could refer to the macro imported here + --> $DIR/macros.rs:18:13 | LL | use foo::m; | ^^^^^^ @@ -17,23 +35,23 @@ LL | use two_macros::*; = help: consider adding an explicit import of `m` to disambiguate error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/macros.rs:29:9 + --> $DIR/macros.rs:30:9 | LL | m! { | ^ ambiguous name | note: `m` could refer to the macro imported here - --> $DIR/macros.rs:30:17 + --> $DIR/macros.rs:31:17 | LL | use two_macros::n as m; | ^^^^^^^^^^^^^^^^^^ note: `m` could also refer to the macro imported here - --> $DIR/macros.rs:22:9 + --> $DIR/macros.rs:23:9 | LL | use two_macros::m; | ^^^^^^^^^^^^^ = help: use `self::m` to refer to this macro unambiguously -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/issues/issue-17718-const-bad-values.rs b/src/test/ui/issues/issue-17718-const-bad-values.rs index 97657f8848155..9355c8ab15256 100644 --- a/src/test/ui/issues/issue-17718-const-bad-values.rs +++ b/src/test/ui/issues/issue-17718-const-bad-values.rs @@ -4,6 +4,7 @@ const C1: &'static mut [usize] = &mut []; static mut S: usize = 3; const C2: &'static mut usize = unsafe { &mut S }; //~^ ERROR: constants cannot refer to statics +//~| ERROR: constants cannot refer to statics //~| ERROR: references in constants may only refer to immutable values fn main() {} diff --git a/src/test/ui/issues/issue-17718-const-bad-values.stderr b/src/test/ui/issues/issue-17718-const-bad-values.stderr index 7e4a62ac96957..14bf5dc38b47a 100644 --- a/src/test/ui/issues/issue-17718-const-bad-values.stderr +++ b/src/test/ui/issues/issue-17718-const-bad-values.stderr @@ -13,6 +13,12 @@ error[E0013]: constants cannot refer to statics, use a constant instead LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ +error[E0013]: constants cannot refer to statics, use a constant instead + --> $DIR/issue-17718-const-bad-values.rs:5:46 + | +LL | const C2: &'static mut usize = unsafe { &mut S }; + | ^ + error[E0658]: references in constants may only refer to immutable values --> $DIR/issue-17718-const-bad-values.rs:5:41 | @@ -22,7 +28,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; = note: for more information, see https://github.com/rust-lang/rust/issues/57349 = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0013, E0658. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/issues/issue-20831-debruijn.rs b/src/test/ui/issues/issue-20831-debruijn.rs index ef4b1581fd874..d0e15cb393ae8 100644 --- a/src/test/ui/issues/issue-20831-debruijn.rs +++ b/src/test/ui/issues/issue-20831-debruijn.rs @@ -28,6 +28,7 @@ impl<'a> Publisher<'a> for MyStruct<'a> { fn subscribe(&mut self, t : Box::Output> + 'a>) { // Not obvious, but there is an implicit lifetime here -------^ //~^^ ERROR cannot infer + //~| ERROR cannot infer //~| ERROR mismatched types //~| ERROR mismatched types // diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index c7fd134a129de..a4ea1cd9834c8 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -102,7 +102,49 @@ LL | | } = note: expected `Publisher<'_>` found `Publisher<'_>` -error: aborting due to 3 previous errors +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { +LL | | // Not obvious, but there is an implicit lifetime here -------^ +LL | | +LL | | +... | +LL | | self.sub = t; +LL | | } + | |_____^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5... + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { +LL | | // Not obvious, but there is an implicit lifetime here -------^ +LL | | +LL | | +... | +LL | | self.sub = t; +LL | | } + | |_____^ +note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6... + --> $DIR/issue-20831-debruijn.rs:26:6 + | +LL | impl<'a> Publisher<'a> for MyStruct<'a> { + | ^^ +note: ...so that the types are compatible + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { +LL | | // Not obvious, but there is an implicit lifetime here -------^ +LL | | +LL | | +... | +LL | | self.sub = t; +LL | | } + | |_____^ + = note: expected `Publisher<'_>` + found `Publisher<'_>` + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0495. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-32963.rs b/src/test/ui/issues/issue-32963.rs index ee099069f0241..3e6cf446da3f7 100644 --- a/src/test/ui/issues/issue-32963.rs +++ b/src/test/ui/issues/issue-32963.rs @@ -7,5 +7,6 @@ fn size_of_copy() -> usize { mem::size_of::() } fn main() { size_of_copy::(); //~^ ERROR only auto traits can be used as additional traits in a trait object + //~| ERROR only auto traits can be used as additional traits in a trait object //~| ERROR the trait bound `dyn Misc: std::marker::Copy` is not satisfied } diff --git a/src/test/ui/issues/issue-32963.stderr b/src/test/ui/issues/issue-32963.stderr index e3564e8670174..450c37f456a80 100644 --- a/src/test/ui/issues/issue-32963.stderr +++ b/src/test/ui/issues/issue-32963.stderr @@ -9,6 +9,17 @@ LL | size_of_copy::(); | first non-auto trait | trait alias used in trait object type (first use) +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/issue-32963.rs:8:31 + | +LL | size_of_copy::(); + | ---- ^^^^ + | | | + | | additional non-auto trait + | | trait alias used in trait object type (additional use) + | first non-auto trait + | trait alias used in trait object type (first use) + error[E0277]: the trait bound `dyn Misc: std::marker::Copy` is not satisfied --> $DIR/issue-32963.rs:8:5 | @@ -18,7 +29,7 @@ LL | fn size_of_copy() -> usize { mem::size_of::() } LL | size_of_copy::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `dyn Misc` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0225, E0277. For more information about an error, try `rustc --explain E0225`. diff --git a/src/test/ui/issues/issue-33571.rs b/src/test/ui/issues/issue-33571.rs index 147fb3fa8cf33..2713f47ad2ff6 100644 --- a/src/test/ui/issues/issue-33571.rs +++ b/src/test/ui/issues/issue-33571.rs @@ -1,5 +1,6 @@ #[derive(Clone, Sync, //~ ERROR cannot find derive macro `Sync` in this scope + //~| ERROR cannot find derive macro `Sync` in this scope Copy)] enum Foo {} diff --git a/src/test/ui/issues/issue-33571.stderr b/src/test/ui/issues/issue-33571.stderr index 78e7202077498..2a9ba5ba71b8f 100644 --- a/src/test/ui/issues/issue-33571.stderr +++ b/src/test/ui/issues/issue-33571.stderr @@ -10,5 +10,17 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | Sync, | ^^^^ -error: aborting due to previous error +error: cannot find derive macro `Sync` in this scope + --> $DIR/issue-33571.rs:2:10 + | +LL | Sync, + | ^^^^ + | +note: unsafe traits like `Sync` should be implemented explicitly + --> $DIR/issue-33571.rs:2:10 + | +LL | Sync, + | ^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-34229.rs b/src/test/ui/issues/issue-34229.rs index 13e627a492f40..625fcb0a6f607 100644 --- a/src/test/ui/issues/issue-34229.rs +++ b/src/test/ui/issues/issue-34229.rs @@ -1,5 +1,9 @@ #[derive(PartialEq)] struct Comparable; #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); //~^ ERROR can't compare `Comparable` +//~| ERROR can't compare `Comparable` +//~| ERROR can't compare `Comparable` +//~| ERROR can't compare `Comparable` +//~| ERROR can't compare `Comparable` fn main() {} diff --git a/src/test/ui/issues/issue-34229.stderr b/src/test/ui/issues/issue-34229.stderr index c57f80cd4091c..9e1734899bdd2 100644 --- a/src/test/ui/issues/issue-34229.stderr +++ b/src/test/ui/issues/issue-34229.stderr @@ -7,6 +7,42 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` -error: aborting due to previous error +error[E0277]: can't compare `Comparable` with `Comparable` + --> $DIR/issue-34229.rs:2:46 + | +LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Comparable` with `Comparable` + --> $DIR/issue-34229.rs:2:46 + | +LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Comparable` with `Comparable` + --> $DIR/issue-34229.rs:2:46 + | +LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `Comparable` with `Comparable` + --> $DIR/issue-34229.rs:2:46 + | +LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-36617.rs b/src/test/ui/issues/issue-36617.rs index 1102f3c4640a1..58f44f42524bc 100644 --- a/src/test/ui/issues/issue-36617.rs +++ b/src/test/ui/issues/issue-36617.rs @@ -1,4 +1,5 @@ #![derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions //~| ERROR cannot determine resolution for the derive macro `Copy` + //~| ERROR cannot determine resolution for the derive macro `Copy` fn main() {} diff --git a/src/test/ui/issues/issue-36617.stderr b/src/test/ui/issues/issue-36617.stderr index b5db98f306bd3..98b41b07ea98a 100644 --- a/src/test/ui/issues/issue-36617.stderr +++ b/src/test/ui/issues/issue-36617.stderr @@ -12,5 +12,13 @@ LL | #![derive(Copy)] | = note: import resolution is stuck, try simplifying macro imports -error: aborting due to 2 previous errors +error: cannot determine resolution for the derive macro `Copy` + --> $DIR/issue-36617.rs:1:11 + | +LL | #![derive(Copy)] + | ^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-41255.rs b/src/test/ui/issues/issue-41255.rs index 60fdf7c3e8a47..478e13bb177f6 100644 --- a/src/test/ui/issues/issue-41255.rs +++ b/src/test/ui/issues/issue-41255.rs @@ -12,16 +12,28 @@ fn main() { //~| ERROR floating-point types cannot be used in patterns //~| WARNING this was previously accepted by the compiler but is being 5.0f32 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error //~| WARNING hard error -5.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error //~| WARNING hard error 1.0 .. 33.0 => {}, //~ ERROR floating-point types cannot be used in patterns //~| WARNING hard error //~| ERROR floating-point types cannot be used in patterns //~| WARNING hard error + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error 39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns //~| WARNING hard error //~| ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| WARNING hard error //~| WARNING hard error _ => {}, }; @@ -29,6 +41,8 @@ fn main() { // Same for tuples match (x, 5) { (3.14, 1) => {}, //~ ERROR floating-point types cannot be used + //~| ERROR floating-point types cannot be used + //~| WARNING hard error //~| WARNING hard error _ => {}, } @@ -36,6 +50,8 @@ fn main() { struct Foo { x: f32 }; match (Foo { x }) { Foo { x: 2.0 } => {}, //~ ERROR floating-point types cannot be used + //~| ERROR floating-point types cannot be used + //~| WARNING hard error //~| WARNING hard error _ => {}, } diff --git a/src/test/ui/issues/issue-41255.stderr b/src/test/ui/issues/issue-41255.stderr index c334742cfc4a4..4f24456c169b8 100644 --- a/src/test/ui/issues/issue-41255.stderr +++ b/src/test/ui/issues/issue-41255.stderr @@ -22,7 +22,7 @@ LL | 5.0f32 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:16:10 + --> $DIR/issue-41255.rs:18:10 | LL | -5.0 => {}, | ^^^ @@ -31,7 +31,7 @@ LL | -5.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:18:9 + --> $DIR/issue-41255.rs:22:9 | LL | 1.0 .. 33.0 => {}, | ^^^ @@ -40,7 +40,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:18:16 + --> $DIR/issue-41255.rs:22:16 | LL | 1.0 .. 33.0 => {}, | ^^^^ @@ -49,7 +49,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:9 + --> $DIR/issue-41255.rs:30:9 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -58,7 +58,7 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:18 + --> $DIR/issue-41255.rs:30:18 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -67,7 +67,7 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:31:10 + --> $DIR/issue-41255.rs:43:10 | LL | (3.14, 1) => {}, | ^^^^ @@ -76,7 +76,7 @@ LL | (3.14, 1) => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:38:18 + --> $DIR/issue-41255.rs:52:18 | LL | Foo { x: 2.0 } => {}, | ^^^ @@ -93,5 +93,77 @@ LL | 5.0 => {}, = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 -error: aborting due to 10 previous errors +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:14:9 + | +LL | 5.0f32 => {}, + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:18:10 + | +LL | -5.0 => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:22:9 + | +LL | 1.0 .. 33.0 => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:22:16 + | +LL | 1.0 .. 33.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:30:9 + | +LL | 39.0 ..= 70.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:30:18 + | +LL | 39.0 ..= 70.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:43:10 + | +LL | (3.14, 1) => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:52:18 + | +LL | Foo { x: 2.0 } => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: aborting due to 18 previous errors diff --git a/src/test/ui/issues/issue-43105.rs b/src/test/ui/issues/issue-43105.rs index f61b65baac419..231af76fc932d 100644 --- a/src/test/ui/issues/issue-43105.rs +++ b/src/test/ui/issues/issue-43105.rs @@ -8,6 +8,7 @@ fn main() { match 1 { NUM => unimplemented!(), //~^ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern _ => unimplemented!(), } } diff --git a/src/test/ui/issues/issue-43105.stderr b/src/test/ui/issues/issue-43105.stderr index e3609c57dcec5..1a7b67b563d52 100644 --- a/src/test/ui/issues/issue-43105.stderr +++ b/src/test/ui/issues/issue-43105.stderr @@ -20,6 +20,12 @@ error: could not evaluate constant pattern LL | NUM => unimplemented!(), | ^^^ -error: aborting due to 3 previous errors +error: could not evaluate constant pattern + --> $DIR/issue-43105.rs:9:9 + | +LL | NUM => unimplemented!(), + | ^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/issues/issue-46101.rs b/src/test/ui/issues/issue-46101.rs index 8b1343b1326b4..7c8bf299db581 100644 --- a/src/test/ui/issues/issue-46101.rs +++ b/src/test/ui/issues/issue-46101.rs @@ -1,6 +1,7 @@ #![feature(use_extern_macros)] trait Foo {} #[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro + //~| ERROR failed to resolve: partially resolved path in a derive macro struct S; fn main() {} diff --git a/src/test/ui/issues/issue-46101.stderr b/src/test/ui/issues/issue-46101.stderr index 9c88d3b87c907..2ffa15264b66d 100644 --- a/src/test/ui/issues/issue-46101.stderr +++ b/src/test/ui/issues/issue-46101.stderr @@ -4,6 +4,12 @@ error[E0433]: failed to resolve: partially resolved path in a derive macro LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ partially resolved path in a derive macro -error: aborting due to previous error +error[E0433]: failed to resolve: partially resolved path in a derive macro + --> $DIR/issue-46101.rs:3:10 + | +LL | #[derive(Foo::Anything)] + | ^^^^^^^^^^^^^ partially resolved path in a derive macro + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/issues/issue-50480.rs b/src/test/ui/issues/issue-50480.rs index 31dbb75ec1cc4..deb63872f6968 100644 --- a/src/test/ui/issues/issue-50480.rs +++ b/src/test/ui/issues/issue-50480.rs @@ -2,6 +2,7 @@ //~^ ERROR the trait `Copy` may not be implemented for this type struct Foo(NotDefined, ::Item, Vec, String); //~^ ERROR cannot find type `NotDefined` in this scope +//~| ERROR cannot find type `NotDefined` in this scope //~| ERROR `i32` is not an iterator fn main() {} diff --git a/src/test/ui/issues/issue-50480.stderr b/src/test/ui/issues/issue-50480.stderr index 9022bfae509f5..2b92664d57772 100644 --- a/src/test/ui/issues/issue-50480.stderr +++ b/src/test/ui/issues/issue-50480.stderr @@ -4,6 +4,12 @@ error[E0412]: cannot find type `NotDefined` in this scope LL | struct Foo(NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope +error[E0412]: cannot find type `NotDefined` in this scope + --> $DIR/issue-50480.rs:3:12 + | +LL | struct Foo(NotDefined, ::Item, Vec, String); + | ^^^^^^^^^^ not found in this scope + error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:3:24 | @@ -24,7 +30,7 @@ LL | struct Foo(NotDefined, ::Item, Vec, String); | | | this field does not implement `Copy` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0204, E0277, E0412. For more information about an error, try `rustc --explain E0204`. diff --git a/src/test/ui/issues/issue-53251.rs b/src/test/ui/issues/issue-53251.rs index 0751b0a635b3e..b5d55141b7509 100644 --- a/src/test/ui/issues/issue-53251.rs +++ b/src/test/ui/issues/issue-53251.rs @@ -10,6 +10,7 @@ macro_rules! impl_add { fn $n() { S::f::(); //~^ ERROR wrong number of type arguments + //~| ERROR wrong number of type arguments } )* } diff --git a/src/test/ui/issues/issue-53251.stderr b/src/test/ui/issues/issue-53251.stderr index 9fbffaf39e551..21e41574a4683 100644 --- a/src/test/ui/issues/issue-53251.stderr +++ b/src/test/ui/issues/issue-53251.stderr @@ -7,6 +7,15 @@ LL | S::f::(); LL | impl_add!(a b); | --------------- in this macro invocation -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/issue-53251.rs:11:24 + | +LL | S::f::(); + | ^^^ unexpected type argument +... +LL | impl_add!(a b); + | --------------- in this macro invocation + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs index e98a4d0e491a3..8ab47a4af1d2e 100644 --- a/src/test/ui/issues/issue-59029-1.rs +++ b/src/test/ui/issues/issue-59029-1.rs @@ -4,5 +4,6 @@ trait Svc { type Res; } trait MkSvc = Svc where Self::Res: Svc; //~^ ERROR associated type `Res` not found for `Self` +//~| ERROR associated type `Res` not found for `Self` fn main() {} diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr index fb1de9759c5cf..53cdb8b1baf4c 100644 --- a/src/test/ui/issues/issue-59029-1.stderr +++ b/src/test/ui/issues/issue-59029-1.stderr @@ -4,6 +4,12 @@ error[E0220]: associated type `Res` not found for `Self` LL | trait MkSvc = Svc where Self::Res: Svc; | ^^^ associated type `Res` not found -error: aborting due to previous error +error[E0220]: associated type `Res` not found for `Self` + --> $DIR/issue-59029-1.rs:5:52 + | +LL | trait MkSvc = Svc where Self::Res: Svc; + | ^^^ associated type `Res` not found + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-62554.rs b/src/test/ui/issues/issue-62554.rs index 20e84ec364b65..cfd02183cb4a8 100644 --- a/src/test/ui/issues/issue-62554.rs +++ b/src/test/ui/issues/issue-62554.rs @@ -1,5 +1,6 @@ +// error-pattern:this file contains an unclosed delimiter +// error-pattern:xpected `{`, found `macro_rules` + fn main() {} fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { -//~^ ERROR expected `{`, found `macro_rules` -//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/issues/issue-62554.stderr b/src/test/ui/issues/issue-62554.stderr index 692bfe02275a8..935d3842cdf61 100644 --- a/src/test/ui/issues/issue-62554.stderr +++ b/src/test/ui/issues/issue-62554.stderr @@ -1,18 +1,60 @@ error: this file contains an unclosed delimiter - --> $DIR/issue-62554.rs:5:52 + --> $DIR/issue-62554.rs:6:89 | LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { - | - - - - - unclosed delimiter - | | | | | + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter | | | | unclosed delimiter | | | unclosed delimiter | unclosed delimiter unclosed delimiter -LL | -LL | - | ^ error: expected `{`, found `macro_rules` - --> $DIR/issue-62554.rs:3:23 + --> $DIR/issue-62554.rs:6:23 | LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { | -- ^^^^^^^^^^^ expected `{` @@ -22,10 +64,8 @@ LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s help: try placing this code inside a block | LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { -LL | -LL | LL | } | -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/issues/issue-6804.rs b/src/test/ui/issues/issue-6804.rs index b4af3581a0de0..325137327b269 100644 --- a/src/test/ui/issues/issue-6804.rs +++ b/src/test/ui/issues/issue-6804.rs @@ -17,7 +17,9 @@ fn main() { match [x, 1.0] { [NAN, _] => {}, //~ ERROR floating-point types cannot be used - //~^ WARN this was previously accepted by the compiler but is being phased out + //~| ERROR floating-point types cannot be used + //~| WARN this was previously accepted by the compiler but is being phased out + //~| WARN this was previously accepted by the compiler but is being phased out _ => {}, }; } diff --git a/src/test/ui/issues/issue-6804.stderr b/src/test/ui/issues/issue-6804.stderr index ab4467e5135ed..f4188dc3566c2 100644 --- a/src/test/ui/issues/issue-6804.stderr +++ b/src/test/ui/issues/issue-6804.stderr @@ -30,5 +30,14 @@ LL | NAN => {}, = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 -error: aborting due to 3 previous errors +error: floating-point types cannot be used in patterns + --> $DIR/issue-6804.rs:19:10 + | +LL | [NAN, _] => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/lint-forbid-attr.rs b/src/test/ui/lint/lint-forbid-attr.rs index 082b5430bf471..13b28e8830b62 100644 --- a/src/test/ui/lint/lint-forbid-attr.rs +++ b/src/test/ui/lint/lint-forbid-attr.rs @@ -2,5 +2,7 @@ #[allow(deprecated)] //~^ ERROR allow(deprecated) overruled by outer forbid(deprecated) +//~| ERROR allow(deprecated) overruled by outer forbid(deprecated) +//~| ERROR allow(deprecated) overruled by outer forbid(deprecated) fn main() { } diff --git a/src/test/ui/lint/lint-forbid-attr.stderr b/src/test/ui/lint/lint-forbid-attr.stderr index 6e1e2b3e1478b..bf138c317e93d 100644 --- a/src/test/ui/lint/lint-forbid-attr.stderr +++ b/src/test/ui/lint/lint-forbid-attr.stderr @@ -7,6 +7,24 @@ LL | LL | #[allow(deprecated)] | ^^^^^^^^^^ overruled by previous forbid -error: aborting due to previous error +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-attr.rs:3:9 + | +LL | #![forbid(deprecated)] + | ---------- `forbid` level set here +LL | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-attr.rs:3:9 + | +LL | #![forbid(deprecated)] + | ---------- `forbid` level set here +LL | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/lint-forbid-cmdline.rs b/src/test/ui/lint/lint-forbid-cmdline.rs index 150685c3186aa..821470c86860a 100644 --- a/src/test/ui/lint/lint-forbid-cmdline.rs +++ b/src/test/ui/lint/lint-forbid-cmdline.rs @@ -1,5 +1,7 @@ // compile-flags: -F deprecated #[allow(deprecated)] //~ ERROR allow(deprecated) overruled by outer forbid(deprecated) + //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) + //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) fn main() { } diff --git a/src/test/ui/lint/lint-forbid-cmdline.stderr b/src/test/ui/lint/lint-forbid-cmdline.stderr index bece4775abb93..89a4445d80068 100644 --- a/src/test/ui/lint/lint-forbid-cmdline.stderr +++ b/src/test/ui/lint/lint-forbid-cmdline.stderr @@ -6,6 +6,22 @@ LL | #[allow(deprecated)] | = note: `forbid` lint level was set on command line -error: aborting due to previous error +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-cmdline.rs:3:9 + | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-cmdline.rs:3:9 + | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/lint-malformed.rs b/src/test/ui/lint/lint-malformed.rs index 0d327677d5469..cf5570753d85d 100644 --- a/src/test/ui/lint/lint-malformed.rs +++ b/src/test/ui/lint/lint-malformed.rs @@ -1,4 +1,8 @@ #![deny = "foo"] //~ ERROR malformed `deny` attribute input #![allow(bar = "baz")] //~ ERROR malformed lint attribute - + //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute fn main() { } diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr index f4876290ddb5d..6dc8d4984445e 100644 --- a/src/test/ui/lint/lint-malformed.stderr +++ b/src/test/ui/lint/lint-malformed.stderr @@ -4,12 +4,42 @@ error[E0452]: malformed lint attribute input LL | #![allow(bar = "baz")] | ^^^^^^^^^^^ bad attribute argument +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + error: malformed `deny` attribute input --> $DIR/lint-malformed.rs:1:1 | LL | #![deny = "foo"] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` -error: aborting due to 2 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr index 69b0d2675c22d..b4ab5f5ee62dd 100644 --- a/src/test/ui/lint/lint-removed-cmdline.stderr +++ b/src/test/ui/lint/lint-removed-cmdline.stderr @@ -2,6 +2,18 @@ warning: lint `raw_pointer_derive` has been removed: `using derive with raw poin | = note: requested on the command line with `-D raw_pointer_derive` +warning: lint `raw_pointer_derive` has been removed: `using derive with raw pointers is ok` + | + = note: requested on the command line with `-D raw_pointer_derive` + +warning: lint `raw_pointer_derive` has been removed: `using derive with raw pointers is ok` + | + = note: requested on the command line with `-D raw_pointer_derive` + +warning: lint `raw_pointer_derive` has been removed: `using derive with raw pointers is ok` + | + = note: requested on the command line with `-D raw_pointer_derive` + error: unused variable: `unused` --> $DIR/lint-removed-cmdline.rs:12:17 | diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr index c978981a5c2ed..6401d9b77e007 100644 --- a/src/test/ui/lint/lint-renamed-cmdline.stderr +++ b/src/test/ui/lint/lint-renamed-cmdline.stderr @@ -2,6 +2,18 @@ warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` | = note: requested on the command line with `-D bare_trait_object` +warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` + | + = note: requested on the command line with `-D bare_trait_object` + +warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` + | + = note: requested on the command line with `-D bare_trait_object` + +warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` + | + = note: requested on the command line with `-D bare_trait_object` + error: unused variable: `unused` --> $DIR/lint-renamed-cmdline.rs:8:17 | diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 0585fec99b418..0bac9bb3d99cd 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -97,10 +97,13 @@ mod cross_crate { struct S1(T::TypeUnstable); struct S2(T::TypeDeprecated); //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text type A = dyn TraitWithAssociatedTypes< TypeUnstable = u8, TypeDeprecated = u16, //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' + //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' + //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' >; let _ = DeprecatedStruct { //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct' diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 62380135b333b..650373c90bcf2 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -77,241 +77,241 @@ LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:106:17 + --> $DIR/lint-stability-deprecated.rs:109:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text - --> $DIR/lint-stability-deprecated.rs:109:17 + --> $DIR/lint-stability-deprecated.rs:112:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:116:17 + --> $DIR/lint-stability-deprecated.rs:119:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:117:17 + --> $DIR/lint-stability-deprecated.rs:120:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:121:17 + --> $DIR/lint-stability-deprecated.rs:124:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text - --> $DIR/lint-stability-deprecated.rs:122:17 + --> $DIR/lint-stability-deprecated.rs:125:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:126:17 + --> $DIR/lint-stability-deprecated.rs:129:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:127:17 + --> $DIR/lint-stability-deprecated.rs:130:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:136:25 + --> $DIR/lint-stability-deprecated.rs:139:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:137:25 + --> $DIR/lint-stability-deprecated.rs:140:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:138:41 + --> $DIR/lint-stability-deprecated.rs:141:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:143:9 + --> $DIR/lint-stability-deprecated.rs:146:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:145:9 + --> $DIR/lint-stability-deprecated.rs:148:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:147:9 + --> $DIR/lint-stability-deprecated.rs:150:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:149:9 + --> $DIR/lint-stability-deprecated.rs:152:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:151:9 + --> $DIR/lint-stability-deprecated.rs:154:9 | LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:153:9 + --> $DIR/lint-stability-deprecated.rs:156:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:155:9 + --> $DIR/lint-stability-deprecated.rs:158:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:157:9 + --> $DIR/lint-stability-deprecated.rs:160:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:185:10 + --> $DIR/lint-stability-deprecated.rs:188:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:187:25 + --> $DIR/lint-stability-deprecated.rs:190:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text - --> $DIR/lint-stability-deprecated.rs:206:9 + --> $DIR/lint-stability-deprecated.rs:209:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated': text - --> $DIR/lint-stability-deprecated.rs:328:9 + --> $DIR/lint-stability-deprecated.rs:331:9 | LL | deprecated(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:333:9 + --> $DIR/lint-stability-deprecated.rs:336:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:335:9 + --> $DIR/lint-stability-deprecated.rs:338:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:337:9 + --> $DIR/lint-stability-deprecated.rs:340:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:342:9 + --> $DIR/lint-stability-deprecated.rs:345:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:344:9 + --> $DIR/lint-stability-deprecated.rs:347:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:382:17 + --> $DIR/lint-stability-deprecated.rs:385:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:389:17 + --> $DIR/lint-stability-deprecated.rs:392:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:393:17 + --> $DIR/lint-stability-deprecated.rs:396:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:397:17 + --> $DIR/lint-stability-deprecated.rs:400:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:404:9 + --> $DIR/lint-stability-deprecated.rs:407:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:406:9 + --> $DIR/lint-stability-deprecated.rs:409:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:408:9 + --> $DIR/lint-stability-deprecated.rs:411:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:410:9 + --> $DIR/lint-stability-deprecated.rs:413:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:437:9 + --> $DIR/lint-stability-deprecated.rs:440:9 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:457:10 + --> $DIR/lint-stability-deprecated.rs:460:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:459:24 + --> $DIR/lint-stability-deprecated.rs:462:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:445:13 + --> $DIR/lint-stability-deprecated.rs:448:13 | LL | fn_in_body(); | ^^^^^^^^^^ @@ -323,7 +323,7 @@ LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - --> $DIR/lint-stability-deprecated.rs:102:13 + --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ @@ -449,188 +449,206 @@ LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:107:13 + --> $DIR/lint-stability-deprecated.rs:110:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text - --> $DIR/lint-stability-deprecated.rs:111:13 + --> $DIR/lint-stability-deprecated.rs:114:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:142:13 + --> $DIR/lint-stability-deprecated.rs:145:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:144:9 + --> $DIR/lint-stability-deprecated.rs:147:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:146:13 + --> $DIR/lint-stability-deprecated.rs:149:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:148:9 + --> $DIR/lint-stability-deprecated.rs:151:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:150:13 + --> $DIR/lint-stability-deprecated.rs:153:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:152:9 + --> $DIR/lint-stability-deprecated.rs:155:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:154:13 + --> $DIR/lint-stability-deprecated.rs:157:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:156:9 + --> $DIR/lint-stability-deprecated.rs:159:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:173:13 + --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:174:13 + --> $DIR/lint-stability-deprecated.rs:177:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:175:13 + --> $DIR/lint-stability-deprecated.rs:178:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:176:13 + --> $DIR/lint-stability-deprecated.rs:179:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:329:13 + --> $DIR/lint-stability-deprecated.rs:332:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:330:9 + --> $DIR/lint-stability-deprecated.rs:333:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:331:9 + --> $DIR/lint-stability-deprecated.rs:334:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:332:13 + --> $DIR/lint-stability-deprecated.rs:335:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:334:9 + --> $DIR/lint-stability-deprecated.rs:337:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:338:13 + --> $DIR/lint-stability-deprecated.rs:341:13 | LL | foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:339:9 + --> $DIR/lint-stability-deprecated.rs:342:9 | LL | Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:340:9 + --> $DIR/lint-stability-deprecated.rs:343:9 | LL | ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:341:13 + --> $DIR/lint-stability-deprecated.rs:344:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:343:9 + --> $DIR/lint-stability-deprecated.rs:346:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:384:13 + --> $DIR/lint-stability-deprecated.rs:387:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:403:13 + --> $DIR/lint-stability-deprecated.rs:406:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:405:9 + --> $DIR/lint-stability-deprecated.rs:408:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:407:13 + --> $DIR/lint-stability-deprecated.rs:410:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:409:9 + --> $DIR/lint-stability-deprecated.rs:412:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:426:13 + --> $DIR/lint-stability-deprecated.rs:429:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:427:13 + --> $DIR/lint-stability-deprecated.rs:430:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ +warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + --> $DIR/lint-stability-deprecated.rs:98:48 + | +LL | struct S2(T::TypeDeprecated); + | ^^^^^^^^^^^^^^^^^ + +warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + --> $DIR/lint-stability-deprecated.rs:103:13 + | +LL | TypeDeprecated = u16, + | ^^^^^^^^^^^^^^^^^^^^ + +warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + --> $DIR/lint-stability-deprecated.rs:103:13 + | +LL | TypeDeprecated = u16, + | ^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr index c2cbf5feaada4..3a78ed2ceea15 100644 --- a/src/test/ui/lint/lint-unexported-no-mangle.stderr +++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr @@ -6,6 +6,30 @@ warning: lint `private_no_mangle_statics` has been removed: `no longer a warning | = note: requested on the command line with `-F private_no_mangle_statics` +warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, `#[no_mangle]` functions always exported` + | + = note: requested on the command line with `-F private_no_mangle_fns` + +warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, `#[no_mangle]` statics always exported` + | + = note: requested on the command line with `-F private_no_mangle_statics` + +warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, `#[no_mangle]` functions always exported` + | + = note: requested on the command line with `-F private_no_mangle_fns` + +warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, `#[no_mangle]` statics always exported` + | + = note: requested on the command line with `-F private_no_mangle_statics` + +warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, `#[no_mangle]` functions always exported` + | + = note: requested on the command line with `-F private_no_mangle_fns` + +warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, `#[no_mangle]` statics always exported` + | + = note: requested on the command line with `-F private_no_mangle_statics` + error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:9:1 | diff --git a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr index 58fdae3333ca1..27e7ee7fc03bd 100644 --- a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr +++ b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr @@ -7,6 +7,24 @@ error[E0602]: unknown lint: `dead_cod` = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` -error: aborting due to 2 previous errors +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error[E0602]: unknown lint: `dead_cod` + | + = help: did you mean: `dead_code` + = note: requested on the command line with `-D dead_cod` + +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error[E0602]: unknown lint: `dead_cod` + | + = help: did you mean: `dead_code` + = note: requested on the command line with `-D dead_cod` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0602`. diff --git a/src/test/ui/lint/outer-forbid.rs b/src/test/ui/lint/outer-forbid.rs index 950533cca1a98..2a38565f60364 100644 --- a/src/test/ui/lint/outer-forbid.rs +++ b/src/test/ui/lint/outer-forbid.rs @@ -7,12 +7,18 @@ #![forbid(unused, non_snake_case)] #[allow(unused_variables)] //~ ERROR overruled + //~| ERROR overruled + //~| ERROR overruled fn foo() {} #[allow(unused)] //~ ERROR overruled + //~| ERROR overruled + //~| ERROR overruled fn bar() {} #[allow(nonstandard_style)] //~ ERROR overruled + //~| ERROR overruled + //~| ERROR overruled fn main() { println!("hello forbidden world") } diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index 310a5d88f8c1c..b2e638e7af978 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -8,7 +8,7 @@ LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: allow(unused) overruled by outer forbid(unused) - --> $DIR/outer-forbid.rs:12:9 + --> $DIR/outer-forbid.rs:14:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here @@ -17,7 +17,7 @@ LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) - --> $DIR/outer-forbid.rs:15:9 + --> $DIR/outer-forbid.rs:19:9 | LL | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here @@ -25,6 +25,60 @@ LL | #![forbid(unused, non_snake_case)] LL | #[allow(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ overruled by previous forbid -error: aborting due to 3 previous errors +error[E0453]: allow(unused_variables) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:9:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:14:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) + --> $DIR/outer-forbid.rs:19:9 + | +LL | #![forbid(unused, non_snake_case)] + | -------------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused_variables) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:9:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:14:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) + --> $DIR/outer-forbid.rs:19:9 + | +LL | #![forbid(unused, non_snake_case)] + | -------------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs index 21c2ddd5ef7ce..03cf0679fce94 100644 --- a/src/test/ui/lint/reasons-erroneous.rs +++ b/src/test/ui/lint/reasons-erroneous.rs @@ -2,24 +2,70 @@ #![warn(absolute_paths_not_starting_with_crate, reason = 0)] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason must be a string literal +//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason must be a string literal +//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason in lint attribute must come last +//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] //~^ ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason in lint attribute must come last +//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last #![warn(missing_copy_implementations, reason)] //~^ WARN unknown lint diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr index 3f925f19ef18e..a84167fed12d0 100644 --- a/src/test/ui/lint/reasons-erroneous.stderr +++ b/src/test/ui/lint/reasons-erroneous.stderr @@ -5,49 +5,187 @@ LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] | ^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:6:40 + --> $DIR/reasons-erroneous.rs:10:40 | LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:9:29 + --> $DIR/reasons-erroneous.rs:17:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:12:23 + --> $DIR/reasons-erroneous.rs:17:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:30:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:15:36 + --> $DIR/reasons-erroneous.rs:30:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:18:44 + --> $DIR/reasons-erroneous.rs:56:44 | LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:21:25 + --> $DIR/reasons-erroneous.rs:63:25 | LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last warning: unknown lint: `reason` - --> $DIR/reasons-erroneous.rs:24:39 + --> $DIR/reasons-erroneous.rs:70:39 | LL | #![warn(missing_copy_implementations, reason)] | ^^^^^^ | = note: `#[warn(unknown_lints)]` on by default -error: aborting due to 7 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:3:58 + | +LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] + | ^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:10:40 + | +LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:17:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:17:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:30:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:30:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:56:44 + | +LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] + | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:63:25 + | +LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:3:58 + | +LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] + | ^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:10:40 + | +LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:17:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:17:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:30:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:30:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:43:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:56:44 + | +LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] + | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:63:25 + | +LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error: aborting due to 30 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/lint/reasons-forbidden.rs b/src/test/ui/lint/reasons-forbidden.rs index 19ab76707d408..6a71176aabb15 100644 --- a/src/test/ui/lint/reasons-forbidden.rs +++ b/src/test/ui/lint/reasons-forbidden.rs @@ -3,6 +3,8 @@ #![forbid( unsafe_code, //~^ NOTE `forbid` level set here + //~| NOTE `forbid` level set here + //~| NOTE `forbid` level set here reason = "our errors & omissions insurance policy doesn't cover unsafe Rust" )] @@ -13,7 +15,13 @@ fn main() { #[allow(unsafe_code)] //~^ ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) + //~| ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) + //~| ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) //~| NOTE overruled by previous forbid + //~| NOTE overruled by previous forbid + //~| NOTE overruled by previous forbid + //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust + //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust unsafe { *a_billion_dollar_mistake diff --git a/src/test/ui/lint/reasons-forbidden.stderr b/src/test/ui/lint/reasons-forbidden.stderr index ea09e591cba0f..0954edea7378c 100644 --- a/src/test/ui/lint/reasons-forbidden.stderr +++ b/src/test/ui/lint/reasons-forbidden.stderr @@ -1,5 +1,5 @@ error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) - --> $DIR/reasons-forbidden.rs:14:13 + --> $DIR/reasons-forbidden.rs:16:13 | LL | unsafe_code, | ----------- `forbid` level set here @@ -9,6 +9,28 @@ LL | #[allow(unsafe_code)] | = note: our errors & omissions insurance policy doesn't cover unsafe Rust -error: aborting due to previous error +error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) + --> $DIR/reasons-forbidden.rs:16:13 + | +LL | unsafe_code, + | ----------- `forbid` level set here +... +LL | #[allow(unsafe_code)] + | ^^^^^^^^^^^ overruled by previous forbid + | + = note: our errors & omissions insurance policy doesn't cover unsafe Rust + +error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) + --> $DIR/reasons-forbidden.rs:16:13 + | +LL | unsafe_code, + | ----------- `forbid` level set here +... +LL | #[allow(unsafe_code)] + | ^^^^^^^^^^^ overruled by previous forbid + | + = note: our errors & omissions insurance policy doesn't cover unsafe Rust + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/macros/builtin-std-paths-fail.rs b/src/test/ui/macros/builtin-std-paths-fail.rs index 33de3d5184b1f..c1a4e32a6dcbc 100644 --- a/src/test/ui/macros/builtin-std-paths-fail.rs +++ b/src/test/ui/macros/builtin-std-paths-fail.rs @@ -1,6 +1,8 @@ #[derive( core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` + //~| ERROR could not find `RustcDecodable` in `core` core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` + //~| ERROR could not find `RustcDecodable` in `core` )] #[core::bench] //~ ERROR could not find `bench` in `core` #[core::global_allocator] //~ ERROR could not find `global_allocator` in `core` @@ -10,7 +12,9 @@ struct Core; #[derive( std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` + //~| ERROR could not find `RustcDecodable` in `std` std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` + //~| ERROR could not find `RustcDecodable` in `std` )] #[std::bench] //~ ERROR could not find `bench` in `std` #[std::global_allocator] //~ ERROR could not find `global_allocator` in `std` diff --git a/src/test/ui/macros/builtin-std-paths-fail.stderr b/src/test/ui/macros/builtin-std-paths-fail.stderr index 6de689076b849..9831e46ec30a1 100644 --- a/src/test/ui/macros/builtin-std-paths-fail.stderr +++ b/src/test/ui/macros/builtin-std-paths-fail.stderr @@ -1,23 +1,23 @@ error[E0433]: failed to resolve: could not find `bench` in `core` - --> $DIR/builtin-std-paths-fail.rs:5:9 + --> $DIR/builtin-std-paths-fail.rs:7:9 | LL | #[core::bench] | ^^^^^ could not find `bench` in `core` error[E0433]: failed to resolve: could not find `global_allocator` in `core` - --> $DIR/builtin-std-paths-fail.rs:6:9 + --> $DIR/builtin-std-paths-fail.rs:8:9 | LL | #[core::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `core` error[E0433]: failed to resolve: could not find `test_case` in `core` - --> $DIR/builtin-std-paths-fail.rs:7:9 + --> $DIR/builtin-std-paths-fail.rs:9:9 | LL | #[core::test_case] | ^^^^^^^^^ could not find `test_case` in `core` error[E0433]: failed to resolve: could not find `test` in `core` - --> $DIR/builtin-std-paths-fail.rs:8:9 + --> $DIR/builtin-std-paths-fail.rs:10:9 | LL | #[core::test] | ^^^^ could not find `test` in `core` @@ -29,47 +29,71 @@ LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` - --> $DIR/builtin-std-paths-fail.rs:3:11 + --> $DIR/builtin-std-paths-fail.rs:4:11 + | +LL | core::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` + --> $DIR/builtin-std-paths-fail.rs:4:11 + | +LL | core::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` + --> $DIR/builtin-std-paths-fail.rs:2:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` error[E0433]: failed to resolve: could not find `bench` in `std` - --> $DIR/builtin-std-paths-fail.rs:15:8 + --> $DIR/builtin-std-paths-fail.rs:19:8 | LL | #[std::bench] | ^^^^^ could not find `bench` in `std` error[E0433]: failed to resolve: could not find `global_allocator` in `std` - --> $DIR/builtin-std-paths-fail.rs:16:8 + --> $DIR/builtin-std-paths-fail.rs:20:8 | LL | #[std::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `std` error[E0433]: failed to resolve: could not find `test_case` in `std` - --> $DIR/builtin-std-paths-fail.rs:17:8 + --> $DIR/builtin-std-paths-fail.rs:21:8 | LL | #[std::test_case] | ^^^^^^^^^ could not find `test_case` in `std` error[E0433]: failed to resolve: could not find `test` in `std` - --> $DIR/builtin-std-paths-fail.rs:18:8 + --> $DIR/builtin-std-paths-fail.rs:22:8 | LL | #[std::test] | ^^^^ could not find `test` in `std` error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` - --> $DIR/builtin-std-paths-fail.rs:12:10 + --> $DIR/builtin-std-paths-fail.rs:14:10 + | +LL | std::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` + --> $DIR/builtin-std-paths-fail.rs:16:10 + | +LL | std::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` + --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` - --> $DIR/builtin-std-paths-fail.rs:13:10 + --> $DIR/builtin-std-paths-fail.rs:14:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` -error: aborting due to 12 previous errors +error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/meta-item-absolute-path.rs b/src/test/ui/macros/meta-item-absolute-path.rs index 14d23be059c87..8ed911cbca718 100644 --- a/src/test/ui/macros/meta-item-absolute-path.rs +++ b/src/test/ui/macros/meta-item-absolute-path.rs @@ -1,4 +1,5 @@ #[derive(::Absolute)] //~ ERROR failed to resolve + //~| ERROR failed to resolve struct S; fn main() {} diff --git a/src/test/ui/macros/meta-item-absolute-path.stderr b/src/test/ui/macros/meta-item-absolute-path.stderr index 711fa4dd405bc..c53971e245fdb 100644 --- a/src/test/ui/macros/meta-item-absolute-path.stderr +++ b/src/test/ui/macros/meta-item-absolute-path.stderr @@ -4,6 +4,12 @@ error[E0433]: failed to resolve: maybe a missing crate `Absolute`? LL | #[derive(::Absolute)] | ^^^^^^^^ maybe a missing crate `Absolute`? -error: aborting due to previous error +error[E0433]: failed to resolve: maybe a missing crate `Absolute`? + --> $DIR/meta-item-absolute-path.rs:1:12 + | +LL | #[derive(::Absolute)] + | ^^^^^^^^ maybe a missing crate `Absolute`? + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/match/match-range-fail-2.rs b/src/test/ui/match/match-range-fail-2.rs index 19e6e12958bf3..792664e1db82c 100644 --- a/src/test/ui/match/match-range-fail-2.rs +++ b/src/test/ui/match/match-range-fail-2.rs @@ -6,16 +6,19 @@ fn main() { _ => { } }; //~^^^ ERROR lower range bound must be less than or equal to upper + //~| ERROR lower range bound must be less than or equal to upper match 5 { 0 .. 0 => { } _ => { } }; //~^^^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper match 5u64 { 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } _ => { } }; //~^^^ ERROR lower range bound must be less than or equal to upper + //~| ERROR lower range bound must be less than or equal to upper } diff --git a/src/test/ui/match/match-range-fail-2.stderr b/src/test/ui/match/match-range-fail-2.stderr index 52a2bf2b34aa6..7a0852d7e6ce6 100644 --- a/src/test/ui/match/match-range-fail-2.stderr +++ b/src/test/ui/match/match-range-fail-2.stderr @@ -5,18 +5,36 @@ LL | 6 ..= 1 => { } | ^ lower bound larger than upper bound error[E0579]: lower range bound must be less than upper - --> $DIR/match-range-fail-2.rs:11:9 + --> $DIR/match-range-fail-2.rs:12:9 | LL | 0 .. 0 => { } | ^ error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/match-range-fail-2.rs:17:9 + --> $DIR/match-range-fail-2.rs:19:9 | LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound -error: aborting due to 3 previous errors +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:5:9 + | +LL | 6 ..= 1 => { } + | ^ lower bound larger than upper bound + +error[E0579]: lower range bound must be less than upper + --> $DIR/match-range-fail-2.rs:12:9 + | +LL | 0 .. 0 => { } + | ^ + +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:19:9 + | +LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } + | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0030, E0579. For more information about an error, try `rustc --explain E0030`. diff --git a/src/test/ui/parser/issue-62973.rs b/src/test/ui/parser/issue-62973.rs index 18bc51e7ba7cd..1c5d0c6f8ab46 100644 --- a/src/test/ui/parser/issue-62973.rs +++ b/src/test/ui/parser/issue-62973.rs @@ -1,5 +1,5 @@ // ignore-tidy-trailing-newlines -// error-pattern: aborting due to 6 previous errors +// error-pattern: aborting due to 7 previous errors fn main() {} diff --git a/src/test/ui/parser/issue-62973.stderr b/src/test/ui/parser/issue-62973.stderr index e95e629957c26..95ee52d810ddc 100644 --- a/src/test/ui/parser/issue-62973.stderr +++ b/src/test/ui/parser/issue-62973.stderr @@ -9,6 +9,17 @@ LL | LL | | ^ +error: this file contains an unclosed delimiter + --> $DIR/issue-62973.rs:8:2 + | +LL | fn p() { match s { v, E { [) {) } + | - - unclosed delimiter + | | + | unclosed delimiter +LL | +LL | + | ^ + error: expected one of `,` or `}`, found `{` --> $DIR/issue-62973.rs:6:25 | @@ -60,5 +71,5 @@ LL | fn p() { match s { v, E { [) {) } | | | unclosed delimiter -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/src/test/ui/parser/issue-63135.rs b/src/test/ui/parser/issue-63135.rs index a5a8de85466bb..d5f5f1469f35a 100644 --- a/src/test/ui/parser/issue-63135.rs +++ b/src/test/ui/parser/issue-63135.rs @@ -1,3 +1,3 @@ -// error-pattern: aborting due to 5 previous errors +// error-pattern: aborting due to 6 previous errors fn i(n{...,f # diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr index a6fb037b299f5..462fdf11f40a9 100644 --- a/src/test/ui/parser/issue-63135.stderr +++ b/src/test/ui/parser/issue-63135.stderr @@ -7,6 +7,15 @@ LL | fn i(n{...,f # | | unclosed delimiter | unclosed delimiter +error: this file contains an unclosed delimiter + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + error: expected field pattern, found `...` --> $DIR/issue-63135.rs:3:8 | @@ -34,5 +43,5 @@ error: expected one of `:` or `|`, found `)` LL | fn i(n{...,f # | ^ expected one of `:` or `|` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs index 4f7c5eea1d183..c35236ce7934e 100644 --- a/src/test/ui/parser/missing_right_paren.rs +++ b/src/test/ui/parser/missing_right_paren.rs @@ -1,3 +1,3 @@ // ignore-tidy-trailing-newlines -// error-pattern: aborting due to 2 previous errors +// error-pattern: aborting due to 3 previous errors fn main((ؼ \ No newline at end of file diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr index c98b6bb6991c7..d67e7c88912a5 100644 --- a/src/test/ui/parser/missing_right_paren.stderr +++ b/src/test/ui/parser/missing_right_paren.stderr @@ -7,11 +7,20 @@ LL | fn main((ؼ | |unclosed delimiter | unclosed delimiter +error: this file contains an unclosed delimiter + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | -- ^ + | || + | |unclosed delimiter + | unclosed delimiter + error: expected one of `:` or `|`, found `)` --> $DIR/missing_right_paren.rs:3:11 | LL | fn main((ؼ | ^ expected one of `:` or `|` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index 88eda9afec7eb..559925c282f9a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -101,6 +101,7 @@ fn main() { //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable //~| ERROR cannot move out of `b` in pattern guard + //~| ERROR cannot move out of `b` in pattern guard _ => {} } match Ok(U) { @@ -108,6 +109,7 @@ fn main() { //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable //~| ERROR cannot move out of `a` in pattern guard + //~| ERROR cannot move out of `a` in pattern guard _ => {} } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index b068a6125b670..b5c26a1fa0399 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -191,7 +191,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -200,7 +200,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -209,7 +209,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:114:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:116:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -219,7 +219,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -229,7 +229,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:126:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -239,7 +239,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -359,8 +359,24 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +error[E0507]: cannot move out of `b` in pattern guard + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66 + | +LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} + | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error[E0507]: cannot move out of `a` in pattern guard + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 + | +LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} + | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -368,7 +384,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -380,7 +396,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -392,7 +408,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:126:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -404,7 +420,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:126:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -415,7 +431,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | drop(a); | - immutable borrow later used here -error: aborting due to 43 previous errors +error: aborting due to 45 previous errors Some errors have detailed explanations: E0502, E0507, E0594. For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/pattern/patkind-litrange-no-expr.rs b/src/test/ui/pattern/patkind-litrange-no-expr.rs index def6c62459e5a..5b3db2e57c836 100644 --- a/src/test/ui/pattern/patkind-litrange-no-expr.rs +++ b/src/test/ui/pattern/patkind-litrange-no-expr.rs @@ -18,7 +18,8 @@ enum_number!(Change { Pos = 1, Neg = -1, Arith = 1 + 1, //~ ERROR arbitrary expressions aren't allowed in patterns - //~^ ERROR only char and numeric types are allowed in range patterns + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR only char and numeric types are allowed in range patterns }); fn main() {} diff --git a/src/test/ui/pattern/patkind-litrange-no-expr.stderr b/src/test/ui/pattern/patkind-litrange-no-expr.stderr index 78768d282e7c4..70dd1a9263f6f 100644 --- a/src/test/ui/pattern/patkind-litrange-no-expr.stderr +++ b/src/test/ui/pattern/patkind-litrange-no-expr.stderr @@ -4,6 +4,12 @@ error: arbitrary expressions aren't allowed in patterns LL | Arith = 1 + 1, | ^^^^^ +error: arbitrary expressions aren't allowed in patterns + --> $DIR/patkind-litrange-no-expr.rs:20:13 + | +LL | Arith = 1 + 1, + | ^^^^^ + error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/patkind-litrange-no-expr.rs:20:13 | @@ -13,6 +19,6 @@ LL | $( $value ..= 42 => Some($name::$variant), )* // PatKind::R LL | Arith = 1 + 1, | ^^^^^ this is of type `_` but it should be `char` or numeric -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs index 7de7b7e79be44..37c4ccda0f5e3 100644 --- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs +++ b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs @@ -34,11 +34,15 @@ fn main() { //~^ WARNING floating-point types cannot be used in patterns //~| WARNING floating-point types cannot be used in patterns //~| WARNING floating-point types cannot be used in patterns + //~| WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler //~| WARNING this was previously accepted by the compiler //~| WARNING this was previously accepted by the compiler //~| WARNING this was previously accepted by the compiler 0.02f64 => {} //~ ERROR unreachable pattern //~^ WARNING floating-point types cannot be used in patterns + //~| WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler //~| WARNING this was previously accepted by the compiler _ => {} }; diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr index c15186d2558f2..8412a113664c8 100644 --- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr +++ b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr @@ -48,7 +48,7 @@ LL | 0.01f64 ..= 6.5f64 => {} = note: for more information, see issue #41620 warning: floating-point types cannot be used in patterns - --> $DIR/match-range-fail-dominate.rs:40:7 + --> $DIR/match-range-fail-dominate.rs:42:7 | LL | 0.02f64 => {} | ^^^^^^^ @@ -57,7 +57,7 @@ LL | 0.02f64 => {} = note: for more information, see issue #41620 error: unreachable pattern - --> $DIR/match-range-fail-dominate.rs:40:7 + --> $DIR/match-range-fail-dominate.rs:42:7 | LL | 0.02f64 => {} | ^^^^^^^ @@ -71,5 +71,23 @@ LL | 0.01f64 ..= 6.5f64 => {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:33:19 + | +LL | 0.01f64 ..= 6.5f64 => {} + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:42:7 + | +LL | 0.02f64 => {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + error: aborting due to 5 previous errors diff --git a/src/test/ui/privacy/privacy1.rs b/src/test/ui/privacy/privacy1.rs index d376237c355d0..fcf7b19572f1f 100644 --- a/src/test/ui/privacy/privacy1.rs +++ b/src/test/ui/privacy/privacy1.rs @@ -131,6 +131,7 @@ mod foo { fn test2() { use bar::baz::{foo, bar}; //~^ ERROR: module `baz` is private + //~| ERROR: module `baz` is private foo(); bar(); diff --git a/src/test/ui/privacy/privacy1.stderr b/src/test/ui/privacy/privacy1.stderr index b647cc8ab8a83..29f53cd0e3545 100644 --- a/src/test/ui/privacy/privacy1.stderr +++ b/src/test/ui/privacy/privacy1.stderr @@ -5,13 +5,19 @@ LL | use bar::baz::{foo, bar}; | ^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:140:18 + --> $DIR/privacy1.rs:132:18 + | +LL | use bar::baz::{foo, bar}; + | ^^^ + +error[E0603]: module `baz` is private + --> $DIR/privacy1.rs:141:18 | LL | use bar::baz; | ^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:164:20 + --> $DIR/privacy1.rs:165:20 | LL | use self::foo::i::A; | ^ @@ -65,7 +71,7 @@ LL | ::bar::baz::bar(); | ^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:156:17 + --> $DIR/privacy1.rs:157:17 | LL | impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } | ^ @@ -100,7 +106,7 @@ error[E0624]: method `bar2` is private LL | ::bar::baz::A.bar2(); | ^^^^ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors Some errors have detailed explanations: E0603, E0624. For more information about an error, try `rustc --explain E0603`. diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.rs b/src/test/ui/privacy/private-in-public-assoc-ty.rs index 3c42f24d5ff73..ad1052ada6084 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.rs +++ b/src/test/ui/privacy/private-in-public-assoc-ty.rs @@ -17,6 +17,8 @@ mod m { //~^ WARN private trait `m::PrivTr` in public interface //~| WARN this was previously accepted //~| WARN private type `m::Priv` in public interface + //~| WARN private type `m::Priv` in public interface + //~| WARN this was previously accepted //~| WARN this was previously accepted type Alias1: PrivTr; type Alias2: PubTrAux1 = u8; @@ -34,6 +36,7 @@ mod m { type Exist = impl PrivTr; //~^ ERROR private trait `m::PrivTr` in public interface + //~| ERROR private trait `m::PrivTr` in public interface fn infer_exist() -> Self::Exist { Priv } } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index 158862f9228cc..3cc551cdeded6 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -29,8 +29,23 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: private type `m::Priv` in public interface (error E0446) + --> $DIR/private-in-public-assoc-ty.rs:16:5 + | +LL | / pub trait PubTr { +LL | | +LL | | +LL | | +... | +LL | | fn infer_exist() -> Self::Exist; +LL | | } + | |_____^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 + error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:25:9 + --> $DIR/private-in-public-assoc-ty.rs:27:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -39,7 +54,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:32:9 + --> $DIR/private-in-public-assoc-ty.rs:34:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -48,7 +63,16 @@ LL | type Alias1 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:35:9 + --> $DIR/private-in-public-assoc-ty.rs:37:9 + | +LL | trait PrivTr {} + | - `m::PrivTr` declared as private +... +LL | type Exist = impl PrivTr; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + +error[E0445]: private trait `m::PrivTr` in public interface + --> $DIR/private-in-public-assoc-ty.rs:37:9 | LL | trait PrivTr {} | - `m::PrivTr` declared as private @@ -56,7 +80,7 @@ LL | trait PrivTr {} LL | type Exist = impl PrivTr; | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0445, E0446. For more information about an error, try `rustc --explain E0445`. diff --git a/src/test/ui/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs index 5d1a9f25baffd..f1934f62fd88a 100644 --- a/src/test/ui/proc-macro/issue-50493.rs +++ b/src/test/ui/proc-macro/issue-50493.rs @@ -4,6 +4,7 @@ extern crate issue_50493; #[derive(Derive)] //~ ERROR field `field` of struct `Restricted` is private + //~| ERROR field `field` of struct `Restricted` is private struct Restricted { pub(in restricted) field: usize, //~ visibilities can only be restricted to ancestor modules } diff --git a/src/test/ui/proc-macro/issue-50493.stderr b/src/test/ui/proc-macro/issue-50493.stderr index 6b8724457a6a3..56c7800102176 100644 --- a/src/test/ui/proc-macro/issue-50493.stderr +++ b/src/test/ui/proc-macro/issue-50493.stderr @@ -1,5 +1,5 @@ error[E0742]: visibilities can only be restricted to ancestor modules - --> $DIR/issue-50493.rs:8:12 + --> $DIR/issue-50493.rs:9:12 | LL | pub(in restricted) field: usize, | ^^^^^^^^^^ @@ -10,7 +10,13 @@ error[E0616]: field `field` of struct `Restricted` is private LL | #[derive(Derive)] | ^^^^^^ -error: aborting due to 2 previous errors +error[E0616]: field `field` of struct `Restricted` is private + --> $DIR/issue-50493.rs:6:10 + | +LL | #[derive(Derive)] + | ^^^^^^ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0616, E0742. For more information about an error, try `rustc --explain E0616`. diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index b17c0565932fd..470b22b48749d 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -46,6 +46,7 @@ fn check_attr2() {} fn check_attr3() {} #[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope + //~| ERROR cannot find derive macro `my_macro` in this scope #[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines //~| ERROR expected derive macro, found macro `crate::my_macro` struct CheckDerive1; 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 c011a70cd0c84..a617319faea80 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -47,19 +47,19 @@ LL | #[MyTrait] | ^^^^^^^ not an attribute error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:52:10 + --> $DIR/macro-namespace-reserved-2.rs:53:10 | LL | #[derive(my_macro_attr)] | ^^^^^^^^^^^^^ error: expected derive macro, found attribute macro `my_macro_attr` - --> $DIR/macro-namespace-reserved-2.rs:52:10 + --> $DIR/macro-namespace-reserved-2.rs:53:10 | LL | #[derive(my_macro_attr)] | ^^^^^^^^^^^^^ not a derive macro error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:55:10 + --> $DIR/macro-namespace-reserved-2.rs:56:10 | LL | #[derive(MyTrait)] | ^^^^^^^ @@ -77,13 +77,13 @@ LL | #[crate::my_macro] | ^^^^^^^^^^^^^^^ not an attribute error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:49:10 + --> $DIR/macro-namespace-reserved-2.rs:50:10 | LL | #[derive(crate::my_macro)] | ^^^^^^^^^^^^^^^ error: expected derive macro, found macro `crate::my_macro` - --> $DIR/macro-namespace-reserved-2.rs:49:10 + --> $DIR/macro-namespace-reserved-2.rs:50:10 | LL | #[derive(crate::my_macro)] | ^^^^^^^^^^^^^^^ not a derive macro @@ -112,5 +112,11 @@ error: cannot find derive macro `my_macro` in this scope LL | #[derive(my_macro)] | ^^^^^^^^ -error: aborting due to 19 previous errors +error: cannot find derive macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:48:10 + | +LL | #[derive(my_macro)] + | ^^^^^^^^ + +error: aborting due to 20 previous errors diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs index d2282af27f543..ad8a5bbb0f9ff 100644 --- a/src/test/ui/proc-macro/resolve-error.rs +++ b/src/test/ui/proc-macro/resolve-error.rs @@ -21,6 +21,7 @@ macro_rules! attr_proc_mac { #[derive(FooWithLongNan)] //~^ ERROR cannot find +//~| ERROR cannot find struct Foo; // Interpreted as an unstable custom attribute @@ -33,14 +34,17 @@ struct Asdf; #[derive(Dlone)] //~^ ERROR cannot find +//~| ERROR cannot find struct A; #[derive(Dlona)] //~^ ERROR cannot find +//~| ERROR cannot find struct B; #[derive(attr_proc_macra)] //~^ ERROR cannot find +//~| ERROR cannot find struct C; fn main() { diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index 02c82c01ed3e0..f7e00ed77d9b0 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,17 +1,17 @@ error: cannot find macro `bang_proc_macrp` in this scope - --> $DIR/resolve-error.rs:56:5 + --> $DIR/resolve-error.rs:60:5 | LL | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` error: cannot find macro `Dlona` in this scope - --> $DIR/resolve-error.rs:53:5 + --> $DIR/resolve-error.rs:57:5 | LL | Dlona!(); | ^^^^^ error: cannot find macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:50:5 + --> $DIR/resolve-error.rs:54:5 | LL | / macro_rules! attr_proc_mac { LL | | () => {} @@ -22,7 +22,7 @@ LL | attr_proc_macra!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` error: cannot find macro `FooWithLongNama` in this scope - --> $DIR/resolve-error.rs:47:5 + --> $DIR/resolve-error.rs:51:5 | LL | / macro_rules! FooWithLongNam { LL | | () => {} @@ -33,31 +33,49 @@ LL | FooWithLongNama!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:42:10 + --> $DIR/resolve-error.rs:45:10 + | +LL | #[derive(attr_proc_macra)] + | ^^^^^^^^^^^^^^^ + +error: cannot find derive macro `attr_proc_macra` in this scope + --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:38:10 + --> $DIR/resolve-error.rs:40:10 + | +LL | #[derive(Dlona)] + | ^^^^^ help: a derive macro with a similar name exists: `Clona` + +error: cannot find derive macro `Dlona` in this scope + --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] | ^^^^^ help: a derive macro with a similar name exists: `Clona` error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:34:10 + --> $DIR/resolve-error.rs:35:10 + | +LL | #[derive(Dlone)] + | ^^^^^ help: a derive macro with a similar name exists: `Clone` + +error: cannot find derive macro `Dlone` in this scope + --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] | ^^^^^ help: a derive macro with a similar name exists: `Clone` error: cannot find attribute `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:31:3 + --> $DIR/resolve-error.rs:32:3 | LL | #[FooWithLongNan] | ^^^^^^^^^^^^^^ error: cannot find attribute `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:27:3 + --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` @@ -68,5 +86,11 @@ error: cannot find derive macro `FooWithLongNan` in this scope LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` -error: aborting due to 10 previous errors +error: cannot find derive macro `FooWithLongNan` in this scope + --> $DIR/resolve-error.rs:22:10 + | +LL | #[derive(FooWithLongNan)] + | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + +error: aborting due to 14 previous errors diff --git a/src/test/ui/range/range_traits-1.rs b/src/test/ui/range/range_traits-1.rs index e28e47435c2c2..4f57c32e913e1 100644 --- a/src/test/ui/range/range_traits-1.rs +++ b/src/test/ui/range/range_traits-1.rs @@ -4,21 +4,45 @@ use std::ops::*; struct AllTheRanges { a: Range, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord b: RangeTo, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord c: RangeFrom, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord d: RangeFull, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord e: RangeInclusive, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord f: RangeToInclusive, //~^ ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare + //~| ERROR can't compare //~| ERROR Ord } diff --git a/src/test/ui/range/range_traits-1.stderr b/src/test/ui/range/range_traits-1.stderr index d085cab89a17c..f60ec23bdb0da 100644 --- a/src/test/ui/range/range_traits-1.stderr +++ b/src/test/ui/range/range_traits-1.stderr @@ -8,7 +8,7 @@ LL | a: Range, = note: required by `std::cmp::PartialOrd::partial_cmp` error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` - --> $DIR/range_traits-1.rs:8:5 + --> $DIR/range_traits-1.rs:12:5 | LL | b: RangeTo, | ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo < std::ops::RangeTo` and `std::ops::RangeTo > std::ops::RangeTo` @@ -17,7 +17,7 @@ LL | b: RangeTo, = note: required by `std::cmp::PartialOrd::partial_cmp` error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` - --> $DIR/range_traits-1.rs:11:5 + --> $DIR/range_traits-1.rs:19:5 | LL | c: RangeFrom, | ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom < std::ops::RangeFrom` and `std::ops::RangeFrom > std::ops::RangeFrom` @@ -26,7 +26,7 @@ LL | c: RangeFrom, = note: required by `std::cmp::PartialOrd::partial_cmp` error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` - --> $DIR/range_traits-1.rs:14:5 + --> $DIR/range_traits-1.rs:26:5 | LL | d: RangeFull, | ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull` @@ -35,7 +35,7 @@ LL | d: RangeFull, = note: required by `std::cmp::PartialOrd::partial_cmp` error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` - --> $DIR/range_traits-1.rs:17:5 + --> $DIR/range_traits-1.rs:33:5 | LL | e: RangeInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive < std::ops::RangeInclusive` and `std::ops::RangeInclusive > std::ops::RangeInclusive` @@ -44,7 +44,223 @@ LL | e: RangeInclusive, = note: required by `std::cmp::PartialOrd::partial_cmp` error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` - --> $DIR/range_traits-1.rs:20:5 + --> $DIR/range_traits-1.rs:40:5 + | +LL | f: RangeToInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive < std::ops::RangeToInclusive` and `std::ops::RangeToInclusive > std::ops::RangeToInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` + --> $DIR/range_traits-1.rs:5:5 + | +LL | a: Range, + | ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range < std::ops::Range` and `std::ops::Range > std::ops::Range` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` + --> $DIR/range_traits-1.rs:12:5 + | +LL | b: RangeTo, + | ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo < std::ops::RangeTo` and `std::ops::RangeTo > std::ops::RangeTo` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` + --> $DIR/range_traits-1.rs:19:5 + | +LL | c: RangeFrom, + | ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom < std::ops::RangeFrom` and `std::ops::RangeFrom > std::ops::RangeFrom` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` + --> $DIR/range_traits-1.rs:26:5 + | +LL | d: RangeFull, + | ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` + --> $DIR/range_traits-1.rs:33:5 + | +LL | e: RangeInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive < std::ops::RangeInclusive` and `std::ops::RangeInclusive > std::ops::RangeInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` + --> $DIR/range_traits-1.rs:40:5 + | +LL | f: RangeToInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive < std::ops::RangeToInclusive` and `std::ops::RangeToInclusive > std::ops::RangeToInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` + --> $DIR/range_traits-1.rs:5:5 + | +LL | a: Range, + | ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range < std::ops::Range` and `std::ops::Range > std::ops::Range` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` + --> $DIR/range_traits-1.rs:12:5 + | +LL | b: RangeTo, + | ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo < std::ops::RangeTo` and `std::ops::RangeTo > std::ops::RangeTo` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` + --> $DIR/range_traits-1.rs:19:5 + | +LL | c: RangeFrom, + | ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom < std::ops::RangeFrom` and `std::ops::RangeFrom > std::ops::RangeFrom` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` + --> $DIR/range_traits-1.rs:26:5 + | +LL | d: RangeFull, + | ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` + --> $DIR/range_traits-1.rs:33:5 + | +LL | e: RangeInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive < std::ops::RangeInclusive` and `std::ops::RangeInclusive > std::ops::RangeInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` + --> $DIR/range_traits-1.rs:40:5 + | +LL | f: RangeToInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive < std::ops::RangeToInclusive` and `std::ops::RangeToInclusive > std::ops::RangeToInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` + --> $DIR/range_traits-1.rs:5:5 + | +LL | a: Range, + | ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range < std::ops::Range` and `std::ops::Range > std::ops::Range` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` + --> $DIR/range_traits-1.rs:12:5 + | +LL | b: RangeTo, + | ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo < std::ops::RangeTo` and `std::ops::RangeTo > std::ops::RangeTo` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` + --> $DIR/range_traits-1.rs:19:5 + | +LL | c: RangeFrom, + | ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom < std::ops::RangeFrom` and `std::ops::RangeFrom > std::ops::RangeFrom` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` + --> $DIR/range_traits-1.rs:26:5 + | +LL | d: RangeFull, + | ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` + --> $DIR/range_traits-1.rs:33:5 + | +LL | e: RangeInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive < std::ops::RangeInclusive` and `std::ops::RangeInclusive > std::ops::RangeInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` + --> $DIR/range_traits-1.rs:40:5 + | +LL | f: RangeToInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive < std::ops::RangeToInclusive` and `std::ops::RangeToInclusive > std::ops::RangeToInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` + --> $DIR/range_traits-1.rs:5:5 + | +LL | a: Range, + | ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range < std::ops::Range` and `std::ops::Range > std::ops::Range` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` + --> $DIR/range_traits-1.rs:12:5 + | +LL | b: RangeTo, + | ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo < std::ops::RangeTo` and `std::ops::RangeTo > std::ops::RangeTo` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` + --> $DIR/range_traits-1.rs:19:5 + | +LL | c: RangeFrom, + | ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom < std::ops::RangeFrom` and `std::ops::RangeFrom > std::ops::RangeFrom` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` + --> $DIR/range_traits-1.rs:26:5 + | +LL | d: RangeFull, + | ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` + --> $DIR/range_traits-1.rs:33:5 + | +LL | e: RangeInclusive, + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive < std::ops::RangeInclusive` and `std::ops::RangeInclusive > std::ops::RangeInclusive` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` + --> $DIR/range_traits-1.rs:40:5 | LL | f: RangeToInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive < std::ops::RangeToInclusive` and `std::ops::RangeToInclusive > std::ops::RangeToInclusive` @@ -61,7 +277,7 @@ LL | a: Range, = note: required by `std::cmp::Ord::cmp` error[E0277]: the trait bound `std::ops::RangeTo: std::cmp::Ord` is not satisfied - --> $DIR/range_traits-1.rs:8:5 + --> $DIR/range_traits-1.rs:12:5 | LL | b: RangeTo, | ^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeTo` @@ -69,7 +285,7 @@ LL | b: RangeTo, = note: required by `std::cmp::Ord::cmp` error[E0277]: the trait bound `std::ops::RangeFrom: std::cmp::Ord` is not satisfied - --> $DIR/range_traits-1.rs:11:5 + --> $DIR/range_traits-1.rs:19:5 | LL | c: RangeFrom, | ^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeFrom` @@ -77,7 +293,7 @@ LL | c: RangeFrom, = note: required by `std::cmp::Ord::cmp` error[E0277]: the trait bound `std::ops::RangeFull: std::cmp::Ord` is not satisfied - --> $DIR/range_traits-1.rs:14:5 + --> $DIR/range_traits-1.rs:26:5 | LL | d: RangeFull, | ^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeFull` @@ -85,7 +301,7 @@ LL | d: RangeFull, = note: required by `std::cmp::Ord::cmp` error[E0277]: the trait bound `std::ops::RangeInclusive: std::cmp::Ord` is not satisfied - --> $DIR/range_traits-1.rs:17:5 + --> $DIR/range_traits-1.rs:33:5 | LL | e: RangeInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeInclusive` @@ -93,13 +309,13 @@ LL | e: RangeInclusive, = note: required by `std::cmp::Ord::cmp` error[E0277]: the trait bound `std::ops::RangeToInclusive: std::cmp::Ord` is not satisfied - --> $DIR/range_traits-1.rs:20:5 + --> $DIR/range_traits-1.rs:40:5 | LL | f: RangeToInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeToInclusive` | = note: required by `std::cmp::Ord::cmp` -error: aborting due to 12 previous errors +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/regions/regions-close-object-into-object-5.rs b/src/test/ui/regions/regions-close-object-into-object-5.rs index 609c8ce2792c5..2921a2bb398c3 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.rs +++ b/src/test/ui/regions/regions-close-object-into-object-5.rs @@ -21,6 +21,7 @@ fn f<'a, T, U>(v: Box+'static>) -> Box { //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr index 01975d40fdf1f..7c530cec7c31a 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr @@ -88,6 +88,21 @@ note: ...so that the type `(dyn A + 'static)` is not borrowed for too long LL | box B(&*v) as Box | ^^^ -error: aborting due to 6 previous errors +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/regions-close-object-into-object-5.rs:17:11 + | +LL | fn f<'a, T, U>(v: Box+'static>) -> Box { + | - help: consider adding an explicit lifetime bound `T: 'static`... +LL | // oh dear! +LL | box B(&*v) as Box + | ^^^ + | +note: ...so that the type `(dyn A + 'static)` is not borrowed for too long + --> $DIR/regions-close-object-into-object-5.rs:17:11 + | +LL | box B(&*v) as Box + | ^^^ + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.rs b/src/test/ui/regions/regions-normalize-in-where-clause-list.rs index e94e8b25d6529..e912805d855d2 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.rs +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.rs @@ -20,6 +20,8 @@ fn foo<'a: 'b, 'b>() // Here we get an error: we need `'a: 'b`. fn bar<'a, 'b>() //~ ERROR cannot infer + //~| ERROR cannot infer + //~| ERROR cannot infer where <() as Project<'a, 'b>>::Item : Eq { } diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr index 8a600d2a1e695..cc2245f81ace5 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -2,6 +2,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 | LL | / fn bar<'a, 'b>() +LL | | +LL | | LL | | where <() as Project<'a, 'b>>::Item : Eq LL | | { LL | | } @@ -21,6 +23,8 @@ note: ...so that the types are compatible --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 | LL | / fn bar<'a, 'b>() +LL | | +LL | | LL | | where <() as Project<'a, 'b>>::Item : Eq LL | | { LL | | } @@ -28,6 +32,74 @@ LL | | } = note: expected `Project<'a, 'b>` found `Project<'_, '_>` -error: aborting due to previous error +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + | +LL | / fn bar<'a, 'b>() +LL | | +LL | | +LL | | where <() as Project<'a, 'b>>::Item : Eq +LL | | { +LL | | } + | |_^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8... + --> $DIR/regions-normalize-in-where-clause-list.rs:22:8 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12... + --> $DIR/regions-normalize-in-where-clause-list.rs:22:12 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...so that the types are compatible + --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + | +LL | / fn bar<'a, 'b>() +LL | | +LL | | +LL | | where <() as Project<'a, 'b>>::Item : Eq +LL | | { +LL | | } + | |_^ + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` + +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + | +LL | / fn bar<'a, 'b>() +LL | | +LL | | +LL | | where <() as Project<'a, 'b>>::Item : Eq +LL | | { +LL | | } + | |_^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8... + --> $DIR/regions-normalize-in-where-clause-list.rs:22:8 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12... + --> $DIR/regions-normalize-in-where-clause-list.rs:22:12 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...so that the types are compatible + --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + | +LL | / fn bar<'a, 'b>() +LL | | +LL | | +LL | | where <() as Project<'a, 'b>>::Item : Eq +LL | | { +LL | | } + | |_^ + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/repr/repr-align-assign.fixed b/src/test/ui/repr/repr-align-assign.fixed index 2e1d9a2d32691..59ca22e9728c6 100644 --- a/src/test/ui/repr/repr-align-assign.fixed +++ b/src/test/ui/repr/repr-align-assign.fixed @@ -3,9 +3,11 @@ #![allow(dead_code)] #[repr(align(8))] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format struct A(u64); #[repr(align(8))] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format struct B(u64); fn main() {} diff --git a/src/test/ui/repr/repr-align-assign.rs b/src/test/ui/repr/repr-align-assign.rs index b8f7c15ded695..6b7799297e89e 100644 --- a/src/test/ui/repr/repr-align-assign.rs +++ b/src/test/ui/repr/repr-align-assign.rs @@ -3,9 +3,11 @@ #![allow(dead_code)] #[repr(align=8)] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format struct A(u64); #[repr(align="8")] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format struct B(u64); fn main() {} diff --git a/src/test/ui/repr/repr-align-assign.stderr b/src/test/ui/repr/repr-align-assign.stderr index 177bd81e8f265..192312d165bc8 100644 --- a/src/test/ui/repr/repr-align-assign.stderr +++ b/src/test/ui/repr/repr-align-assign.stderr @@ -5,10 +5,22 @@ LL | #[repr(align=8)] | ^^^^^^^ help: use parentheses instead: `align(8)` error[E0693]: incorrect `repr(align)` attribute format - --> $DIR/repr-align-assign.rs:8:8 + --> $DIR/repr-align-assign.rs:9:8 | LL | #[repr(align="8")] | ^^^^^^^^^ help: use parentheses instead: `align(8)` -error: aborting due to 2 previous errors +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:5:8 + | +LL | #[repr(align=8)] + | ^^^^^^^ help: use parentheses instead: `align(8)` + +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:9:8 + | +LL | #[repr(align="8")] + | ^^^^^^^^^ help: use parentheses instead: `align(8)` + +error: aborting due to 4 previous errors diff --git a/src/test/ui/repr/repr-align.rs b/src/test/ui/repr/repr-align.rs index bc6a9fe562a67..58ecf9a518327 100644 --- a/src/test/ui/repr/repr-align.rs +++ b/src/test/ui/repr/repr-align.rs @@ -1,24 +1,30 @@ #![allow(dead_code)] #[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer + //~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer struct S0(i32); #[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two + //~| ERROR: invalid `repr(align)` attribute: not a power of two struct S1(i32); #[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29 + //~| ERROR: invalid `repr(align)` attribute: larger than 2^29 struct S2(i32); #[repr(align(536870912))] // ok: this is the largest accepted alignment struct S3(i32); #[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer + //~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer enum E0 { A, B } #[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two + //~| ERROR: invalid `repr(align)` attribute: not a power of two enum E1 { A, B } #[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29 + //~| ERROR: invalid `repr(align)` attribute: larger than 2^29 enum E2 { A, B } #[repr(align(536870912))] // ok: this is the largest accepted alignment diff --git a/src/test/ui/repr/repr-align.stderr b/src/test/ui/repr/repr-align.stderr index 280cab2b4a144..900a811bb8ad7 100644 --- a/src/test/ui/repr/repr-align.stderr +++ b/src/test/ui/repr/repr-align.stderr @@ -5,35 +5,71 @@ LL | #[repr(align(16.0))] | ^^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:6:8 + --> $DIR/repr-align.rs:7:8 | LL | #[repr(align(15))] | ^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:9:8 + --> $DIR/repr-align.rs:11:8 | LL | #[repr(align(4294967296))] | ^^^^^^^^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:15:8 + --> $DIR/repr-align.rs:18:8 + | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:22:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:26:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/repr-align.rs:3:8 | LL | #[repr(align(16.0))] | ^^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:7:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:11:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer --> $DIR/repr-align.rs:18:8 | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:22:8 + | LL | #[repr(align(15))] | ^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:21:8 + --> $DIR/repr-align.rs:26:8 | LL | #[repr(align(4294967296))] | ^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0589`. diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs index 64987663adb90..f5cb1860d4786 100644 --- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs @@ -123,9 +123,11 @@ fn _macros() { use_expr!((let 0 = 1 && 0 == 0)); //~^ ERROR `let` expressions in this position are experimental [E0658] //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here use_expr!((let 0 = 1)); //~^ ERROR `let` expressions in this position are experimental [E0658] //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here #[cfg(FALSE)] (let 0 = 1); //~^ ERROR `let` expressions in this position are experimental [E0658] use_expr!(let 0 = 1); diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr index abe200944b969..c14a45af40bb1 100644 --- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr @@ -1,5 +1,5 @@ error: no rules expected the token `let` - --> $DIR/feature-gate.rs:131:15 + --> $DIR/feature-gate.rs:133:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -260,7 +260,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:129:20 + --> $DIR/feature-gate.rs:131:20 | LL | #[cfg(FALSE)] (let 0 = 1); | ^^^^^^^^^ @@ -287,7 +287,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:126:16 + --> $DIR/feature-gate.rs:127:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ @@ -557,7 +557,25 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:126:16 + --> $DIR/feature-gate.rs:123:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:127:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:127:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ @@ -565,6 +583,6 @@ LL | use_expr!((let 0 = 1)); = note: only supported directly in conditions of `if`- and `while`-expressions = note: as well as when nested within `&&` and parenthesis in those conditions -error: aborting due to 63 previous errors +error: aborting due to 65 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs index b8949ae8b500f..e9dcb4f85f60b 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs @@ -21,6 +21,7 @@ fn main() { match WRAP_DIRECT_INLINE { WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` _ => { println!("WRAP_DIRECT_INLINE did not match itself"); } } } diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr index c73a6cf1326b3..9c7d1f3a18fec 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr @@ -4,5 +4,11 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be ann LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9 + | +LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs index 584e7a00f0993..ab1cb3babaa25 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs @@ -21,6 +21,7 @@ fn main() { match WRAP_DIRECT_PARAM { WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` _ => { println!("WRAP_DIRECT_PARAM did not match itself"); } } } diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr index 6fdf9db89b8dc..6f49a8a0c9d21 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr @@ -4,5 +4,11 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be ann LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-direct-struct-param.rs:22:9 + | +LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc1445/match-forbidden-without-eq.rs b/src/test/ui/rfc1445/match-forbidden-without-eq.rs index 1cca27520618d..59141eac3e896 100644 --- a/src/test/ui/rfc1445/match-forbidden-without-eq.rs +++ b/src/test/ui/rfc1445/match-forbidden-without-eq.rs @@ -12,6 +12,7 @@ fn main() { match y { FOO => { } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` _ => { } } diff --git a/src/test/ui/rfc1445/match-forbidden-without-eq.stderr b/src/test/ui/rfc1445/match-forbidden-without-eq.stderr index c05bb8f19f362..b9476e399f3e7 100644 --- a/src/test/ui/rfc1445/match-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/match-forbidden-without-eq.stderr @@ -5,7 +5,7 @@ LL | FOO => { } | ^^^ warning: floating-point types cannot be used in patterns - --> $DIR/match-forbidden-without-eq.rs:20:9 + --> $DIR/match-forbidden-without-eq.rs:21:9 | LL | f32::INFINITY => { } | ^^^^^^^^^^^^^ @@ -14,8 +14,14 @@ LL | f32::INFINITY => { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 +error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match-forbidden-without-eq.rs:13:9 + | +LL | FOO => { } + | ^^^ + warning: floating-point types cannot be used in patterns - --> $DIR/match-forbidden-without-eq.rs:20:9 + --> $DIR/match-forbidden-without-eq.rs:21:9 | LL | f32::INFINITY => { } | ^^^^^^^^^^^^^ @@ -23,5 +29,5 @@ LL | f32::INFINITY => { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 -error: aborting due to previous error +error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs index 3d56fb05dc460..9ef8a68da80b9 100644 --- a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs +++ b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs @@ -15,5 +15,6 @@ fn main() { match [B(1)] { FOO => { } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` } } diff --git a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr index 371f8a0aa1d77..7e354bf9ade5a 100644 --- a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr @@ -4,5 +4,11 @@ error: to use a constant of type `B` in a pattern, `B` must be annotated with `# LL | FOO => { } | ^^^ -error: aborting due to previous error +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match-nonempty-array-forbidden-without-eq.rs:16:9 + | +LL | FOO => { } + | ^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.rs b/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.rs index 6b7d94603b567..9530a1ffec453 100644 --- a/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.rs +++ b/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.rs @@ -16,6 +16,7 @@ fn main() { match y { FOO => { } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` _ => { } } } diff --git a/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.stderr b/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.stderr index 4157cf65283e3..7ef082852ba8d 100644 --- a/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.stderr +++ b/src/test/ui/rfc1445/match-requires-both-partialeq-and-eq.stderr @@ -4,5 +4,11 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit LL | FOO => { } | ^^^ -error: aborting due to previous error +error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match-requires-both-partialeq-and-eq.rs:17:9 + | +LL | FOO => { } + | ^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs index 27d6dbf4683e3..0ca7fa37a3096 100644 --- a/src/test/ui/rust-2018/uniform-paths/cross-crate.rs +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs @@ -6,6 +6,7 @@ use cross_crate::*; #[built_in_attr] //~ ERROR cannot use a built-in attribute through an import #[tool_mod::skip] //~ ERROR cannot use a tool module through an import + //~| ERROR cannot use a tool module through an import fn main() { let _: built_in_type; // OK } diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr index fdde75faf5f04..45f77a0c9fe6a 100644 --- a/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr @@ -22,5 +22,17 @@ note: the tool module imported here LL | use cross_crate::*; | ^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: cannot use a tool module through an import + --> $DIR/cross-crate.rs:8:3 + | +LL | #[tool_mod::skip] + | ^^^^^^^^ + | +note: the tool module imported here + --> $DIR/cross-crate.rs:5:5 + | +LL | use cross_crate::*; + | ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs index 541fc1be4e82f..44da71de085be 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs @@ -15,5 +15,7 @@ mod tool_mod { #[imported_inline] //~ ERROR cannot use a built-in attribute through an import #[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import #[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import + //~| ERROR cannot use a tool module through an import #[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import + //~| ERROR cannot use a tool module through an import fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr index fc6453193bc98..908bb49858613 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr @@ -29,7 +29,7 @@ LL | use rustfmt as imported_rustfmt; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot use a tool module through an import - --> $DIR/prelude-fail-2.rs:18:13 + --> $DIR/prelude-fail-2.rs:19:13 | LL | #[tool_mod::imported_rustfmt::skip] | ^^^^^^^^^^^^^^^^ @@ -40,5 +40,29 @@ note: the tool module imported here LL | pub use rustfmt as imported_rustfmt; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: cannot use a tool module through an import + --> $DIR/prelude-fail-2.rs:17:3 + | +LL | #[imported_rustfmt::skip] + | ^^^^^^^^^^^^^^^^ + | +note: the tool module imported here + --> $DIR/prelude-fail-2.rs:10:5 + | +LL | use rustfmt as imported_rustfmt; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot use a tool module through an import + --> $DIR/prelude-fail-2.rs:19:13 + | +LL | #[tool_mod::imported_rustfmt::skip] + | ^^^^^^^^^^^^^^^^ + | +note: the tool module imported here + --> $DIR/prelude-fail-2.rs:12:13 + | +LL | pub use rustfmt as imported_rustfmt; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs index 8f1599a5abcb0..89b8eba1e95e7 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.rs +++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs @@ -5,6 +5,9 @@ //~| ERROR cannot determine resolution for the derive macro `Debug` //~| ERROR cannot determine resolution for the derive macro `PartialEq` //~| ERROR cannot determine resolution for the derive macro `Eq` +//~| ERROR cannot determine resolution for the derive macro `Debug` +//~| ERROR cannot determine resolution for the derive macro `PartialEq` +//~| ERROR cannot determine resolution for the derive macro `Eq` struct DerivedOn; fn main() {} diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr index 47ce718600cec..b68681c52973a 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.stderr +++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr @@ -28,5 +28,29 @@ LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! | = note: import resolution is stuck, try simplifying macro imports -error: aborting due to 4 previous errors +error: cannot determine resolution for the derive macro `Eq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:29 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `PartialEq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:18 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `Debug` + --> $DIR/issue-43927-non-ADT-derive.rs:3:11 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 7 previous errors diff --git a/src/test/ui/suffixed-literal-meta.rs b/src/test/ui/suffixed-literal-meta.rs index a6531490c0159..c3a4eabad7050 100644 --- a/src/test/ui/suffixed-literal-meta.rs +++ b/src/test/ui/suffixed-literal-meta.rs @@ -1,15 +1,27 @@ #![feature(rustc_attrs)] #[rustc_dummy = 1usize] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1u8] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1u16] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1u32] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1u64] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1isize] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1i8] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1i16] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1i32] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1i64] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1.0f32] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes #[rustc_dummy = 1.0f64] //~ ERROR: suffixed literals are not allowed in attributes + //~| ERROR: suffixed literals are not allowed in attributes fn main() {} diff --git a/src/test/ui/suffixed-literal-meta.stderr b/src/test/ui/suffixed-literal-meta.stderr index 83de173b1a703..ee35b53abe111 100644 --- a/src/test/ui/suffixed-literal-meta.stderr +++ b/src/test/ui/suffixed-literal-meta.stderr @@ -7,7 +7,7 @@ LL | #[rustc_dummy = 1usize] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:4:17 + --> $DIR/suffixed-literal-meta.rs:5:17 | LL | #[rustc_dummy = 1u8] | ^^^ @@ -15,7 +15,7 @@ LL | #[rustc_dummy = 1u8] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:5:17 + --> $DIR/suffixed-literal-meta.rs:7:17 | LL | #[rustc_dummy = 1u16] | ^^^^ @@ -23,7 +23,7 @@ LL | #[rustc_dummy = 1u16] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:6:17 + --> $DIR/suffixed-literal-meta.rs:9:17 | LL | #[rustc_dummy = 1u32] | ^^^^ @@ -31,7 +31,7 @@ LL | #[rustc_dummy = 1u32] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:7:17 + --> $DIR/suffixed-literal-meta.rs:11:17 | LL | #[rustc_dummy = 1u64] | ^^^^ @@ -39,7 +39,7 @@ LL | #[rustc_dummy = 1u64] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:8:17 + --> $DIR/suffixed-literal-meta.rs:13:17 | LL | #[rustc_dummy = 1isize] | ^^^^^^ @@ -47,7 +47,7 @@ LL | #[rustc_dummy = 1isize] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:9:17 + --> $DIR/suffixed-literal-meta.rs:15:17 | LL | #[rustc_dummy = 1i8] | ^^^ @@ -55,7 +55,7 @@ LL | #[rustc_dummy = 1i8] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:10:17 + --> $DIR/suffixed-literal-meta.rs:17:17 | LL | #[rustc_dummy = 1i16] | ^^^^ @@ -63,7 +63,7 @@ LL | #[rustc_dummy = 1i16] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:11:17 + --> $DIR/suffixed-literal-meta.rs:19:17 | LL | #[rustc_dummy = 1i32] | ^^^^ @@ -71,28 +71,124 @@ LL | #[rustc_dummy = 1i32] = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:12:17 + --> $DIR/suffixed-literal-meta.rs:21:17 | LL | #[rustc_dummy = 1i64] | ^^^^ | = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:23:17 + | +LL | #[rustc_dummy = 1.0f32] + | ^^^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:25:17 + | +LL | #[rustc_dummy = 1.0f64] + | ^^^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:3:17 + | +LL | #[rustc_dummy = 1usize] + | ^^^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:5:17 + | +LL | #[rustc_dummy = 1u8] + | ^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:7:17 + | +LL | #[rustc_dummy = 1u16] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:9:17 + | +LL | #[rustc_dummy = 1u32] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:11:17 + | +LL | #[rustc_dummy = 1u64] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:13:17 | +LL | #[rustc_dummy = 1isize] + | ^^^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:15:17 + | +LL | #[rustc_dummy = 1i8] + | ^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:17:17 + | +LL | #[rustc_dummy = 1i16] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:19:17 + | +LL | #[rustc_dummy = 1i32] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:21:17 + | +LL | #[rustc_dummy = 1i64] + | ^^^^ + | + = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + +error: suffixed literals are not allowed in attributes + --> $DIR/suffixed-literal-meta.rs:23:17 + | LL | #[rustc_dummy = 1.0f32] | ^^^^^^ | = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: suffixed literals are not allowed in attributes - --> $DIR/suffixed-literal-meta.rs:14:17 + --> $DIR/suffixed-literal-meta.rs:25:17 | LL | #[rustc_dummy = 1.0f64] | ^^^^^^ | = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). -error: aborting due to 12 previous errors +error: aborting due to 24 previous errors diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs index d5698be8d4c57..bf45ba2ed8227 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -2,6 +2,7 @@ type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt` type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip` #[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` in this scope + //~| ERROR cannot find derive macro `rustfmt` in this scope struct S; // Interpreted as an unstable custom attribute diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr index b831e624cb6ff..71fd5f1d44a8d 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -4,14 +4,20 @@ error: cannot find derive macro `rustfmt` in this scope LL | #[derive(rustfmt)] | ^^^^^^^ +error: cannot find derive macro `rustfmt` in this scope + --> $DIR/tool-attributes-misplaced-1.rs:4:10 + | +LL | #[derive(rustfmt)] + | ^^^^^^^ + error: cannot find attribute `rustfmt` in this scope - --> $DIR/tool-attributes-misplaced-1.rs:8:3 + --> $DIR/tool-attributes-misplaced-1.rs:9:3 | LL | #[rustfmt] | ^^^^^^^ error: cannot find macro `rustfmt` in this scope - --> $DIR/tool-attributes-misplaced-1.rs:14:5 + --> $DIR/tool-attributes-misplaced-1.rs:15:5 | LL | rustfmt!(); | ^^^^^^^ @@ -29,18 +35,18 @@ LL | type B = rustfmt::skip; | ^^^^^^^^^^^^^ not a type error[E0423]: expected value, found tool module `rustfmt` - --> $DIR/tool-attributes-misplaced-1.rs:13:5 + --> $DIR/tool-attributes-misplaced-1.rs:14:5 | LL | rustfmt; | ^^^^^^^ not a value error[E0423]: expected value, found tool attribute `rustfmt::skip` - --> $DIR/tool-attributes-misplaced-1.rs:16:5 + --> $DIR/tool-attributes-misplaced-1.rs:17:5 | LL | rustfmt::skip; | ^^^^^^^^^^^^^ not a value -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0423, E0573. For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs index fa8f041c646c2..9c8540eede792 100644 --- a/src/test/ui/tool_lints.rs +++ b/src/test/ui/tool_lints.rs @@ -1,3 +1,5 @@ #[warn(foo::bar)] //~^ ERROR an unknown tool name found in scoped lint: `foo::bar` +//~| ERROR an unknown tool name found in scoped lint: `foo::bar` +//~| ERROR an unknown tool name found in scoped lint: `foo::bar` fn main() {} diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr index de941604a9491..86f87784eaf86 100644 --- a/src/test/ui/tool_lints.stderr +++ b/src/test/ui/tool_lints.stderr @@ -4,5 +4,17 @@ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` LL | #[warn(foo::bar)] | ^^^ -error: aborting due to previous error +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/tool_lints.rs:1:8 + | +LL | #[warn(foo::bar)] + | ^^^ + +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/tool_lints.rs:1:8 + | +LL | #[warn(foo::bar)] + | ^^^ + +error: aborting due to 3 previous errors diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.rs b/src/test/ui/tuple/tuple-struct-fields/test2.rs index fc0f78b12c9f7..2b2a2c127e985 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test2.rs +++ b/src/test/ui/tuple/tuple-struct-fields/test2.rs @@ -9,6 +9,7 @@ macro_rules! define_struct { mod foo { define_struct! { (foo) } //~ ERROR cannot find type `foo` in this scope + //~| ERROR cannot find type `foo` in this scope } fn main() {} diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.stderr b/src/test/ui/tuple/tuple-struct-fields/test2.stderr index d924c351439bd..2f1ca2fe0c1e7 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test2.stderr +++ b/src/test/ui/tuple/tuple-struct-fields/test2.stderr @@ -15,6 +15,12 @@ error[E0412]: cannot find type `foo` in this scope LL | define_struct! { (foo) } | ^^^ not found in this scope -error: aborting due to 2 previous errors +error[E0412]: cannot find type `foo` in this scope + --> $DIR/test2.rs:11:23 + | +LL | define_struct! { (foo) } + | ^^^ not found in this scope + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.rs b/src/test/ui/tuple/tuple-struct-fields/test3.rs index 6b8534b452411..98d19426e7733 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test3.rs +++ b/src/test/ui/tuple/tuple-struct-fields/test3.rs @@ -9,6 +9,7 @@ macro_rules! define_struct { mod foo { define_struct! { foo } //~ ERROR cannot find type `foo` in this scope + //~| ERROR cannot find type `foo` in this scope } fn main() {} diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.stderr b/src/test/ui/tuple/tuple-struct-fields/test3.stderr index 50cac6c179e31..5d42fe6ef50b3 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test3.stderr +++ b/src/test/ui/tuple/tuple-struct-fields/test3.stderr @@ -15,6 +15,12 @@ error[E0412]: cannot find type `foo` in this scope LL | define_struct! { foo } | ^^^ not found in this scope -error: aborting due to 2 previous errors +error[E0412]: cannot find type `foo` in this scope + --> $DIR/test3.rs:11:22 + | +LL | define_struct! { foo } + | ^^^ not found in this scope + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/union/union-const-pat.rs b/src/test/ui/union/union-const-pat.rs index e7cb248a201ac..cb2248cc6d189 100644 --- a/src/test/ui/union/union-const-pat.rs +++ b/src/test/ui/union/union-const-pat.rs @@ -8,6 +8,7 @@ const C: U = U { a: 10 }; fn main() { match C { C => {} //~ ERROR cannot use unions in constant patterns + //~| ERROR cannot use unions in constant patterns _ => {} } } diff --git a/src/test/ui/union/union-const-pat.stderr b/src/test/ui/union/union-const-pat.stderr index dc87f4de5219f..bec720401b9e1 100644 --- a/src/test/ui/union/union-const-pat.stderr +++ b/src/test/ui/union/union-const-pat.stderr @@ -4,5 +4,11 @@ error: cannot use unions in constant patterns LL | C => {} | ^ -error: aborting due to previous error +error: cannot use unions in constant patterns + --> $DIR/union-const-pat.rs:10:9 + | +LL | C => {} + | ^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs index c92a71e939711..182aec34b4781 100644 --- a/src/test/ui/unknown-lint-tool-name.rs +++ b/src/test/ui/unknown-lint-tool-name.rs @@ -1,4 +1,8 @@ #![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` #[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` fn main() {} diff --git a/src/test/ui/unknown-lint-tool-name.stderr b/src/test/ui/unknown-lint-tool-name.stderr index dd3070bbcb3d2..1940f61a47b68 100644 --- a/src/test/ui/unknown-lint-tool-name.stderr +++ b/src/test/ui/unknown-lint-tool-name.stderr @@ -5,10 +5,34 @@ LL | #![deny(foo::bar)] | ^^^ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:3:9 + --> $DIR/unknown-lint-tool-name.rs:5:9 | LL | #[allow(foo::bar)] | ^^^ -error: aborting due to 2 previous errors +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:1:9 + | +LL | #![deny(foo::bar)] + | ^^^ + +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:5:9 + | +LL | #[allow(foo::bar)] + | ^^^ + +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:1:9 + | +LL | #![deny(foo::bar)] + | ^^^ + +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:5:9 + | +LL | #[allow(foo::bar)] + | ^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/use/use-super-global-path.rs b/src/test/ui/use/use-super-global-path.rs index 3e0ebccc0a0d6..27a4a653b4903 100644 --- a/src/test/ui/use/use-super-global-path.rs +++ b/src/test/ui/use/use-super-global-path.rs @@ -5,6 +5,7 @@ struct Z; mod foo { use ::super::{S, Z}; //~ ERROR global paths cannot start with `super` + //~| ERROR global paths cannot start with `super` pub fn g() { use ::super::main; //~ ERROR global paths cannot start with `super` diff --git a/src/test/ui/use/use-super-global-path.stderr b/src/test/ui/use/use-super-global-path.stderr index 3ca30ebebbab7..7f98ac7cd0fef 100644 --- a/src/test/ui/use/use-super-global-path.stderr +++ b/src/test/ui/use/use-super-global-path.stderr @@ -5,13 +5,19 @@ LL | use ::super::{S, Z}; | ^^^^^ global paths cannot start with `super` error[E0433]: failed to resolve: global paths cannot start with `super` - --> $DIR/use-super-global-path.rs:10:15 + --> $DIR/use-super-global-path.rs:7:11 + | +LL | use ::super::{S, Z}; + | ^^^^^ global paths cannot start with `super` + +error[E0433]: failed to resolve: global paths cannot start with `super` + --> $DIR/use-super-global-path.rs:11:15 | LL | use ::super::main; | ^^^^^ global paths cannot start with `super` error[E0425]: cannot find function `main` in this scope - --> $DIR/use-super-global-path.rs:11:9 + --> $DIR/use-super-global-path.rs:12:9 | LL | main(); | ^^^^ not found in this scope @@ -21,7 +27,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use main; | -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0425, E0433. For more information about an error, try `rustc --explain E0425`. From 4e98966757cad7301ed2ae350d600c1678cc5116 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Thu, 9 Jan 2020 13:11:54 -0500 Subject: [PATCH 0111/1253] stabalize ManuallyDrop::take --- src/libcore/mem/manually_drop.rs | 15 ++++++++------- src/libstd/lib.rs | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs index 36064488eb249..4c3b81ea5eca5 100644 --- a/src/libcore/mem/manually_drop.rs +++ b/src/libcore/mem/manually_drop.rs @@ -87,27 +87,28 @@ impl ManuallyDrop { slot.value } - /// Takes the contained value out. + /// Takes the value from the `ManuallyDrop` container out. /// /// This method is primarily intended for moving out values in drop. /// Instead of using [`ManuallyDrop::drop`] to manually drop the value, /// you can use this method to take the value and use it however desired. - /// `Drop` will be invoked on the returned value following normal end-of-scope rules. /// - /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead. + /// Whenever possible, it is preferrable to use [`into_inner`][`ManuallyDrop::into_inner`] + /// instead, which prevents duplicating the content of the `ManuallyDrop`. /// /// # Safety /// - /// This function semantically moves out the contained value without preventing further usage. - /// It is up to the user of this method to ensure that this container is not used again. + /// This function semantically moves out the contained value without preventing further usage, + /// leaving the state of this container unchanged. + /// It is your responsibility to ensure that this `ManuallyDrop` is not used again. /// /// [`ManuallyDrop::drop`]: #method.drop /// [`ManuallyDrop::into_inner`]: #method.into_inner #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"] - #[unstable(feature = "manually_drop_take", issue = "55422")] + #[stable(feature = "manually_drop_take", since = "1.42.0")] #[inline] pub unsafe fn take(slot: &mut ManuallyDrop) -> T { - ManuallyDrop::into_inner(ptr::read(slot)) + ptr::read(&slot.value) } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f90647472c678..32e6869a8c1ce 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -275,7 +275,6 @@ #![feature(link_args)] #![feature(linkage)] #![feature(log_syntax)] -#![feature(manually_drop_take)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] #![feature(needs_panic_runtime)] From e47fec56dd438c416ce45b06c9b3b23103c4ee3a Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Sat, 9 Nov 2019 13:43:11 -0500 Subject: [PATCH 0112/1253] Make Layout::new const --- src/libcore/alloc.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index b2d4b1b5fb916..37672888d0127 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -17,7 +17,7 @@ use crate::usize; #[derive(Debug)] pub struct Excess(pub NonNull, pub usize); -fn size_align() -> (usize, usize) { +const fn size_align() -> (usize, usize) { (mem::size_of::(), mem::align_of::()) } @@ -121,13 +121,12 @@ impl Layout { /// Constructs a `Layout` suitable for holding a value of type `T`. #[stable(feature = "alloc_layout", since = "1.28.0")] #[inline] - pub fn new() -> Self { + pub const fn new() -> Self { let (size, align) = size_align::(); // Note that the align is guaranteed by rustc to be a power of two and // the size+align combo is guaranteed to fit in our address space. As a // result use the unchecked constructor here to avoid inserting code // that panics if it isn't optimized well enough. - debug_assert!(Layout::from_size_align(size, align).is_ok()); unsafe { Layout::from_size_align_unchecked(size, align) } } From d860def8e2e2c807c37907c764b937ec35d4f2e6 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Tue, 17 Dec 2019 14:55:46 -0500 Subject: [PATCH 0113/1253] Mark Layout::new as const stable --- src/libcore/alloc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 37672888d0127..163f9170b8bfb 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -120,6 +120,7 @@ impl Layout { /// Constructs a `Layout` suitable for holding a value of type `T`. #[stable(feature = "alloc_layout", since = "1.28.0")] + #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")] #[inline] pub const fn new() -> Self { let (size, align) = size_align::(); From b82cd9f6391df865551bc6c756cc29a7993e39be Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 8 Jan 2020 23:16:57 +0300 Subject: [PATCH 0114/1253] Address review comments + Update NLL tests --- ...duplicate-diagnostics-2.deduplicate.stderr | 28 ++++++++++++++ ...deduplicate-diagnostics-2.duplicate.stderr | 37 +++++++++++++++++++ src/test/ui/deduplicate-diagnostics-2.rs | 17 +++++++++ ...deduplicate-diagnostics.deduplicate.stderr | 9 ++++- .../deduplicate-diagnostics.duplicate.stderr | 21 ++++++++++- src/test/ui/deduplicate-diagnostics.rs | 3 ++ .../generator/auto-trait-regions.nll.stderr | 6 +-- .../hrtb/hrtb-perfect-forwarding.nll.stderr | 3 +- 8 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/deduplicate-diagnostics-2.deduplicate.stderr create mode 100644 src/test/ui/deduplicate-diagnostics-2.duplicate.stderr create mode 100644 src/test/ui/deduplicate-diagnostics-2.rs diff --git a/src/test/ui/deduplicate-diagnostics-2.deduplicate.stderr b/src/test/ui/deduplicate-diagnostics-2.deduplicate.stderr new file mode 100644 index 0000000000000..7a28c6428a355 --- /dev/null +++ b/src/test/ui/deduplicate-diagnostics-2.deduplicate.stderr @@ -0,0 +1,28 @@ +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:7:9 + | +LL | 1.0 => {} + | ^^^ + | + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:11:9 + | +LL | 2.0 => {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:7:9 + | +LL | 1.0 => {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + diff --git a/src/test/ui/deduplicate-diagnostics-2.duplicate.stderr b/src/test/ui/deduplicate-diagnostics-2.duplicate.stderr new file mode 100644 index 0000000000000..4fff3a8c0f374 --- /dev/null +++ b/src/test/ui/deduplicate-diagnostics-2.duplicate.stderr @@ -0,0 +1,37 @@ +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:7:9 + | +LL | 1.0 => {} + | ^^^ + | + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:11:9 + | +LL | 2.0 => {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:7:9 + | +LL | 1.0 => {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/deduplicate-diagnostics-2.rs:11:9 + | +LL | 2.0 => {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + diff --git a/src/test/ui/deduplicate-diagnostics-2.rs b/src/test/ui/deduplicate-diagnostics-2.rs new file mode 100644 index 0000000000000..f46a7c0c1c4d8 --- /dev/null +++ b/src/test/ui/deduplicate-diagnostics-2.rs @@ -0,0 +1,17 @@ +// build-pass +// revisions: duplicate deduplicate +//[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes + +fn main() { + match 0.0 { + 1.0 => {} //~ WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted + //~| WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted + 2.0 => {} //~ WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted + //[duplicate]~| WARNING floating-point types cannot be used in patterns + //[duplicate]~| WARNING this was previously accepted + _ => {} + } +} diff --git a/src/test/ui/deduplicate-diagnostics.deduplicate.stderr b/src/test/ui/deduplicate-diagnostics.deduplicate.stderr index 1acfce506229f..5df2c687bddc2 100644 --- a/src/test/ui/deduplicate-diagnostics.deduplicate.stderr +++ b/src/test/ui/deduplicate-diagnostics.deduplicate.stderr @@ -1,8 +1,15 @@ +error[E0452]: malformed lint attribute input + --> $DIR/deduplicate-diagnostics.rs:8:8 + | +LL | #[deny("literal")] + | ^^^^^^^^^ bad attribute argument + error: cannot find derive macro `Unresolved` in this scope --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] | ^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/deduplicate-diagnostics.duplicate.stderr b/src/test/ui/deduplicate-diagnostics.duplicate.stderr index 325da3b5d915b..3b100b59995f0 100644 --- a/src/test/ui/deduplicate-diagnostics.duplicate.stderr +++ b/src/test/ui/deduplicate-diagnostics.duplicate.stderr @@ -1,3 +1,9 @@ +error[E0452]: malformed lint attribute input + --> $DIR/deduplicate-diagnostics.rs:8:8 + | +LL | #[deny("literal")] + | ^^^^^^^^^ bad attribute argument + error: cannot find derive macro `Unresolved` in this scope --> $DIR/deduplicate-diagnostics.rs:4:10 | @@ -10,5 +16,18 @@ error: cannot find derive macro `Unresolved` in this scope LL | #[derive(Unresolved)] | ^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/deduplicate-diagnostics.rs:8:8 + | +LL | #[deny("literal")] + | ^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/deduplicate-diagnostics.rs:8:8 + | +LL | #[deny("literal")] + | ^^^^^^^^^ bad attribute argument + +error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/deduplicate-diagnostics.rs b/src/test/ui/deduplicate-diagnostics.rs index 90ed344c11a26..c5d41ff2fdac3 100644 --- a/src/test/ui/deduplicate-diagnostics.rs +++ b/src/test/ui/deduplicate-diagnostics.rs @@ -5,4 +5,7 @@ //[duplicate]~| ERROR cannot find derive macro `Unresolved` in this scope struct S; +#[deny("literal")] //~ ERROR malformed lint attribute input + //[duplicate]~| ERROR malformed lint attribute input + //[duplicate]~| ERROR malformed lint attribute input fn main() {} diff --git a/src/test/ui/generator/auto-trait-regions.nll.stderr b/src/test/ui/generator/auto-trait-regions.nll.stderr index 4c157a05a5e05..bf87aea0d4c1a 100644 --- a/src/test/ui/generator/auto-trait-regions.nll.stderr +++ b/src/test/ui/generator/auto-trait-regions.nll.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:44:24 + --> $DIR/auto-trait-regions.rs:45:24 | LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement @@ -12,7 +12,7 @@ LL | assert_foo(a); = note: consider using a `let` binding to create a longer lived value error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:44:35 + --> $DIR/auto-trait-regions.rs:45:35 | LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement @@ -31,7 +31,7 @@ LL | assert_foo(gen); | ^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/auto-trait-regions.rs:48:5 + --> $DIR/auto-trait-regions.rs:49:5 | LL | assert_foo(gen); | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr index afa07cc60eb84..303c0cc645e38 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr @@ -39,6 +39,7 @@ LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also ... | LL | | foo_hrtb_bar_not(&mut t); | | ------------------------ recursive call site +LL | | LL | | } | |_^ cannot return without recursing | @@ -62,7 +63,7 @@ LL | foo_hrtb_bar_not(&mut t); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:49:1 + --> $DIR/hrtb-perfect-forwarding.rs:50:1 | LL | / fn foo_hrtb_bar_hrtb(mut t: T) LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> From f79ba857dd1271ea8d5207121c2487621ebc23dd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 9 Jan 2020 22:25:58 +0100 Subject: [PATCH 0115/1253] clean up E0185 explanation --- src/librustc_error_codes/error_codes/E0185.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0185.md b/src/librustc_error_codes/error_codes/E0185.md index f0ad2af144aa0..ea29e2d451622 100644 --- a/src/librustc_error_codes/error_codes/E0185.md +++ b/src/librustc_error_codes/error_codes/E0185.md @@ -2,7 +2,7 @@ An associated function for a trait was defined to be static, but an implementation of the trait declared the same function to be a method (i.e., to take a `self` parameter). -Here's an example of this error: +Erroneous code example: ```compile_fail,E0185 trait Foo { @@ -17,3 +17,19 @@ impl Foo for Bar { fn foo(&self) {} } ``` + +When a type implements a trait's associated function, it has to use the same +signature. So in this case, since `Foo::foo` doesn't take argument and doesn't +return anything, its implementation on `Bar` should the same: + +``` +trait Foo { + fn foo(); +} + +struct Bar; + +impl Foo for Bar { + fn foo() {} // ok! +} +``` From f45758cddc962248dc46d8c051f9f3a73ef50c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 5 Jan 2020 02:10:23 +0100 Subject: [PATCH 0116/1253] Compile some CGUs in parallel at the start of codegen --- src/librustc_codegen_llvm/base.rs | 10 ++-- src/librustc_codegen_llvm/lib.rs | 6 +-- src/librustc_codegen_ssa/base.rs | 59 +++++++++++++++++++--- src/librustc_codegen_ssa/traits/backend.rs | 7 ++- 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index cb44a56d07516..d3b524c1a1e70 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -13,7 +13,7 @@ //! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int, //! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`. -use super::{LlvmCodegenBackend, ModuleLlvm}; +use super::ModuleLlvm; use crate::builder::Builder; use crate::common; @@ -29,7 +29,6 @@ use rustc::middle::exported_symbols; use rustc::mir::mono::{Linkage, Visibility}; use rustc::session::config::DebugInfo; use rustc::ty::TyCtxt; -use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::*; @@ -100,8 +99,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { pub fn compile_codegen_unit( tcx: TyCtxt<'tcx>, cgu_name: Symbol, - tx_to_llvm_workers: &std::sync::mpsc::Sender>, -) { +) -> (ModuleCodegen, u64) { let prof_timer = tcx.prof.generic_activity("codegen_module"); let start_time = Instant::now(); @@ -115,8 +113,6 @@ pub fn compile_codegen_unit( // the time we needed for codegenning it. let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64; - submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tx_to_llvm_workers, module, cost); - fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... @@ -164,6 +160,8 @@ pub fn compile_codegen_unit( kind: ModuleKind::Regular, } } + + (module, cost) } pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) { diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 35c71a6675683..a6168128c4d44 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -19,6 +19,7 @@ #![feature(link_args)] #![feature(static_nobundle)] #![feature(trusted_len)] +#![recursion_limit = "256"] use back::write::{create_informational_target_machine, create_target_machine}; use rustc_span::symbol::Symbol; @@ -108,9 +109,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend { &self, tcx: TyCtxt<'_>, cgu_name: Symbol, - tx: &std::sync::mpsc::Sender>, - ) { - base::compile_codegen_unit(tcx, cgu_name, tx); + ) -> (ModuleCodegen, u64) { + base::compile_codegen_unit(tcx, cgu_name) } fn target_machine_factory( &self, diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index c838109072775..d2823381d887e 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -14,8 +14,8 @@ //! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`. use crate::back::write::{ - start_async_codegen, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, - OngoingCodegen, + start_async_codegen, submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm, + submit_pre_lto_module_to_llvm, OngoingCodegen, }; use crate::common::{IntPredicate, RealPredicate, TypeKind}; use crate::meth; @@ -40,6 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::print_time_passes_entry; +use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::Idx; @@ -606,20 +607,62 @@ pub fn codegen_crate( codegen_units }; - let mut total_codegen_time = Duration::new(0, 0); + let total_codegen_time = Lock::new(Duration::new(0, 0)); - for cgu in codegen_units.into_iter() { + let cgu_reuse: Vec<_> = tcx.sess.time("find cgu reuse", || { + codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect() + }); + + let mut cgus: FxHashMap = if cfg!(parallel_compiler) { + tcx.sess.time("compile first CGUs", || { + // Try to find one CGU to compile per thread. + let cgus: Vec<_> = cgu_reuse + .iter() + .enumerate() + .filter(|&(_, reuse)| reuse == &CguReuse::No) + .take(tcx.sess.threads()) + .collect(); + + // Compile the found CGUs in parallel. + par_iter(cgus) + .map(|(i, _)| { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); + let mut time = total_codegen_time.lock(); + *time += start_time.elapsed(); + (i, module) + }) + .collect() + }) + } else { + FxHashMap::default() + }; + + let mut total_codegen_time = total_codegen_time.into_inner(); + + for (i, cgu) in codegen_units.into_iter().enumerate() { ongoing_codegen.wait_for_signal_to_codegen_item(); ongoing_codegen.check_for_errors(tcx.sess); - let cgu_reuse = determine_cgu_reuse(tcx, &cgu); + let cgu_reuse = cgu_reuse[i]; tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse); match cgu_reuse { CguReuse::No => { - let start_time = Instant::now(); - backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send); - total_codegen_time += start_time.elapsed(); + let (module, cost) = if let Some(cgu) = cgus.remove(&i) { + cgu + } else { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, cgu.name()); + total_codegen_time += start_time.elapsed(); + module + }; + submit_codegened_module_to_llvm( + &backend, + &ongoing_codegen.coordinator_send, + module, + cost, + ); false } CguReuse::PreLto => { diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index e0d0a2f32f331..2662b81a98409 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -1,5 +1,6 @@ use super::write::WriteBackendMethods; use super::CodegenObject; +use crate::ModuleCodegen; use rustc::middle::cstore::EncodedMetadata; use rustc::session::{config, Session}; @@ -10,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_span::symbol::Symbol; use syntax::expand::allocator::AllocatorKind; -use std::sync::mpsc; use std::sync::Arc; pub trait BackendTypes { @@ -34,7 +34,7 @@ impl<'tcx, T> Backend<'tcx> for T where { } -pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send { +pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync { fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module; fn write_compressed_metadata<'tcx>( &self, @@ -52,8 +52,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se &self, tcx: TyCtxt<'_>, cgu_name: Symbol, - tx_to_llvm_workers: &mpsc::Sender>, - ); + ) -> (ModuleCodegen, u64); // If find_features is true this won't access `sess.crate_types` by assuming // that `is_pie_binary` is false. When we discover LLVM target features // `sess.crate_types` is uninitialized so we cannot access it. From 69bacd002b432292f5b0fdf76b4fad1432473f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 8 Jan 2020 06:05:26 +0100 Subject: [PATCH 0117/1253] Precompile CGUs while the main thread has the implicit job server token --- src/librustc_codegen_ssa/base.rs | 101 +++++++++++++-------- src/librustc_codegen_ssa/traits/backend.rs | 2 + 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index d2823381d887e..3e39fa7c8f36d 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -609,54 +609,75 @@ pub fn codegen_crate( let total_codegen_time = Lock::new(Duration::new(0, 0)); - let cgu_reuse: Vec<_> = tcx.sess.time("find cgu reuse", || { - codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect() - }); - - let mut cgus: FxHashMap = if cfg!(parallel_compiler) { - tcx.sess.time("compile first CGUs", || { - // Try to find one CGU to compile per thread. - let cgus: Vec<_> = cgu_reuse - .iter() - .enumerate() - .filter(|&(_, reuse)| reuse == &CguReuse::No) - .take(tcx.sess.threads()) - .collect(); - - // Compile the found CGUs in parallel. - par_iter(cgus) - .map(|(i, _)| { - let start_time = Instant::now(); - let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); - let mut time = total_codegen_time.lock(); - *time += start_time.elapsed(); - (i, module) - }) - .collect() - }) - } else { - FxHashMap::default() + // The non-parallel compiler can only translate codegen units to LLVM IR + // on a single thread, leading to a staircase effect where the N LLVM + // threads have to wait on the single codegen threads to generate work + // for them. The parallel compiler does not have this restriction, so + // we can pre-load the LLVM queue in parallel before handing off + // coordination to the OnGoingCodegen scheduler. + // + // This likely is a temporary measure. Once we don't have to support the + // non-parallel compiler anymore, we can compile CGUs end-to-end in + // parallel and get rid of the complicated scheduling logic. + let pre_compile_cgus = |cgu_reuse: &[CguReuse]| { + if cfg!(parallel_compiler) { + tcx.sess.time("compile_first_CGU_batch", || { + // Try to find one CGU to compile per thread. + let cgus: Vec<_> = cgu_reuse + .iter() + .enumerate() + .filter(|&(_, reuse)| reuse == &CguReuse::No) + .take(tcx.sess.threads()) + .collect(); + + // Compile the found CGUs in parallel. + par_iter(cgus) + .map(|(i, _)| { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); + let mut time = total_codegen_time.lock(); + *time += start_time.elapsed(); + (i, module) + }) + .collect() + }) + } else { + FxHashMap::default() + } }; - let mut total_codegen_time = total_codegen_time.into_inner(); + let mut cgu_reuse = Vec::new(); + let mut pre_compiled_cgus: Option> = None; - for (i, cgu) in codegen_units.into_iter().enumerate() { + for (i, cgu) in codegen_units.iter().enumerate() { ongoing_codegen.wait_for_signal_to_codegen_item(); ongoing_codegen.check_for_errors(tcx.sess); + // Do some setup work in the first iteration + if pre_compiled_cgus.is_none() { + // Calculate the CGU reuse + cgu_reuse = tcx.sess.time("find_cgu_reuse", || { + codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect() + }); + // Pre compile some CGUs + pre_compiled_cgus = Some(pre_compile_cgus(&cgu_reuse)); + } + let cgu_reuse = cgu_reuse[i]; tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse); match cgu_reuse { CguReuse::No => { - let (module, cost) = if let Some(cgu) = cgus.remove(&i) { - cgu - } else { - let start_time = Instant::now(); - let module = backend.compile_codegen_unit(tcx, cgu.name()); - total_codegen_time += start_time.elapsed(); - module - }; + let (module, cost) = + if let Some(cgu) = pre_compiled_cgus.as_mut().unwrap().remove(&i) { + cgu + } else { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, cgu.name()); + let mut time = total_codegen_time.lock(); + *time += start_time.elapsed(); + module + }; submit_codegened_module_to_llvm( &backend, &ongoing_codegen.coordinator_send, @@ -695,7 +716,11 @@ pub fn codegen_crate( // Since the main thread is sometimes blocked during codegen, we keep track // -Ztime-passes output manually. - print_time_passes_entry(tcx.sess.time_passes(), "codegen_to_LLVM_IR", total_codegen_time); + print_time_passes_entry( + tcx.sess.time_passes(), + "codegen_to_LLVM_IR", + total_codegen_time.into_inner(), + ); ::rustc_incremental::assert_module_sources::assert_module_sources(tcx); diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 2662b81a98409..bc3a75250bf70 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -48,6 +48,8 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se mods: &mut Self::Module, kind: AllocatorKind, ); + /// This generates the codegen unit and returns it along with + /// a `u64` giving an estimate of the unit's processing cost. fn compile_codegen_unit( &self, tcx: TyCtxt<'_>, From b650e91cf40500b60475c17ff289e1db761d7836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 9 Jan 2020 03:48:00 +0100 Subject: [PATCH 0118/1253] Label unmarked time --- src/librustc_codegen_ssa/back/link.rs | 49 +++++++++------ src/librustc_codegen_ssa/back/write.rs | 9 ++- src/librustc_data_structures/profiling.rs | 6 ++ src/librustc_driver/lib.rs | 3 + src/librustc_incremental/persist/fs.rs | 4 ++ src/librustc_incremental/persist/load.rs | 2 + src/librustc_interface/interface.rs | 14 +++-- src/librustc_interface/passes.rs | 74 +++++++++++++---------- src/librustc_interface/queries.rs | 15 ++++- 9 files changed, 117 insertions(+), 59 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 253225f308e88..7436b7b9a4f56 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -53,6 +53,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( crate_name: &str, target_cpu: &str, ) { + let _timer = sess.timer("link_binary"); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-codegen, as they will error. @@ -71,9 +72,11 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( ); } - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { - check_file_is_writeable(obj, sess); - } + sess.time("link_binary_check_files_are_writeable", || { + for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { + check_file_is_writeable(obj, sess); + } + }); let tmpdir = TempFileBuilder::new() .prefix("rustc") @@ -84,6 +87,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( let out_filename = out_filename(sess, crate_type, outputs, crate_name); match crate_type { config::CrateType::Rlib => { + let _timer = sess.timer("link_rlib"); link_rlib::( sess, codegen_results, @@ -118,29 +122,34 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( } // Remove the temporary object file and metadata if we aren't saving temps - if !sess.opts.cg.save_temps { - if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { - remove(sess, obj); + sess.time("link_binary_remove_temps", || { + if !sess.opts.cg.save_temps { + if sess.opts.output_types.should_codegen() + && !preserve_objects_for_their_debuginfo(sess) + { + for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { + remove(sess, obj); + } } - } - for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) { - remove(sess, obj); - } - if let Some(ref metadata_module) = codegen_results.metadata_module { - if let Some(ref obj) = metadata_module.object { + for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) + { remove(sess, obj); } - } - if let Some(ref allocator_module) = codegen_results.allocator_module { - if let Some(ref obj) = allocator_module.object { - remove(sess, obj); + if let Some(ref metadata_module) = codegen_results.metadata_module { + if let Some(ref obj) = metadata_module.object { + remove(sess, obj); + } } - if let Some(ref bc) = allocator_module.bytecode_compressed { - remove(sess, bc); + if let Some(ref allocator_module) = codegen_results.allocator_module { + if let Some(ref obj) = allocator_module.object { + remove(sess, obj); + } + if let Some(ref bc) = allocator_module.bytecode_compressed { + remove(sess, bc); + } } } - } + }); } // The third parameter is for env vars, used on windows to set up the diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 1ce0a29d55d9d..4d09e23ee7f7a 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -479,6 +479,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( return work_products; } + let _timer = sess.timer("incr_comp_copy_cgu_workproducts"); + for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) { let mut files = vec![]; @@ -1714,8 +1716,11 @@ pub struct OngoingCodegen { impl OngoingCodegen { pub fn join(self, sess: &Session) -> (CodegenResults, FxHashMap) { + let _timer = sess.timer("finish_ongoing_codegen"); + self.shared_emitter_main.check(sess, true); - let compiled_modules = match self.future.join() { + let future = self.future; + let compiled_modules = sess.time("join_worker_thread", || match future.join() { Ok(Ok(compiled_modules)) => compiled_modules, Ok(Err(())) => { sess.abort_if_errors(); @@ -1724,7 +1729,7 @@ impl OngoingCodegen { Err(_) => { bug!("panic during codegen/LLVM phase"); } - }; + }); sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic()); diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index a9d3a2668aab1..892509fc2d66f 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -347,6 +347,12 @@ impl<'a> TimingGuard<'a> { pub fn none() -> TimingGuard<'a> { TimingGuard(None) } + + #[inline(always)] + pub fn run(self, f: impl FnOnce() -> R) -> R { + let _timer = self; + f() + } } #[must_use] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a5277bcd120ed..a334124bf7e00 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -389,6 +389,7 @@ pub fn run_compiler( })?; } else { // Drop AST after creating GlobalCtxt to free memory + let _timer = sess.prof.generic_activity("drop_ast"); mem::drop(queries.expansion()?.take()); } @@ -408,11 +409,13 @@ pub fn run_compiler( sess.code_stats.print_type_sizes(); } + let _timer = sess.timer("query_linker"); let linker = queries.linker()?; Ok(Some(linker)) })?; if let Some(linker) = linker { + let _timer = sess.timer("link"); linker.link()? } diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index adf8f57f01d08..ba20006d73ccc 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -190,6 +190,8 @@ pub fn prepare_session_directory( return; } + let _timer = sess.timer("incr_comp_prepare_session_directory"); + debug!("prepare_session_directory"); // {incr-comp-dir}/{crate-name-and-disambiguator} @@ -306,6 +308,8 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { return; } + let _timer = sess.timer("incr_comp_finalize_session_directory"); + let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone(); if sess.has_errors_or_delayed_span_bugs() { diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 0732ddd3261a4..6c57f79e1a7fb 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -102,6 +102,8 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() }); } + let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph"); + // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`. // Fortunately, we just checked that this isn't the case. let path = dep_graph_path_from(&sess.incr_comp_session_dir()); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index c4449945dd19d..d00875f6fee88 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -177,11 +177,17 @@ pub fn run_compiler_in_existing_thread_pool( override_queries: config.override_queries, }; - let _sess_abort_error = OnDrop(|| { - compiler.sess.diagnostic().print_error_count(registry); - }); + let r = { + let _sess_abort_error = OnDrop(|| { + compiler.sess.diagnostic().print_error_count(registry); + }); - f(&compiler) + f(&compiler) + }; + + let prof = compiler.sess.prof.clone(); + prof.generic_activity("drop_compiler").run(move || drop(compiler)); + r } pub fn run_compiler(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a7e174f04553c..76ceeabdb728b 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -163,19 +163,22 @@ pub fn register_plugins<'a>( ) }); - let (krate, features) = rustc_expand::config::features( - krate, - &sess.parse_sess, - sess.edition(), - &sess.opts.debugging_opts.allow_features, - ); + let (krate, features) = sess.time("compute_features", || { + rustc_expand::config::features( + krate, + &sess.parse_sess, + sess.edition(), + &sess.opts.debugging_opts.allow_features, + ) + }); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); let crate_types = util::collect_crate_types(sess, &krate.attrs); sess.crate_types.set(crate_types); - let disambiguator = util::compute_crate_disambiguator(sess); + let disambiguator = + sess.time("compute_crate_disambiguator", || util::compute_crate_disambiguator(sess)); sess.crate_disambiguator.set(disambiguator); rustc_incremental::prepare_session_directory(sess, &crate_name, disambiguator); @@ -611,6 +614,8 @@ pub fn prepare_outputs( boxed_resolver: &Steal>>, crate_name: &str, ) -> Result { + let _timer = sess.timer("prepare_outputs"); + // FIXME: rustdoc passes &[] instead of &krate.attrs here let outputs = util::build_output_filenames( &compiler.input, @@ -721,33 +726,40 @@ pub fn create_global_ctxt<'tcx>( let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); - let codegen_backend = compiler.codegen_backend(); - let mut local_providers = ty::query::Providers::default(); - default_provide(&mut local_providers); - codegen_backend.provide(&mut local_providers); + let codegen_backend = sess.time("load_codegen_backend", || compiler.codegen_backend()); - let mut extern_providers = local_providers; - default_provide_extern(&mut extern_providers); - codegen_backend.provide_extern(&mut extern_providers); + let (local_providers, extern_providers) = sess.time("load_codegen_backend", || { + let mut local_providers = ty::query::Providers::default(); + default_provide(&mut local_providers); + codegen_backend.provide(&mut local_providers); - if let Some(callback) = compiler.override_queries { - callback(sess, &mut local_providers, &mut extern_providers); - } + let mut extern_providers = local_providers; + default_provide_extern(&mut extern_providers); + codegen_backend.provide_extern(&mut extern_providers); - let gcx = global_ctxt.init_locking(|| { - TyCtxt::create_global_ctxt( - sess, - lint_store, - local_providers, - extern_providers, - &all_arenas, - arena, - resolver_outputs, - hir_map, - query_result_on_disk_cache, - &crate_name, - &outputs, - ) + if let Some(callback) = compiler.override_queries { + callback(sess, &mut local_providers, &mut extern_providers); + } + + (local_providers, extern_providers) + }); + + let gcx = sess.time("setup_global_ctxt", || { + global_ctxt.init_locking(|| { + TyCtxt::create_global_ctxt( + sess, + lint_store, + local_providers, + extern_providers, + &all_arenas, + arena, + resolver_outputs, + hir_map, + query_result_on_disk_cache, + &crate_name, + &outputs, + ) + }) }); // Do some initialization of the DepGraph that can only be done with the tcx available. diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 6033569d765b4..3ec043624accb 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -158,6 +158,7 @@ impl<'tcx> Queries<'tcx> { Ok(match self.compiler.crate_name { Some(ref crate_name) => crate_name.clone(), None => { + let _timer = self.session().timer("crate_name"); let parse_result = self.parse()?; let krate = parse_result.peek(); rustc_codegen_utils::link::find_crate_name( @@ -176,6 +177,7 @@ impl<'tcx> Queries<'tcx> { self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let (krate, lint_store) = self.register_plugins()?.take(); + let _timer = self.session().timer("configure_and_expand"); passes::configure_and_expand( self.session().clone(), lint_store.clone(), @@ -256,6 +258,7 @@ impl<'tcx> Queries<'tcx> { let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?.peek(); let (ref hir_forest, ref resolver_outputs) = &*hir; + let _timer = self.session().timer("create_global_ctxt"); Ok(passes::create_global_ctxt( self.compiler, lint_store, @@ -312,14 +315,19 @@ pub struct Linker { impl Linker { pub fn link(self) -> Result<()> { - self.codegen_backend + let r = self + .codegen_backend .join_codegen_and_link( self.ongoing_codegen, &self.sess, &self.dep_graph, &self.prepare_outputs, ) - .map_err(|_| ErrorReported) + .map_err(|_| ErrorReported); + let prof = self.sess.prof.clone(); + let dep_graph = self.dep_graph; + prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph)); + r } } @@ -328,6 +336,7 @@ impl Compiler { where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, { + let mut _timer = None; let queries = Queries::new(&self); let ret = f(&queries); @@ -337,6 +346,8 @@ impl Compiler { } } + _timer = Some(self.session().timer("free_global_ctxt")); + ret } From 54f860158bcb37e4382ca546437d769619ee67ba Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 10 Jan 2020 06:52:22 +0900 Subject: [PATCH 0119/1253] Fix ICE #68058 --- src/librustc_ast_lowering/expr.rs | 7 ++++++- src/test/ui/macros/issue-68058.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/macros/issue-68058.rs diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index ee020c7e589ab..9a229e709a5e5 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -202,7 +202,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::Mac(_) => panic!("Shouldn't exist here"), }; - hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span, attrs: e.attrs.clone() } + hir::Expr { + hir_id: self.lower_node_id(e.id), + kind, + span: e.span, + attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::>().into(), + } } fn lower_unop(&mut self, u: UnOp) -> hir::UnOp { diff --git a/src/test/ui/macros/issue-68058.rs b/src/test/ui/macros/issue-68058.rs new file mode 100644 index 0000000000000..7679f8eaa7945 --- /dev/null +++ b/src/test/ui/macros/issue-68058.rs @@ -0,0 +1,15 @@ +// check-pass + +macro_rules! def_target { + ($target: expr) => { + #[target_feature(enable=$target)] + unsafe fn f() { + #[target_feature(enable=$target)] + () + } + }; +} + +def_target!("avx2"); + +fn main() {} From 915db7ae6430baef99f186ba40f08e105b7694fe Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 23:00:28 +0100 Subject: [PATCH 0120/1253] expect `fn` after `const unsafe` / `const extern` --- src/librustc_parse/parser/item.rs | 2 +- ...onst-extern-fns-dont-need-fn-specifier-2.rs | 7 +++++++ ...-extern-fns-dont-need-fn-specifier-2.stderr | 8 ++++++++ ...-const-extern-fns-dont-need-fn-specifier.rs | 8 ++++++++ ...st-extern-fns-dont-need-fn-specifier.stderr | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 918e826fc26bf..866bd1ccb55be 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -140,7 +140,7 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span)); } let ext = self.parse_extern()?; - self.bump(); // `fn` + self.expect_keyword(kw::Fn)?; let header = FnHeader { unsafety, diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs new file mode 100644 index 0000000000000..7ced24808bf6e --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs @@ -0,0 +1,7 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const unsafe WhereIsFerris Now() {} + //~^ ERROR expected one of `extern` or `fn` +} diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr new file mode 100644 index 0000000000000..5ec9e2a91f1dc --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `extern` or `fn`, found `WhereIsFerris` + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs:5:18 + | +LL | const unsafe WhereIsFerris Now() {} + | ^^^^^^^^^^^^^ expected one of `extern` or `fn` + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs new file mode 100644 index 0000000000000..1886bfccb4e3e --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs @@ -0,0 +1,8 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + //~^ ERROR expected `fn` + //~| ERROR `const extern fn` definitions are unstable +} diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr new file mode 100644 index 0000000000000..cf71ed4d59765 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr @@ -0,0 +1,18 @@ +error: expected `fn`, found `PUT_ANYTHING_YOU_WANT_HERE` + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier.rs:5:25 + | +LL | const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `fn` + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier.rs:5:5 + | +LL | const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 5918c187854e14a9b9c626753a70530a0e6222db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 9 Jan 2020 23:19:20 +0100 Subject: [PATCH 0121/1253] Tweak timers --- src/librustc_ast_lowering/lib.rs | 2 +- src/librustc_driver/lib.rs | 1 - src/librustc_interface/passes.rs | 42 +++++++++++++------------------ src/librustc_interface/queries.rs | 1 - 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 385153b62ce82..f0724b4bc0c77 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -268,7 +268,7 @@ pub fn lower_crate<'a, 'hir>( // incr. comp. yet. dep_graph.assert_ignored(); - let _prof_timer = sess.prof.generic_activity("hir_lowering"); + let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); LoweringContext { crate_root: sess.parse_sess.injected_crate_name.try_get().copied(), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a334124bf7e00..0cc74060a7df8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -409,7 +409,6 @@ pub fn run_compiler( sess.code_stats.print_type_sizes(); } - let _timer = sess.timer("query_linker"); let linker = queries.linker()?; Ok(Some(linker)) })?; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 76ceeabdb728b..277bdf914085d 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -163,22 +163,19 @@ pub fn register_plugins<'a>( ) }); - let (krate, features) = sess.time("compute_features", || { - rustc_expand::config::features( - krate, - &sess.parse_sess, - sess.edition(), - &sess.opts.debugging_opts.allow_features, - ) - }); + let (krate, features) = rustc_expand::config::features( + krate, + &sess.parse_sess, + sess.edition(), + &sess.opts.debugging_opts.allow_features, + ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); let crate_types = util::collect_crate_types(sess, &krate.attrs); sess.crate_types.set(crate_types); - let disambiguator = - sess.time("compute_crate_disambiguator", || util::compute_crate_disambiguator(sess)); + let disambiguator = util::compute_crate_disambiguator(sess); sess.crate_disambiguator.set(disambiguator); rustc_incremental::prepare_session_directory(sess, &crate_name, disambiguator); @@ -726,23 +723,18 @@ pub fn create_global_ctxt<'tcx>( let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); - let codegen_backend = sess.time("load_codegen_backend", || compiler.codegen_backend()); + let codegen_backend = compiler.codegen_backend(); + let mut local_providers = ty::query::Providers::default(); + default_provide(&mut local_providers); + codegen_backend.provide(&mut local_providers); - let (local_providers, extern_providers) = sess.time("load_codegen_backend", || { - let mut local_providers = ty::query::Providers::default(); - default_provide(&mut local_providers); - codegen_backend.provide(&mut local_providers); + let mut extern_providers = local_providers; + default_provide_extern(&mut extern_providers); + codegen_backend.provide_extern(&mut extern_providers); - let mut extern_providers = local_providers; - default_provide_extern(&mut extern_providers); - codegen_backend.provide_extern(&mut extern_providers); - - if let Some(callback) = compiler.override_queries { - callback(sess, &mut local_providers, &mut extern_providers); - } - - (local_providers, extern_providers) - }); + if let Some(callback) = compiler.override_queries { + callback(sess, &mut local_providers, &mut extern_providers); + } let gcx = sess.time("setup_global_ctxt", || { global_ctxt.init_locking(|| { diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 3ec043624accb..7de1c36ce4b2e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -158,7 +158,6 @@ impl<'tcx> Queries<'tcx> { Ok(match self.compiler.crate_name { Some(ref crate_name) => crate_name.clone(), None => { - let _timer = self.session().timer("crate_name"); let parse_result = self.parse()?; let krate = parse_result.peek(); rustc_codegen_utils::link::find_crate_name( From c751961d290e4da3caae3d5f1d01435accea6c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2020 13:46:37 -0800 Subject: [PATCH 0122/1253] Extend support of `_` in type parameters - Account for `impl Trait<_>`. - Provide a reasonable `Span` for empty `Generics` in `impl`s. - Account for `fn foo<_>(_: _) {}` to suggest `fn foo(_: T) {}`. - Fix #67995. --- src/librustc_parse/parser/generics.rs | 2 +- src/librustc_parse/parser/item.rs | 6 ++- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/collect.rs | 36 +++++++++++---- .../ui/typeck/typeck_type_placeholder_item.rs | 13 ++++++ .../typeck_type_placeholder_item.stderr | 44 ++++++++++++++++++- 6 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 1b816e2b90da9..075583711f5d3 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -156,7 +156,7 @@ impl<'a> Parser<'a> { self.expect_gt()?; (params, span_lo.to(self.prev_span)) } else { - (vec![], self.prev_span.between(self.token.span)) + (vec![], self.prev_span.shrink_to_hi()) }; Ok(ast::Generics { params, diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 918e826fc26bf..12dcf0391da1e 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -555,7 +555,11 @@ impl<'a> Parser<'a> { let mut generics = if self.choose_generics_over_qpath() { self.parse_generics()? } else { - Generics::default() + let mut generics = Generics::default(); + // impl A for B {} + // /\ this is where `generics.span` should point when there are no type params. + generics.span = self.prev_span.shrink_to_hi(); + generics }; // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4bacf9349379e..2b27138a4d854 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2803,7 +2803,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // allowed. `allow_ty_infer` gates this behavior. crate::collect::placeholder_type_error( tcx, - ident_span.unwrap_or(DUMMY_SP), + ident_span.map(|sp| sp.shrink_to_hi()).unwrap_or(DUMMY_SP), generic_params, visitor.0, ident_span.is_some(), diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 35c380612d2fb..43a2bcd564f4c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -124,7 +124,7 @@ struct CollectItemTypesVisitor<'tcx> { /// all already existing generic type parameters to avoid suggesting a name that is already in use. crate fn placeholder_type_error( tcx: TyCtxt<'tcx>, - ident_span: Span, + span: Span, generics: &[hir::GenericParam<'_>], placeholder_types: Vec, suggest: bool, @@ -150,7 +150,14 @@ crate fn placeholder_type_error( let mut sugg: Vec<_> = placeholder_types.iter().map(|sp| (*sp, type_name.to_string())).collect(); if generics.is_empty() { - sugg.push((ident_span.shrink_to_hi(), format!("<{}>", type_name))); + sugg.push((span, format!("<{}>", type_name))); + } else if let Some(arg) = generics.iter().find(|arg| match arg.name { + hir::ParamName::Plain(Ident { name: kw::Underscore, .. }) => true, + _ => false, + }) { + // Account for `_` already present in cases like `struct S<_>(_);` and suggest + // `struct S(T);` instead of `struct S<_, T>(T);`. + sugg.push((arg.span, format!("{}", type_name))); } else { sugg.push(( generics.iter().last().unwrap().span.shrink_to_hi(), @@ -172,8 +179,12 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir let (generics, suggest) = match &item.kind { hir::ItemKind::Union(_, generics) | hir::ItemKind::Enum(_, generics) - | hir::ItemKind::Struct(_, generics) => (&generics.params[..], true), - hir::ItemKind::TyAlias(_, generics) => (&generics.params[..], false), + | hir::ItemKind::TraitAlias(generics, _) + | hir::ItemKind::Trait(_, _, generics, ..) + | hir::ItemKind::Impl(_, _, _, generics, ..) + | hir::ItemKind::Struct(_, generics) => (generics, true), + hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }) + | hir::ItemKind::TyAlias(_, generics) => (generics, false), // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type. _ => return, }; @@ -181,7 +192,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_item(item); - placeholder_type_error(tcx, item.ident.span, generics, visitor.0, suggest); + placeholder_type_error(tcx, generics.span, &generics.params[..], visitor.0, suggest); } impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { @@ -1789,10 +1800,19 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { /// Whether `ty` is a type with `_` placeholders that can be infered. Used in diagnostics only to /// use inference to provide suggestions for the appropriate type if possible. fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { + use hir::TyKind::*; match &ty.kind { - hir::TyKind::Infer => true, - hir::TyKind::Slice(ty) | hir::TyKind::Array(ty, _) => is_suggestable_infer_ty(ty), - hir::TyKind::Tup(tys) => tys.iter().any(|ty| is_suggestable_infer_ty(ty)), + Infer => true, + Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty), + Tup(tys) => tys.iter().any(is_suggestable_infer_ty), + Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), + Def(_, generic_args) => generic_args + .iter() + .filter_map(|arg| match arg { + hir::GenericArg::Type(ty) => Some(ty), + _ => None, + }) + .any(is_suggestable_infer_ty), _ => false, } } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 5b0ca2f347ea8..a53042d6e9538 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -131,3 +131,16 @@ trait T { fn assoc_fn_test3() -> _; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } + +struct BadStruct<_>(_); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR the type placeholder `_` is not allowed within types on item signatures +trait BadTrait<_> {} +//~^ ERROR expected identifier, found reserved identifier `_` +impl BadTrait<_> for BadStruct<_> {} +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +fn impl_trait() -> impl BadTrait<_> { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + unimplemented!() +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 9fe7af4c822c1..e788bf37790cf 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,3 +1,15 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:135:18 + | +LL | struct BadStruct<_>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:138:16 + | +LL | trait BadTrait<_> {} + | ^ expected identifier, found reserved identifier + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:4:14 | @@ -255,6 +267,36 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | | not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:135:21 + | +LL | struct BadStruct<_>(_); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct(T); + | ^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:140:15 + | +LL | impl BadTrait<_> for BadStruct<_> {} + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL | impl BadTrait for BadStruct {} + | ^^^ ^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:143:34 + | +LL | fn impl_trait() -> impl BadTrait<_> { + | ^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:121:31 | @@ -405,7 +447,7 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ -error: aborting due to 40 previous errors +error: aborting due to 45 previous errors Some errors have detailed explanations: E0121, E0282. For more information about an error, try `rustc --explain E0121`. From 1c9f999157e40b770c60518174355273875bf88d Mon Sep 17 00:00:00 2001 From: Matthew Healy Date: Thu, 9 Jan 2020 22:19:33 +0100 Subject: [PATCH 0123/1253] Add llvm-skip-rebuild to opts --- src/bootstrap/flags.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index ffc24367db6e9..813e89eef38ce 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -150,6 +150,14 @@ To learn more about a subcommand, run `./x.py -h`", "VALUE", ); opts.optopt("", "error-format", "rustc error format", "FORMAT"); + opts.optopt( + "", + "llvm-skip-rebuild", + "whether rebuilding llvm should be skipped \ + a VALUE of TRUE indicates that llvm will not be rebuilt \ + VALUE overrides the skip-rebuild option in config.toml.", + "VALUE", + ); // fn usage() let usage = From 663f8b5cfd7b9fdb1a2de53f0cafe3ee26ca5ee1 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 8 Jan 2020 16:47:57 +0900 Subject: [PATCH 0124/1253] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index e8642c7a2900b..43ac9416d9359 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit e8642c7a2900bed28003a98d4db8b62290ac802f +Subproject commit 43ac9416d935942d6c7d2b2e0c876c551652c4ec From 6e04cf062f605fbd70d728dcd364ad3eac0f822c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2020 14:53:17 -0800 Subject: [PATCH 0125/1253] review comments: more tests --- .../ui/typeck/typeck_type_placeholder_item.rs | 32 +++ .../typeck_type_placeholder_item.stderr | 248 ++++++++++++------ 2 files changed, 195 insertions(+), 85 deletions(-) diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index a53042d6e9538..adecbd7e5b40e 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -1,3 +1,4 @@ +#![feature(type_alias_impl_trait)] // Needed for single test `type Y = impl Trait<_>` // This test checks that it is not possible to enable global type // inference by using the `_` type placeholder. @@ -42,6 +43,16 @@ impl Test9 { //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } +fn test11(x: &usize) -> &_ { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + &x +} + +unsafe fn test12(x: *const usize) -> *const *const _ { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + &x +} + impl Clone for Test9 { fn clone(&self) -> _ { Test9 } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures @@ -144,3 +155,24 @@ fn impl_trait() -> impl BadTrait<_> { //~^ ERROR the type placeholder `_` is not allowed within types on item signatures unimplemented!() } + +struct BadStruct1<_, _>(_); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR expected identifier, found reserved identifier `_` +//~| ERROR the name `_` is already used +//~| ERROR the type placeholder `_` is not allowed within types on item signatures +struct BadStruct2<_, T>(_, T); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR the type placeholder `_` is not allowed within types on item signatures + +type X = Box<_>; +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +struct Struct; +trait Trait {} +impl Trait for Struct {} +type Y = impl Trait<_>; +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +fn foo() -> Y { + Struct +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index e788bf37790cf..05326a3e07a93 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,17 +1,43 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:135:18 + --> $DIR/typeck_type_placeholder_item.rs:146:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:138:16 + --> $DIR/typeck_type_placeholder_item.rs:149:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:159:19 + | +LL | struct BadStruct1<_, _>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:159:22 + | +LL | struct BadStruct1<_, _>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:164:19 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ expected identifier, found reserved identifier + +error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters + --> $DIR/typeck_type_placeholder_item.rs:159:22 + | +LL | struct BadStruct1<_, _>(_); + | - ^ already used + | | + | first use of `_` + error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:4:14 + --> $DIR/typeck_type_placeholder_item.rs:5:14 | LL | fn test() -> _ { 5 } | ^ @@ -20,7 +46,7 @@ LL | fn test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:7:16 + --> $DIR/typeck_type_placeholder_item.rs:8:16 | LL | fn test2() -> (_, _) { (5, 5) } | -^--^- @@ -30,7 +56,7 @@ LL | fn test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:10:15 + --> $DIR/typeck_type_placeholder_item.rs:11:15 | LL | static TEST3: _ = "test"; | ^ @@ -39,7 +65,7 @@ LL | static TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:13:15 + --> $DIR/typeck_type_placeholder_item.rs:14:15 | LL | static TEST4: _ = 145; | ^ @@ -48,13 +74,13 @@ LL | static TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:16:15 + --> $DIR/typeck_type_placeholder_item.rs:17:15 | LL | static TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:19:13 + --> $DIR/typeck_type_placeholder_item.rs:20:13 | LL | fn test6(_: _) { } | ^ not allowed in type signatures @@ -65,7 +91,7 @@ LL | fn test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:22:18 + --> $DIR/typeck_type_placeholder_item.rs:23:18 | LL | fn test6_b(_: _, _: T) { } | ^ not allowed in type signatures @@ -76,7 +102,7 @@ LL | fn test6_b(_: K, _: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:25:30 + --> $DIR/typeck_type_placeholder_item.rs:26:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } | ^ not allowed in type signatures @@ -87,7 +113,7 @@ LL | fn test6_c(_: C, _: (T, K, L, A, B)) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:28:13 + --> $DIR/typeck_type_placeholder_item.rs:29:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -98,13 +124,13 @@ LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:31:22 + --> $DIR/typeck_type_placeholder_item.rs:32:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:31:22 + --> $DIR/typeck_type_placeholder_item.rs:32:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -115,7 +141,25 @@ LL | fn test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:54:8 + --> $DIR/typeck_type_placeholder_item.rs:46:26 + | +LL | fn test11(x: &usize) -> &_ { + | -^ + | || + | |not allowed in type signatures + | help: replace with the correct return type: `&&usize` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:51:52 + | +LL | unsafe fn test12(x: *const usize) -> *const *const _ { + | --------------^ + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `*const *const usize` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:65:8 | LL | a: _, | ^ not allowed in type signatures @@ -134,7 +178,7 @@ LL | b: (T, T), | error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:60:21 + --> $DIR/typeck_type_placeholder_item.rs:71:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -143,7 +187,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:63:23 + --> $DIR/typeck_type_placeholder_item.rs:74:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -153,7 +197,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:66:22 + --> $DIR/typeck_type_placeholder_item.rs:77:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -162,7 +206,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:69:22 + --> $DIR/typeck_type_placeholder_item.rs:80:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -171,13 +215,13 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:72:22 + --> $DIR/typeck_type_placeholder_item.rs:83:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:75:20 + --> $DIR/typeck_type_placeholder_item.rs:86:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -188,7 +232,7 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:78:20 + --> $DIR/typeck_type_placeholder_item.rs:89:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -199,13 +243,13 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:81:29 + --> $DIR/typeck_type_placeholder_item.rs:92:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:81:29 + --> $DIR/typeck_type_placeholder_item.rs:92:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -216,7 +260,7 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:104:12 + --> $DIR/typeck_type_placeholder_item.rs:115:12 | LL | a: _, | ^ not allowed in type signatures @@ -235,13 +279,13 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:109:27 + --> $DIR/typeck_type_placeholder_item.rs:120:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^^^^^^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:109:28 + --> $DIR/typeck_type_placeholder_item.rs:120:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -249,7 +293,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:113:30 + --> $DIR/typeck_type_placeholder_item.rs:124:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -259,7 +303,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:116:33 + --> $DIR/typeck_type_placeholder_item.rs:127:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -268,7 +312,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:135:21 + --> $DIR/typeck_type_placeholder_item.rs:146:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -279,7 +323,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:140:15 + --> $DIR/typeck_type_placeholder_item.rs:151:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -292,13 +336,52 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:143:34 + --> $DIR/typeck_type_placeholder_item.rs:154:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:121:31 + --> $DIR/typeck_type_placeholder_item.rs:159:25 + | +LL | struct BadStruct1<_, _>(_); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct1(T); + | ^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:164:25 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct2(K, T); + | ^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:168:14 + | +LL | type X = Box<_>; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:42:27 + | +LL | fn test10(&self, _x : _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test10(&self, _x : T) { } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:132:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -309,7 +392,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:123:31 + --> $DIR/typeck_type_placeholder_item.rs:134:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -322,7 +405,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:125:31 + --> $DIR/typeck_type_placeholder_item.rs:136:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -333,7 +416,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:26 + --> $DIR/typeck_type_placeholder_item.rs:138:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -344,7 +427,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:129:26 + --> $DIR/typeck_type_placeholder_item.rs:140:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -357,7 +440,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:131:28 + --> $DIR/typeck_type_placeholder_item.rs:142:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -368,47 +451,64 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:38:24 + --> $DIR/typeck_type_placeholder_item.rs:60:37 | -LL | fn test9(&self) -> _ { () } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `()` +LL | fn clone_from(&mut self, other: _) { *self = Test9; } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn clone_from(&mut self, other: T) { *self = Test9; } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:41:27 + --> $DIR/typeck_type_placeholder_item.rs:102:34 | -LL | fn test10(&self, _x : _) { } - | ^ not allowed in type signatures +LL | fn fn_test10(&self, _x : _) { } + | ^ not allowed in type signatures | help: use type parameters instead | -LL | fn test10(&self, _x : T) { } - | ^^^ ^ +LL | fn fn_test10(&self, _x : T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:46:24 + --> $DIR/typeck_type_placeholder_item.rs:110:41 | -LL | fn clone(&self) -> _ { Test9 } +LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:174:21 + | +LL | type Y = impl Trait<_>; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:39:24 + | +LL | fn test9(&self) -> _ { () } | ^ | | | not allowed in type signatures - | help: replace with the correct return type: `Test9` + | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:49:37 - | -LL | fn clone_from(&mut self, other: _) { *self = Test9; } - | ^ not allowed in type signatures - | -help: use type parameters instead + --> $DIR/typeck_type_placeholder_item.rs:57:24 | -LL | fn clone_from(&mut self, other: T) { *self = Test9; } - | ^^^ ^ +LL | fn clone(&self) -> _ { Test9 } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:88:31 + --> $DIR/typeck_type_placeholder_item.rs:99:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -417,18 +517,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:91:34 - | -LL | fn fn_test10(&self, _x : _) { } - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn fn_test10(&self, _x : T) { } - | ^^^ ^ - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:96:28 + --> $DIR/typeck_type_placeholder_item.rs:107:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -436,18 +525,7 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `main::FnTest9` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:41 - | -LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } - | ^^^ ^ - -error: aborting due to 45 previous errors +error: aborting due to 55 previous errors -Some errors have detailed explanations: E0121, E0282. +Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. From 870ca3140896292851c16485403238c560f561b2 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Thu, 9 Jan 2020 23:45:06 +0000 Subject: [PATCH 0126/1253] rustbuild: Cleanup book generation The Cargo book can be generated the same way as the other books. --- src/bootstrap/doc.rs | 86 ++++++++------------------------------------ 1 file changed, 14 insertions(+), 72 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 8cd7fc2c17257..5f03723b068ad 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -49,7 +49,7 @@ macro_rules! book { builder.ensure(RustbookSrc { target: self.target, name: INTERNER.intern_str($book_name), - src: doc_src(builder), + src: INTERNER.intern_path(builder.src.join($path)), }) } } @@ -60,6 +60,7 @@ macro_rules! book { // NOTE: When adding a book here, make sure to ALSO build the book by // adding a build step in `src/bootstrap/builder.rs`! book!( + CargoBook, "src/tools/cargo/src/doc", "cargo"; EditionGuide, "src/doc/edition-guide", "edition-guide"; EmbeddedBook, "src/doc/embedded-book", "embedded-book"; Nomicon, "src/doc/nomicon", "nomicon"; @@ -69,10 +70,6 @@ book!( RustdocBook, "src/doc/rustdoc", "rustdoc"; ); -fn doc_src(builder: &Builder<'_>) -> Interned { - INTERNER.intern_path(builder.src.join("src/doc")) -} - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct UnstableBook { target: Interned, @@ -96,48 +93,11 @@ impl Step for UnstableBook { builder.ensure(RustbookSrc { target: self.target, name: INTERNER.intern_str("unstable-book"), - src: builder.md_doc_out(self.target), + src: INTERNER.intern_path(builder.md_doc_out(self.target).join("unstable-book")), }) } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct CargoBook { - target: Interned, - name: Interned, -} - -impl Step for CargoBook { - type Output = (); - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let builder = run.builder; - run.path("src/tools/cargo/src/doc/book").default_condition(builder.config.docs) - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(CargoBook { target: run.target, name: INTERNER.intern_str("cargo") }); - } - - fn run(self, builder: &Builder<'_>) { - let target = self.target; - let name = self.name; - let src = builder.src.join("src/tools/cargo/src/doc"); - - let out = builder.doc_out(target); - t!(fs::create_dir_all(&out)); - - let out = out.join(name); - - builder.info(&format!("Cargo Book ({}) - {}", target, name)); - - let _ = fs::remove_dir_all(&out); - - builder.run(builder.tool_cmd(Tool::Rustbook).arg("build").arg(&src).arg("-d").arg(out)); - } -} - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] struct RustbookSrc { target: Interned, @@ -164,7 +124,6 @@ impl Step for RustbookSrc { t!(fs::create_dir_all(&out)); let out = out.join(name); - let src = src.join(name); let index = out.join("index.html"); let rustbook = builder.tool_exe(Tool::Rustbook); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); @@ -182,7 +141,6 @@ impl Step for RustbookSrc { pub struct TheBook { compiler: Compiler, target: Interned, - name: &'static str, } impl Step for TheBook { @@ -198,7 +156,6 @@ impl Step for TheBook { run.builder.ensure(TheBook { compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, - name: "book", }); } @@ -206,45 +163,30 @@ impl Step for TheBook { /// /// We need to build: /// - /// * Book (first edition) - /// * Book (second edition) + /// * Book + /// * Older edition redirects /// * Version info and CSS /// * Index page /// * Redirect pages fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; let target = self.target; - let name = self.name; // build book builder.ensure(RustbookSrc { target, - name: INTERNER.intern_string(name.to_string()), - src: doc_src(builder), + name: INTERNER.intern_str("book"), + src: INTERNER.intern_path(builder.src.join("src/doc/book")), }); // building older edition redirects - - let source_name = format!("{}/first-edition", name); - builder.ensure(RustbookSrc { - target, - name: INTERNER.intern_string(source_name), - src: doc_src(builder), - }); - - let source_name = format!("{}/second-edition", name); - builder.ensure(RustbookSrc { - target, - name: INTERNER.intern_string(source_name), - src: doc_src(builder), - }); - - let source_name = format!("{}/2018-edition", name); - builder.ensure(RustbookSrc { - target, - name: INTERNER.intern_string(source_name), - src: doc_src(builder), - }); + for edition in &["first-edition", "second-edition", "2018-edition"] { + builder.ensure(RustbookSrc { + target, + name: INTERNER.intern_string(format!("book/{}", edition)), + src: INTERNER.intern_path(builder.src.join("src/doc/book").join(edition)), + }); + } // build the version info page and CSS builder.ensure(Standalone { compiler, target }); From 63e2e44eb94c375527ddc6438479a0dd10ed4310 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 15:45:48 -0800 Subject: [PATCH 0127/1253] Add `const_trait_impl` feature gate --- src/librustc_feature/active.rs | 4 ++++ src/librustc_span/symbol.rs | 1 + src/libsyntax/feature_gate/check.rs | 1 + 3 files changed, 6 insertions(+) diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 8cb1684491bb8..77ee9f40b6c71 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -544,6 +544,9 @@ declare_features! ( /// For example, you can write `x @ Some(y)`. (active, bindings_after_at, "1.41.0", Some(65490), None), + /// Allows `impl const Trait for T` syntax. + (active, const_trait_impl, "1.42.0", Some(67792), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -559,4 +562,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::or_patterns, sym::let_chains, sym::raw_dylib, + sym::const_trait_impl, ]; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 40abc8b2179b8..5ba45e0a67399 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -219,6 +219,7 @@ symbols! { const_raw_ptr_deref, const_raw_ptr_to_usize_cast, const_transmute, + const_trait_impl, contents, context, convert, diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 26545bfa61b60..f5090bf15536d 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -909,6 +909,7 @@ pub fn check_crate( gate_all!(or_patterns, "or-patterns syntax is experimental"); gate_all!(const_extern_fn, "`const extern fn` definitions are unstable"); gate_all!(raw_ref_op, "raw address of syntax is experimental"); + gate_all!(const_trait_impl, "const trait impls are experimental"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). From 6fc41585043927c3b9b404ddc357e67ab443eb70 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 15:46:30 -0800 Subject: [PATCH 0128/1253] Add `const_trait_bound_opt_out` feature gate --- src/librustc_feature/active.rs | 4 ++++ src/librustc_span/symbol.rs | 1 + src/libsyntax/feature_gate/check.rs | 1 + 3 files changed, 6 insertions(+) diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 77ee9f40b6c71..6a15cc5cb0fce 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -547,6 +547,9 @@ declare_features! ( /// Allows `impl const Trait for T` syntax. (active, const_trait_impl, "1.42.0", Some(67792), None), + /// Allows `T: ?const Trait` syntax in bounds. + (active, const_trait_bound_opt_out, "1.42.0", Some(67794), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -563,4 +566,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::let_chains, sym::raw_dylib, sym::const_trait_impl, + sym::const_trait_bound_opt_out, ]; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 5ba45e0a67399..d9f4b72560ceb 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -219,6 +219,7 @@ symbols! { const_raw_ptr_deref, const_raw_ptr_to_usize_cast, const_transmute, + const_trait_bound_opt_out, const_trait_impl, contents, context, diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index f5090bf15536d..52eb20d320f7b 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -909,6 +909,7 @@ pub fn check_crate( gate_all!(or_patterns, "or-patterns syntax is experimental"); gate_all!(const_extern_fn, "`const extern fn` definitions are unstable"); gate_all!(raw_ref_op, "raw address of syntax is experimental"); + gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental"); gate_all!(const_trait_impl, "const trait impls are experimental"); // All uses of `gate_all!` below this point were added in #65742, From fd4a6a12136c5b5d6bce4081e95890df1fd1febd Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 15:47:27 -0800 Subject: [PATCH 0129/1253] Add a `constness` field to `ast::TraitRef` This is used for both the `?const` syntax in bounds as well as the `impl const Trait` syntax. I also considered handling these separately by adding a variant of `TraitBoundModifier` and a field to `ItemKind::Impl`, but this approach was less intrusive. --- src/librustc_expand/build.rs | 2 +- src/libsyntax/ast.rs | 20 +++++++++++++++++--- src/libsyntax/mut_visit.rs | 3 ++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 11f94ab2e6279..bd3d6b589d00a 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -110,7 +110,7 @@ impl<'a> ExtCtxt<'a> { } pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { - ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } + ast::TraitRef { path, constness: None, ref_id: ast::DUMMY_NODE_ID } } pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 47070261385a2..1d3bb7d87686c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1033,7 +1033,7 @@ impl Expr { pub fn to_bound(&self) -> Option { match &self.kind { ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(Vec::new(), path.clone(), self.span), + PolyTraitRef::new(Vec::new(), path.clone(), None, self.span), TraitBoundModifier::None, )), _ => None, @@ -2376,6 +2376,15 @@ pub enum AttrKind { pub struct TraitRef { pub path: Path, pub ref_id: NodeId, + + /// The `const` modifier, if any, that appears before this trait. + /// + /// | | `constness` | + /// |----------------|-----------------------------| + /// | `Trait` | `None` | + /// | `const Trait` | `Some(Constness::Const)` | + /// | `?const Trait` | `Some(Constness::NotConst)` | + pub constness: Option, } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2390,10 +2399,15 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(generic_params: Vec, path: Path, span: Span) -> Self { + pub fn new( + generic_params: Vec, + path: Path, + constness: Option, + span: Span, + ) -> Self { PolyTraitRef { bound_generic_params: generic_params, - trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, + trait_ref: TraitRef { path, constness, ref_id: DUMMY_NODE_ID }, span, } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 1413f1566d043..264ba25cedecc 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -838,7 +838,8 @@ pub fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut } } -pub fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { +pub fn noop_visit_trait_ref(tr: &mut TraitRef, vis: &mut T) { + let TraitRef { path, ref_id, constness: _ } = tr; vis.visit_path(path); vis.visit_id(ref_id); } From 1c3fe9de4e9b7c41cc0ba86696b4e58f9e0e36e4 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 15:49:45 -0800 Subject: [PATCH 0130/1253] Parse `impl const Trait for Ty` syntax --- src/librustc_parse/parser/item.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 918e826fc26bf..86ab8bf57a3e3 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -542,10 +542,11 @@ impl<'a> Parser<'a> { /// impl<'a, T> TYPE { /* impl items */ } /// impl<'a, T> TRAIT for TYPE { /* impl items */ } /// impl<'a, T> !TRAIT for TYPE { /* impl items */ } + /// impl<'a, T> const TRAIT for TYPE { /* impl items */ } /// /// We actually parse slightly more relaxed grammar for better error reporting and recovery. - /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}` - /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}` + /// `impl` GENERICS `const`? `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}` + /// `impl` GENERICS `const`? `!`? TYPE (`where` PREDICATES)? `{` BODY `}` fn parse_item_impl( &mut self, unsafety: Unsafety, @@ -558,6 +559,13 @@ impl<'a> Parser<'a> { Generics::default() }; + let constness = if self.eat_keyword(kw::Const) { + self.sess.gated_spans.gate(sym::const_trait_impl, self.prev_span); + Some(Constness::Const) + } else { + None + }; + // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) { self.bump(); // `!` @@ -618,7 +626,7 @@ impl<'a> Parser<'a> { err_path(ty_first.span) } }; - let trait_ref = TraitRef { path, ref_id: ty_first.id }; + let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; ItemKind::Impl( unsafety, From 0cf52a7dd8fbe68e85471fd9254d8e2e025a03d8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 15:50:18 -0800 Subject: [PATCH 0131/1253] Parse `?const Trait` bound syntax The grammar also handles `?const ?Trait` even though this is semantically redundant. --- src/librustc_parse/parser/ty.rs | 91 ++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index f96c82a1ab37d..ea14aa278ac29 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -6,7 +6,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_error_codes::*; use rustc_errors::{pluralize, struct_span_err, Applicability, PResult}; use rustc_span::source_map::Span; -use rustc_span::symbol::kw; +use rustc_span::symbol::{kw, sym}; use syntax::ast::{ self, BareFnTy, FunctionRetTy, GenericParam, Ident, Lifetime, MutTy, Ty, TyKind, }; @@ -17,6 +17,24 @@ use syntax::ast::{Mac, Mutability}; use syntax::ptr::P; use syntax::token::{self, Token}; +/// Any `?` or `?const` modifiers that appear at the start of a bound. +struct BoundModifiers { + /// `?Trait`. + maybe: Option, + + /// `?const Trait`. + maybe_const: Option, +} + +impl BoundModifiers { + fn trait_bound_modifier(&self) -> TraitBoundModifier { + match self.maybe { + Some(_) => TraitBoundModifier::Maybe, + None => TraitBoundModifier::None, + } + } +} + /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, /// `IDENT<::AssocTy>`. /// @@ -195,7 +213,9 @@ impl<'a> Parser<'a> { lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span)); + assert_ne!(self.token, token::Question); + + let poly_trait_ref = PolyTraitRef::new(generic_params, path, None, lo.to(self.prev_span)); let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; if parse_plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded @@ -421,12 +441,15 @@ impl<'a> Parser<'a> { let has_parens = self.eat(&token::OpenDelim(token::Paren)); let inner_lo = self.token.span; let is_negative = self.eat(&token::Not); - let question = self.eat(&token::Question).then_some(self.prev_span); + + let modifiers = self.parse_ty_bound_modifiers(); let bound = if self.token.is_lifetime() { - self.parse_generic_lt_bound(lo, inner_lo, has_parens, question)? + self.error_lt_bound_with_modifiers(modifiers); + self.parse_generic_lt_bound(lo, inner_lo, has_parens)? } else { - self.parse_generic_ty_bound(lo, has_parens, question)? + self.parse_generic_ty_bound(lo, has_parens, modifiers)? }; + Ok(if is_negative { Err(anchor_lo.to(self.prev_span)) } else { Ok(bound) }) } @@ -439,9 +462,7 @@ impl<'a> Parser<'a> { lo: Span, inner_lo: Span, has_parens: bool, - question: Option, ) -> PResult<'a, GenericBound> { - self.error_opt_out_lifetime(question); let bound = GenericBound::Outlives(self.expect_lifetime()); if has_parens { // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead, @@ -451,8 +472,17 @@ impl<'a> Parser<'a> { Ok(bound) } - fn error_opt_out_lifetime(&self, question: Option) { - if let Some(span) = question { + /// Emits an error if any trait bound modifiers were present. + fn error_lt_bound_with_modifiers(&self, modifiers: BoundModifiers) { + if let Some(span) = modifiers.maybe_const { + self.struct_span_err( + span, + "`?const` may only modify trait bounds, not lifetime bounds", + ) + .emit(); + } + + if let Some(span) = modifiers.maybe { self.struct_span_err(span, "`?` may only modify trait bounds, not lifetime bounds") .emit(); } @@ -478,25 +508,58 @@ impl<'a> Parser<'a> { Ok(()) } + /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `?const Trait`. + /// + /// If no modifiers are present, this does not consume any tokens. + /// + /// ``` + /// TY_BOUND_MODIFIERS = "?" ["const" ["?"]] + /// ``` + fn parse_ty_bound_modifiers(&mut self) -> BoundModifiers { + if !self.eat(&token::Question) { + return BoundModifiers { maybe: None, maybe_const: None }; + } + + // `? ...` + let first_question = self.prev_span; + if !self.eat_keyword(kw::Const) { + return BoundModifiers { maybe: Some(first_question), maybe_const: None }; + } + + // `?const ...` + let maybe_const = first_question.to(self.prev_span); + self.sess.gated_spans.gate(sym::const_trait_bound_opt_out, maybe_const); + if !self.eat(&token::Question) { + return BoundModifiers { maybe: None, maybe_const: Some(maybe_const) }; + } + + // `?const ? ...` + let second_question = self.prev_span; + BoundModifiers { maybe: Some(second_question), maybe_const: Some(maybe_const) } + } + /// Parses a type bound according to: /// ``` /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN) - /// TY_BOUND_NOPAREN = [?] [for] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`) + /// TY_BOUND_NOPAREN = [TY_BOUND_MODIFIERS] [for] SIMPLE_PATH /// ``` + /// + /// For example, this grammar accepts `?const ?for<'a: 'b> m::Trait<'a>`. fn parse_generic_ty_bound( &mut self, lo: Span, has_parens: bool, - question: Option, + modifiers: BoundModifiers, ) -> PResult<'a, GenericBound> { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; let path = self.parse_path(PathStyle::Type)?; if has_parens { self.expect(&token::CloseDelim(token::Paren))?; } - let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span)); - let modifier = question.map_or(TraitBoundModifier::None, |_| TraitBoundModifier::Maybe); - Ok(GenericBound::Trait(poly_trait, modifier)) + + let constness = modifiers.maybe_const.map(|_| ast::Constness::NotConst); + let poly_trait = PolyTraitRef::new(lifetime_defs, path, constness, lo.to(self.prev_span)); + Ok(GenericBound::Trait(poly_trait, modifiers.trait_bound_modifier())) } /// Optionally parses `for<$generic_params>`. From b390fc4cf1e7293716cd8d80ec532df232022324 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 16:35:07 -0800 Subject: [PATCH 0132/1253] Error when new syntax is lowered This means the new syntax will always fail to compile, even when the feature gate is enabled. These checks will be removed in a later PR once the implementation is done. --- src/librustc_ast_lowering/item.rs | 6 ++++++ src/librustc_ast_lowering/lib.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index a5892a22d9dfa..7c95b2a86c685 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -71,6 +71,12 @@ impl<'a, 'lowering, 'hir> Visitor<'a> for ItemLowerer<'a, 'lowering, 'hir> { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind { + if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + this.lctx + .diagnostic() + .span_err(item.span, "const trait impls are not yet implemented"); + } + this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item)); } else { visit::walk_item(this, item); diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 385153b62ce82..73d1e49725826 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -2579,6 +2579,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &PolyTraitRef, mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::PolyTraitRef<'hir> { + if p.trait_ref.constness.is_some() { + self.diagnostic().span_err(p.span, "`?const` on trait bounds is not yet implemented"); + } + let bound_generic_params = self.lower_generic_params( &p.bound_generic_params, &NodeMap::default(), From 31edbe9acacceb24f0e31a73e0c45f852977c663 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 3 Jan 2020 16:32:01 -0800 Subject: [PATCH 0133/1253] Reject `const` in inherent impls --- src/librustc_parse/parser/item.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 86ab8bf57a3e3..b209e5a78266a 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -5,7 +5,7 @@ use crate::maybe_whole; use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey}; -use rustc_span::source_map::{self, respan, Span}; +use rustc_span::source_map::{self, respan, Span, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::BytePos; use syntax::ast::{self, AttrKind, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; @@ -560,8 +560,9 @@ impl<'a> Parser<'a> { }; let constness = if self.eat_keyword(kw::Const) { - self.sess.gated_spans.gate(sym::const_trait_impl, self.prev_span); - Some(Constness::Const) + let span = self.prev_span; + self.sess.gated_spans.gate(sym::const_trait_impl, span); + Some(respan(span, Constness::Const)) } else { None }; @@ -626,6 +627,7 @@ impl<'a> Parser<'a> { err_path(ty_first.span) } }; + let constness = constness.map(|c| c.node); let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; ItemKind::Impl( @@ -639,6 +641,13 @@ impl<'a> Parser<'a> { ) } None => { + // Reject `impl const Type {}` here + if let Some(Spanned { node: Constness::Const, span }) = constness { + self.struct_span_err(span, "`const` cannot modify an inherent impl") + .help("only a trait impl can be `const`") + .emit(); + } + // impl Type ItemKind::Impl( unsafety, From d843e002bb836be3164bef80d6218228aec974a8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 4 Jan 2020 16:29:45 -0800 Subject: [PATCH 0134/1253] Check for `?const` in invalid contexts during AST validation --- src/librustc_passes/ast_validation.rs | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 5000cd5f52f65..1e5e39217b7aa 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -24,6 +24,23 @@ use syntax::walk_list; use rustc_error_codes::*; +#[derive(Clone, Copy)] +enum BoundContext { + ImplTrait, + TraitBounds, + TraitObject, +} + +impl BoundContext { + fn description(&self) -> &'static str { + match self { + Self::ImplTrait => "`impl Trait`", + Self::TraitBounds => "supertraits", + Self::TraitObject => "trait objects", + } + } +} + struct AstValidator<'a> { session: &'a Session, has_proc_macro_decls: bool, @@ -33,6 +50,11 @@ struct AstValidator<'a> { /// e.g., `impl Iterator`. outer_impl_trait: Option, + /// Tracks the context in which a bound can appear. + /// + /// This is used to forbid `?const Trait` bounds in certain contexts. + bound_context_stack: Vec>, + /// Used to ban `impl Trait` in path projections like `::Item` /// or `Foo::Bar` is_impl_trait_banned: bool, @@ -58,9 +80,21 @@ impl<'a> AstValidator<'a> { } fn with_impl_trait(&mut self, outer: Option, f: impl FnOnce(&mut Self)) { + self.bound_context_stack.push(outer.map(|_| BoundContext::ImplTrait)); let old = mem::replace(&mut self.outer_impl_trait, outer); f(self); self.outer_impl_trait = old; + self.bound_context_stack.pop(); + } + + fn with_bound_context(&mut self, ctx: Option, f: impl FnOnce(&mut Self)) { + self.bound_context_stack.push(ctx); + f(self); + self.bound_context_stack.pop(); + } + + fn innermost_bound_context(&mut self) -> Option { + self.bound_context_stack.iter().rev().find(|x| x.is_some()).copied().flatten() } fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { @@ -84,6 +118,11 @@ impl<'a> AstValidator<'a> { TyKind::ImplTrait(..) => { self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } + TyKind::TraitObject(..) => { + self.with_bound_context(Some(BoundContext::TraitObject), |this| { + visit::walk_ty(this, t) + }); + } TyKind::Path(ref qself, ref path) => { // We allow these: // - `Option` @@ -192,6 +231,8 @@ impl<'a> AstValidator<'a> { } } + // FIXME(ecstaticmorse): Instead, use the `bound_context_stack` to check this in + // `visit_param_bound`. fn no_questions_in_bounds(&self, bounds: &GenericBounds, where_: &str, is_trait: bool) { for bound in bounds { if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound { @@ -697,6 +738,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } self.no_questions_in_bounds(bounds, "supertraits", true); + + // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound + // context for the supertraits. + self.visit_generics(generics); + self.with_bound_context(Some(BoundContext::TraitBounds), |this| { + walk_list!(this, visit_param_bound, bounds); + }); + walk_list!(self, visit_trait_item, trait_items); + return; } ItemKind::Mod(_) => { // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). @@ -841,6 +891,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_generic_param(self, param); } + fn visit_param_bound(&mut self, bound: &'a GenericBound) { + if let GenericBound::Trait(poly, maybe_bound) = bound { + match poly.trait_ref.constness { + Some(Constness::NotConst) => { + if *maybe_bound == TraitBoundModifier::Maybe { + self.err_handler() + .span_err(bound.span(), "`?const` and `?` are mutually exclusive"); + } + + if let Some(ctx) = self.innermost_bound_context() { + let msg = format!("`?const` is not permitted in {}", ctx.description()); + self.err_handler().span_err(bound.span(), &msg); + } + } + + Some(Constness::Const) => bug!("Parser should reject bare `const` on bounds"), + None => {} + } + } + + visit::walk_param_bound(self, bound) + } + fn visit_pat(&mut self, pat: &'a Pat) { match pat.kind { PatKind::Lit(ref expr) => { @@ -949,6 +1022,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe session, has_proc_macro_decls: false, outer_impl_trait: None, + bound_context_stack: Vec::new(), is_impl_trait_banned: false, is_assoc_ty_bound_banned: false, lint_buffer: lints, From 343e1570a9b460e3dda85fe87fd6819df99d7943 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 2 Jan 2020 16:31:30 -0800 Subject: [PATCH 0135/1253] Add tests for RFC 2632 --- src/test/ui/parser/bounds-type.rs | 5 ++ src/test/ui/parser/bounds-type.stderr | 8 ++- .../feature-gate.gated.stderr | 8 +++ .../const-trait-bound-opt-out/feature-gate.rs | 15 ++++++ .../feature-gate.stock.stderr | 18 +++++++ .../in-impl-trait.rs | 25 ++++++++++ .../in-impl-trait.stderr | 50 +++++++++++++++++++ .../in-trait-bounds.rs | 9 ++++ .../in-trait-bounds.stderr | 14 ++++++ .../in-trait-object.rs | 18 +++++++ .../in-trait-object.stderr | 26 ++++++++++ .../opt-out-twice.rs | 8 +++ .../opt-out-twice.stderr | 14 ++++++ .../const-trait-bound-opt-out/syntax.rs | 10 ++++ .../without-question-mark.rs | 7 +++ .../without-question-mark.stderr | 8 +++ .../feature-gate.gated.stderr | 8 +++ .../rfc-2632-const-trait-impl/feature-gate.rs | 13 +++++ .../feature-gate.stock.stderr | 18 +++++++ .../impl-opt-out-trait.rs | 11 ++++ .../impl-opt-out-trait.stderr | 8 +++ .../inherent-impl.rs | 14 ++++++ .../inherent-impl.stderr | 10 ++++ .../ui/rfc-2632-const-trait-impl/syntax.rs | 9 ++++ 24 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/syntax.rs diff --git a/src/test/ui/parser/bounds-type.rs b/src/test/ui/parser/bounds-type.rs index 9122cb49ebc1a..7a187a0518af9 100644 --- a/src/test/ui/parser/bounds-type.rs +++ b/src/test/ui/parser/bounds-type.rs @@ -8,6 +8,11 @@ struct S< T: ?for<'a> Trait, // OK T: Tr +, // OK T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds + + T: ?const Tr, // OK + T: ?const ?Tr, // OK + T: ?const Tr + 'a, // OK + T: ?const 'a, //~ ERROR `?const` may only modify trait bounds, not lifetime bounds >; fn main() {} diff --git a/src/test/ui/parser/bounds-type.stderr b/src/test/ui/parser/bounds-type.stderr index 0b714e40a1012..9a1f2ed398240 100644 --- a/src/test/ui/parser/bounds-type.stderr +++ b/src/test/ui/parser/bounds-type.stderr @@ -4,5 +4,11 @@ error: `?` may only modify trait bounds, not lifetime bounds LL | T: ?'a, | ^ -error: aborting due to previous error +error: `?const` may only modify trait bounds, not lifetime bounds + --> $DIR/bounds-type.rs:15:8 + | +LL | T: ?const 'a, + | ^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr new file mode 100644 index 0000000000000..0bf337ad08dbf --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr @@ -0,0 +1,8 @@ +error: `?const` on trait bounds is not yet implemented + --> $DIR/feature-gate.rs:11:29 + | +LL | const fn get_assoc_const() -> i32 { ::CONST } + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs new file mode 100644 index 0000000000000..cf1ed30da0fcc --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs @@ -0,0 +1,15 @@ +// revisions: stock gated +// gate-test-const_trait_bound_opt_out + +#![cfg_attr(gated, feature(const_trait_bound_opt_out))] +#![allow(incomplete_features)] + +trait T { + const CONST: i32; +} + +const fn get_assoc_const() -> i32 { ::CONST } +//[stock]~^ ERROR `?const` on trait bounds is experimental +//[stock,gated]~^^ ERROR `?const` on trait bounds is not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr new file mode 100644 index 0000000000000..64388004b5b72 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr @@ -0,0 +1,18 @@ +error[E0658]: `?const` on trait bounds is experimental + --> $DIR/feature-gate.rs:11:29 + | +LL | const fn get_assoc_const() -> i32 { ::CONST } + | ^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67794 + = help: add `#![feature(const_trait_bound_opt_out)]` to the crate attributes to enable + +error: `?const` on trait bounds is not yet implemented + --> $DIR/feature-gate.rs:11:29 + | +LL | const fn get_assoc_const() -> i32 { ::CONST } + | ^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs new file mode 100644 index 0000000000000..e4e6bedd93746 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs @@ -0,0 +1,25 @@ +#![feature(const_trait_bound_opt_out)] +#![feature(associated_type_bounds)] +#![allow(incomplete_features)] + +trait T {} +struct S; +impl T for S {} + +fn rpit() -> impl ?const T { S } +//~^ ERROR `?const` is not permitted in `impl Trait` +//~| ERROR `?const` on trait bounds is not yet implemented + +fn apit(_: impl ?const T) {} +//~^ ERROR `?const` is not permitted in `impl Trait` +//~| ERROR `?const` on trait bounds is not yet implemented + +fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } +//~^ ERROR `?const` is not permitted in `impl Trait` +//~| ERROR `?const` on trait bounds is not yet implemented + +fn apit_assoc_bound(_: impl IntoIterator) {} +//~^ ERROR `?const` is not permitted in `impl Trait` +//~| ERROR `?const` on trait bounds is not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr new file mode 100644 index 0000000000000..f4abd4b714e8a --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr @@ -0,0 +1,50 @@ +error: `?const` is not permitted in `impl Trait` + --> $DIR/in-impl-trait.rs:9:19 + | +LL | fn rpit() -> impl ?const T { S } + | ^^^^^^^^ + +error: `?const` is not permitted in `impl Trait` + --> $DIR/in-impl-trait.rs:13:17 + | +LL | fn apit(_: impl ?const T) {} + | ^^^^^^^^ + +error: `?const` is not permitted in `impl Trait` + --> $DIR/in-impl-trait.rs:17:50 + | +LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } + | ^^^^^^^^ + +error: `?const` is not permitted in `impl Trait` + --> $DIR/in-impl-trait.rs:21:48 + | +LL | fn apit_assoc_bound(_: impl IntoIterator) {} + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-impl-trait.rs:9:19 + | +LL | fn rpit() -> impl ?const T { S } + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-impl-trait.rs:13:17 + | +LL | fn apit(_: impl ?const T) {} + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-impl-trait.rs:17:50 + | +LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-impl-trait.rs:21:48 + | +LL | fn apit_assoc_bound(_: impl IntoIterator) {} + | ^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs new file mode 100644 index 0000000000000..4523b46bc51f6 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs @@ -0,0 +1,9 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +trait Super {} +trait T: ?const Super {} +//~^ ERROR `?const` is not permitted in supertraits +//~| ERROR `?const` on trait bounds is not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr new file mode 100644 index 0000000000000..8003361be7d2e --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr @@ -0,0 +1,14 @@ +error: `?const` is not permitted in supertraits + --> $DIR/in-trait-bounds.rs:5:10 + | +LL | trait T: ?const Super {} + | ^^^^^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-trait-bounds.rs:5:10 + | +LL | trait T: ?const Super {} + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs new file mode 100644 index 0000000000000..490fae6d91a15 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs @@ -0,0 +1,18 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(bare_trait_objects)] +#![allow(incomplete_features)] + +struct S; +trait T {} +impl T for S {} + +// An inherent impl for the trait object `?const T`. +impl ?const T {} +//~^ ERROR `?const` is not permitted in trait objects +//~| ERROR `?const` on trait bounds is not yet implemented + +fn trait_object() -> &'static dyn ?const T { &S } +//~^ ERROR `?const` is not permitted in trait objects +//~| ERROR `?const` on trait bounds is not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr new file mode 100644 index 0000000000000..19d52e51b3797 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr @@ -0,0 +1,26 @@ +error: `?const` is not permitted in trait objects + --> $DIR/in-trait-object.rs:10:6 + | +LL | impl ?const T {} + | ^^^^^^^^ + +error: `?const` is not permitted in trait objects + --> $DIR/in-trait-object.rs:14:35 + | +LL | fn trait_object() -> &'static dyn ?const T { &S } + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-trait-object.rs:10:6 + | +LL | impl ?const T {} + | ^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-trait-object.rs:14:35 + | +LL | fn trait_object() -> &'static dyn ?const T { &S } + | ^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs new file mode 100644 index 0000000000000..01e941a8fba45 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z parse-only + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S; +//~^ ERROR expected identifier, found keyword `const` +//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.stderr new file mode 100644 index 0000000000000..f7924b3f24db3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.stderr @@ -0,0 +1,14 @@ +error: expected identifier, found keyword `const` + --> $DIR/opt-out-twice.rs:6:21 + | +LL | struct S; + | ^^^^^ expected identifier, found keyword + +error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` + --> $DIR/opt-out-twice.rs:6:27 + | +LL | struct S; + | ^^ expected one of 7 possible tokens + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs new file mode 100644 index 0000000000000..a0d9610bbb5e2 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z parse-only +// check-pass + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S< + T: ?const ?for<'a> Tr<'a> + 'static + ?const std::ops::Add, + T: ?const ?for<'a: 'b> m::Trait<'a>, +>; diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs new file mode 100644 index 0000000000000..b904a2eec0dd0 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z parse-only + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S; +//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, lifetime, or path diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.stderr new file mode 100644 index 0000000000000..0dbca952c037e --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, lifetime, or path, found keyword `const` + --> $DIR/without-question-mark.rs:6:13 + | +LL | struct S; + | ^^^^^ expected one of 9 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr new file mode 100644 index 0000000000000..b196f9ef57380 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr @@ -0,0 +1,8 @@ +error: const trait impls are not yet implemented + --> $DIR/feature-gate.rs:9:1 + | +LL | impl const T for S {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs new file mode 100644 index 0000000000000..49b6c0926c50c --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs @@ -0,0 +1,13 @@ +// revisions: stock gated +// gate-test-const_trait_impl + +#![cfg_attr(gated, feature(const_trait_impl))] +#![allow(incomplete_features)] + +struct S; +trait T {} +impl const T for S {} +//[stock]~^ ERROR const trait impls are experimental +//[stock,gated]~^^ ERROR const trait impls are not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr new file mode 100644 index 0000000000000..093946f859ac3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr @@ -0,0 +1,18 @@ +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:9:6 + | +LL | impl const T for S {} + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67792 + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error: const trait impls are not yet implemented + --> $DIR/feature-gate.rs:9:1 + | +LL | impl const T for S {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs new file mode 100644 index 0000000000000..98d3a220d8674 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs @@ -0,0 +1,11 @@ +#![feature(const_trait_bound_opt_out)] +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +struct S; +trait T {} + +impl ?const T for S {} +//~^ ERROR expected a trait, found type + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.stderr new file mode 100644 index 0000000000000..8f923efb093f3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.stderr @@ -0,0 +1,8 @@ +error: expected a trait, found type + --> $DIR/impl-opt-out-trait.rs:8:6 + | +LL | impl ?const T for S {} + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs new file mode 100644 index 0000000000000..9cffe75addd63 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z parse-only + +#![feature(const_trait_impl)] +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] +#![allow(bare_trait_objects)] + +struct S; +trait T {} + +impl const T {} +//~^ ERROR `const` cannot modify an inherent impl + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr new file mode 100644 index 0000000000000..1d24557655951 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr @@ -0,0 +1,10 @@ +error: `const` cannot modify an inherent impl + --> $DIR/inherent-impl.rs:11:6 + | +LL | impl const T {} + | ^^^^^ + | + = help: only a trait impl can be `const` + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/syntax.rs b/src/test/ui/rfc-2632-const-trait-impl/syntax.rs new file mode 100644 index 0000000000000..354d48d630f7b --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/syntax.rs @@ -0,0 +1,9 @@ +// compile-flags: -Z parse-only +// check-pass + +#![feature(const_trait_bound_opt_out)] +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +// For now, this parses since an error does not occur until AST lowering. +impl ?const T {} From b6b11f0f282081b2baa3961cc9f78313eafcc8b4 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 4 Jan 2020 18:34:10 -0800 Subject: [PATCH 0136/1253] Call all visit methods on trait definitions --- src/librustc_passes/ast_validation.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 1e5e39217b7aa..cb035e586c109 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -741,11 +741,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound // context for the supertraits. + self.visit_vis(&item.vis); + self.visit_ident(item.ident); self.visit_generics(generics); self.with_bound_context(Some(BoundContext::TraitBounds), |this| { walk_list!(this, visit_param_bound, bounds); }); walk_list!(self, visit_trait_item, trait_items); + walk_list!(self, visit_attribute, &item.attrs); return; } ItemKind::Mod(_) => { From 9950a1f3bdfec11db6bbe2019b819b4410e26905 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 4 Jan 2020 21:47:11 -0800 Subject: [PATCH 0137/1253] Add test for `?const` and `?` on the same bound --- .../const-trait-bound-opt-out/with-maybe-sized.rs | 8 ++++++++ .../with-maybe-sized.stderr | 14 ++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs new file mode 100644 index 0000000000000..425784f4e4326 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs @@ -0,0 +1,8 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S(std::marker::PhantomData); +//~^ ERROR `?const` and `?` are mutually exclusive +//~| ERROR `?const` on trait bounds is not yet implemented + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr new file mode 100644 index 0000000000000..44f6d464ae6a8 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr @@ -0,0 +1,14 @@ +error: `?const` and `?` are mutually exclusive + --> $DIR/with-maybe-sized.rs:4:13 + | +LL | struct S(std::marker::PhantomData); + | ^^^^^^^^^^^^^ + +error: `?const` on trait bounds is not yet implemented + --> $DIR/with-maybe-sized.rs:4:13 + | +LL | struct S(std::marker::PhantomData); + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 14730ed44536b5d50aa8b73fbb1023fffe6eba3d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 5 Jan 2020 16:33:26 -0800 Subject: [PATCH 0138/1253] Make `bound_context` more like neighboring functions --- src/librustc_passes/ast_validation.rs | 39 +++++++++++++-------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index cb035e586c109..724d717304c20 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -24,6 +24,7 @@ use syntax::walk_list; use rustc_error_codes::*; +/// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`). #[derive(Clone, Copy)] enum BoundContext { ImplTrait, @@ -50,10 +51,11 @@ struct AstValidator<'a> { /// e.g., `impl Iterator`. outer_impl_trait: Option, - /// Tracks the context in which a bound can appear. + /// Keeps track of the `BoundContext` as we recurse. /// - /// This is used to forbid `?const Trait` bounds in certain contexts. - bound_context_stack: Vec>, + /// This is used to forbid `?const Trait` bounds in, e.g., + /// `impl Iterator`. + bound_context: Option, /// Used to ban `impl Trait` in path projections like `::Item` /// or `Foo::Bar` @@ -80,21 +82,19 @@ impl<'a> AstValidator<'a> { } fn with_impl_trait(&mut self, outer: Option, f: impl FnOnce(&mut Self)) { - self.bound_context_stack.push(outer.map(|_| BoundContext::ImplTrait)); let old = mem::replace(&mut self.outer_impl_trait, outer); - f(self); + if outer.is_some() { + self.with_bound_context(BoundContext::ImplTrait, |this| f(this)); + } else { + f(self) + } self.outer_impl_trait = old; - self.bound_context_stack.pop(); } - fn with_bound_context(&mut self, ctx: Option, f: impl FnOnce(&mut Self)) { - self.bound_context_stack.push(ctx); + fn with_bound_context(&mut self, ctx: BoundContext, f: impl FnOnce(&mut Self)) { + let old = self.bound_context.replace(ctx); f(self); - self.bound_context_stack.pop(); - } - - fn innermost_bound_context(&mut self) -> Option { - self.bound_context_stack.iter().rev().find(|x| x.is_some()).copied().flatten() + self.bound_context = old; } fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { @@ -119,9 +119,7 @@ impl<'a> AstValidator<'a> { self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } TyKind::TraitObject(..) => { - self.with_bound_context(Some(BoundContext::TraitObject), |this| { - visit::walk_ty(this, t) - }); + self.with_bound_context(BoundContext::TraitObject, |this| visit::walk_ty(this, t)); } TyKind::Path(ref qself, ref path) => { // We allow these: @@ -231,8 +229,7 @@ impl<'a> AstValidator<'a> { } } - // FIXME(ecstaticmorse): Instead, use the `bound_context_stack` to check this in - // `visit_param_bound`. + // FIXME(ecstaticmorse): Instead, use `bound_context` to check this in `visit_param_bound`. fn no_questions_in_bounds(&self, bounds: &GenericBounds, where_: &str, is_trait: bool) { for bound in bounds { if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound { @@ -744,7 +741,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.visit_vis(&item.vis); self.visit_ident(item.ident); self.visit_generics(generics); - self.with_bound_context(Some(BoundContext::TraitBounds), |this| { + self.with_bound_context(BoundContext::TraitBounds, |this| { walk_list!(this, visit_param_bound, bounds); }); walk_list!(self, visit_trait_item, trait_items); @@ -903,7 +900,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .span_err(bound.span(), "`?const` and `?` are mutually exclusive"); } - if let Some(ctx) = self.innermost_bound_context() { + if let Some(ctx) = self.bound_context { let msg = format!("`?const` is not permitted in {}", ctx.description()); self.err_handler().span_err(bound.span(), &msg); } @@ -1025,7 +1022,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe session, has_proc_macro_decls: false, outer_impl_trait: None, - bound_context_stack: Vec::new(), + bound_context: None, is_impl_trait_banned: false, is_assoc_ty_bound_banned: false, lint_buffer: lints, From fd1c00348b7b3521f7340a2d034b32406229fe1b Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 5 Jan 2020 16:34:26 -0800 Subject: [PATCH 0139/1253] Add test for `?const` in nested impl/dyn trait --- .../const-trait-bound-opt-out/in-trait-object.rs | 4 ++++ .../in-trait-object.stderr | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs index 490fae6d91a15..6cfca71548674 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs @@ -15,4 +15,8 @@ fn trait_object() -> &'static dyn ?const T { &S } //~^ ERROR `?const` is not permitted in trait objects //~| ERROR `?const` on trait bounds is not yet implemented +fn trait_object_in_apit(_: impl IntoIterator>) {} +//~^ ERROR `?const` is not permitted in trait objects +//~| ERROR `?const` on trait bounds is not yet implemented + fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr index 19d52e51b3797..c059f16902250 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr @@ -10,6 +10,12 @@ error: `?const` is not permitted in trait objects LL | fn trait_object() -> &'static dyn ?const T { &S } | ^^^^^^^^ +error: `?const` is not permitted in trait objects + --> $DIR/in-trait-object.rs:18:61 + | +LL | fn trait_object_in_apit(_: impl IntoIterator>) {} + | ^^^^^^^^ + error: `?const` on trait bounds is not yet implemented --> $DIR/in-trait-object.rs:10:6 | @@ -22,5 +28,11 @@ error: `?const` on trait bounds is not yet implemented LL | fn trait_object() -> &'static dyn ?const T { &S } | ^^^^^^^^ -error: aborting due to 4 previous errors +error: `?const` on trait bounds is not yet implemented + --> $DIR/in-trait-object.rs:18:61 + | +LL | fn trait_object_in_apit(_: impl IntoIterator>) {} + | ^^^^^^^^ + +error: aborting due to 6 previous errors From fcd850fc5db2501d14b2e0cbfac8aa890d700e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2020 22:10:18 -0800 Subject: [PATCH 0140/1253] Do not ICE on unicode next point Use `shrink_to_hi` instead of `next_point` Fix #68000. --- src/librustc_parse/parser/item.rs | 2 +- ...e-68000-unicode-ident-after-missing-comma.rs | 6 ++++++ ...000-unicode-ident-after-missing-comma.stderr | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 918e826fc26bf..4cd3540ea6807 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1489,7 +1489,7 @@ impl<'a> Parser<'a> { } } _ => { - let sp = self.sess.source_map().next_point(self.prev_span); + let sp = self.prev_span.shrink_to_hi(); let mut err = self.struct_span_err( sp, &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs new file mode 100644 index 0000000000000..3c49a5a975209 --- /dev/null +++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs @@ -0,0 +1,6 @@ +pub struct Foo { + pub bar: Vecö + //~^ ERROR expected `,`, or `}`, found `ö` +} //~ ERROR expected `:`, found `}` + +fn main() {} diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr new file mode 100644 index 0000000000000..ef365a616437b --- /dev/null +++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr @@ -0,0 +1,17 @@ +error: expected `,`, or `}`, found `ö` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22 + | +LL | pub bar: Vecö + | ^ help: try adding a comma: `,` + +error: expected `:`, found `}` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1 + | +LL | pub bar: Vecö + | - expected `:` +LL | +LL | } + | ^ unexpected token + +error: aborting due to 2 previous errors + From d5598aa7a07b324789576585f4f035c93993fea4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 11 Dec 2019 10:04:34 +0100 Subject: [PATCH 0141/1253] Introduce `#![feature(half_open_range_patterns)]`. This feature adds `X..`, `..X`, and `..=X` patterns. --- src/librustc/ty/util.rs | 95 ++- src/librustc_ast_lowering/pat.rs | 13 +- src/librustc_feature/active.rs | 3 + src/librustc_hir/hir.rs | 2 +- src/librustc_hir/intravisit.rs | 4 +- src/librustc_hir/print.rs | 10 +- src/librustc_lint/builtin.rs | 18 +- src/librustc_mir/hair/pattern/mod.rs | 162 +++--- src/librustc_parse/parser/diagnostics.rs | 6 - src/librustc_parse/parser/expr.rs | 4 +- src/librustc_parse/parser/pat.rs | 319 +++++----- src/librustc_passes/ast_validation.rs | 8 +- src/librustc_span/symbol.rs | 1 + src/librustc_typeck/check/pat.rs | 108 ++-- src/libsyntax/ast.rs | 2 +- src/libsyntax/feature_gate/check.rs | 1 + src/libsyntax/mut_visit.rs | 4 +- src/libsyntax/print/pprust.rs | 10 +- src/libsyntax/visit.rs | 4 +- ...xclusive_range_pattern_syntax_collision.rs | 4 +- ...sive_range_pattern_syntax_collision.stderr | 10 +- ...clusive_range_pattern_syntax_collision2.rs | 4 +- ...ive_range_pattern_syntax_collision2.stderr | 12 +- ...clusive_range_pattern_syntax_collision3.rs | 4 +- ...ive_range_pattern_syntax_collision3.stderr | 14 +- .../feature-gate-half-open-range-patterns.rs | 21 + ...ature-gate-half-open-range-patterns.stderr | 74 +++ .../half-open-range-pats-bad-types.rs | 8 + .../half-open-range-pats-bad-types.stderr | 21 + .../half-open-range-pats-exhaustive-fail.rs | 168 ++++++ ...alf-open-range-pats-exhaustive-fail.stderr | 547 ++++++++++++++++++ .../half-open-range-pats-exhaustive-pass.rs | 49 ++ .../half-open-range-pats-hair-lower-empty.rs | 54 ++ ...lf-open-range-pats-hair-lower-empty.stderr | 159 +++++ .../half-open-range-pats-inclusive-no-end.rs | 15 + ...lf-open-range-pats-inclusive-no-end.stderr | 35 ++ ...lf-open-range-pats-ref-ambiguous-interp.rs | 24 + ...pen-range-pats-ref-ambiguous-interp.stderr | 43 ++ .../half-open-range-pats-semantics.rs | 160 +++++ .../half-open-range-pats-syntactic-pass.rs | 32 + .../half-open-range-patterns/pat-tuple-4.rs | 13 + .../half-open-range-patterns/pat-tuple-5.rs | 10 + .../pat-tuple-5.stderr | 14 + src/test/ui/issues/issue-41255.rs | 17 + src/test/ui/issues/issue-41255.stderr | 94 ++- src/test/ui/parser/attr-stmt-expr-attr-bad.rs | 8 +- .../ui/parser/attr-stmt-expr-attr-bad.stderr | 133 +++-- .../issue-63115-range-pat-interpolated.rs | 6 + .../issue-66357-unexpected-unreachable.rs | 4 +- .../issue-66357-unexpected-unreachable.stderr | 6 +- src/test/ui/parser/pat-tuple-4.rs | 11 - src/test/ui/parser/pat-tuple-4.stderr | 25 - src/test/ui/parser/pat-tuple-5.rs | 10 - src/test/ui/parser/pat-tuple-5.stderr | 30 - src/test/ui/parser/recover-range-pats.rs | 70 ++- src/test/ui/parser/recover-range-pats.stderr | 349 ++++------- 56 files changed, 2183 insertions(+), 849 deletions(-) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision.rs (59%) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision.stderr (57%) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision2.rs (58%) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision2.stderr (62%) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision3.rs (69%) rename src/test/ui/{exclusive-range => half-open-range-patterns}/exclusive_range_pattern_syntax_collision3.stderr (75%) create mode 100644 src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs create mode 100644 src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-semantics.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs create mode 100644 src/test/ui/half-open-range-patterns/pat-tuple-4.rs create mode 100644 src/test/ui/half-open-range-patterns/pat-tuple-5.rs create mode 100644 src/test/ui/half-open-range-patterns/pat-tuple-5.stderr delete mode 100644 src/test/ui/parser/pat-tuple-4.rs delete mode 100644 src/test/ui/parser/pat-tuple-4.stderr delete mode 100644 src/test/ui/parser/pat-tuple-5.rs delete mode 100644 src/test/ui/parser/pat-tuple-5.stderr diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index ddff8258c6d8f..8d22ac9dbbe97 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -3,18 +3,18 @@ use crate::hir::map::DefPathData; use crate::ich::NodeIdHashingMode; use crate::mir::interpret::{sign_extend, truncate}; -use crate::ty::layout::{Integer, IntegerExt}; +use crate::ty::layout::{Integer, IntegerExt, Size}; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::TyKind::*; use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable}; use crate::util::common::ErrorReported; +use rustc_apfloat::Float as _; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; - -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_span::Span; use std::{cmp, fmt}; @@ -43,26 +43,38 @@ impl<'tcx> fmt::Display for Discr<'tcx> { } } +fn signed_min(size: Size) -> i128 { + sign_extend(1_u128 << (size.bits() - 1), size) as i128 +} + +fn signed_max(size: Size) -> i128 { + i128::max_value() >> (128 - size.bits()) +} + +fn unsigned_max(size: Size) -> u128 { + u128::max_value() >> (128 - size.bits()) +} + +fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) { + let (int, signed) = match ty.kind { + Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true), + Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false), + _ => bug!("non integer discriminant"), + }; + (int.size(), signed) +} + impl<'tcx> Discr<'tcx> { /// Adds `1` to the value and wraps around if the maximum for the type is reached. pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self { self.checked_add(tcx, 1).0 } pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) { - let (int, signed) = match self.ty.kind { - Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true), - Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false), - _ => bug!("non integer discriminant"), - }; - - let size = int.size(); - let bit_size = int.size().bits(); - let shift = 128 - bit_size; - if signed { - let sext = |u| sign_extend(u, size) as i128; - let min = sext(1_u128 << (bit_size - 1)); - let max = i128::max_value() >> shift; - let val = sext(self.val); + let (size, signed) = int_size_and_signed(tcx, self.ty); + let (val, oflo) = if signed { + let min = signed_min(size); + let max = signed_max(size); + let val = sign_extend(self.val, size) as i128; assert!(n < (i128::max_value() as u128)); let n = n as i128; let oflo = val > max - n; @@ -70,14 +82,15 @@ impl<'tcx> Discr<'tcx> { // zero the upper bits let val = val as u128; let val = truncate(val, size); - (Self { val: val as u128, ty: self.ty }, oflo) + (val, oflo) } else { - let max = u128::max_value() >> shift; + let max = unsigned_max(size); let val = self.val; let oflo = val > max - n; let val = if oflo { n - (max - val) - 1 } else { val + n }; - (Self { val: val, ty: self.ty }, oflo) - } + (val, oflo) + }; + (Self { val, ty: self.ty }, oflo) } } @@ -621,6 +634,44 @@ impl<'tcx> TyCtxt<'tcx> { } impl<'tcx> ty::TyS<'tcx> { + /// Returns the maximum value for the given numeric type (including `char`s) + /// or returns `None` if the type is not numeric. + pub fn numeric_max_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> { + let val = match self.kind { + ty::Int(_) | ty::Uint(_) => { + let (size, signed) = int_size_and_signed(tcx, self); + let val = if signed { signed_max(size) as u128 } else { unsigned_max(size) }; + Some(val) + } + ty::Char => Some(std::char::MAX as u128), + ty::Float(fty) => Some(match fty { + ast::FloatTy::F32 => ::rustc_apfloat::ieee::Single::INFINITY.to_bits(), + ast::FloatTy::F64 => ::rustc_apfloat::ieee::Double::INFINITY.to_bits(), + }), + _ => None, + }; + val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) + } + + /// Returns the minimum value for the given numeric type (including `char`s) + /// or returns `None` if the type is not numeric. + pub fn numeric_min_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> { + let val = match self.kind { + ty::Int(_) | ty::Uint(_) => { + let (size, signed) = int_size_and_signed(tcx, self); + let val = if signed { truncate(signed_min(size) as u128, size) } else { 0 }; + Some(val) + } + ty::Char => Some(0), + ty::Float(fty) => Some(match fty { + ast::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(), + ast::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(), + }), + _ => None, + }; + val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self))) + } + /// Checks whether values of this type `T` are *moved* or *copied* /// when referenced -- this amounts to a check for whether `T: /// Copy`, but note that we **don't** consider lifetimes when diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index cd69646d0c53a..6cf640a0e98a2 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -65,9 +65,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl), PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range( - self.lower_expr(e1), - self.lower_expr(e2), - self.lower_range_end(end), + e1.as_deref().map(|e| self.lower_expr(e)), + e2.as_deref().map(|e| self.lower_expr(e)), + self.lower_range_end(end, e2.is_some()), ), PatKind::Slice(ref pats) => self.lower_pat_slice(pats), PatKind::Rest => { @@ -253,10 +253,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::PatKind::Wild } - fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd { + fn lower_range_end(&mut self, e: &RangeEnd, has_end: bool) -> hir::RangeEnd { match *e { - RangeEnd::Included(_) => hir::RangeEnd::Included, - RangeEnd::Excluded => hir::RangeEnd::Excluded, + RangeEnd::Excluded if has_end => hir::RangeEnd::Excluded, + // No end; so `X..` behaves like `RangeFrom`. + RangeEnd::Excluded | RangeEnd::Included(_) => hir::RangeEnd::Included, } } } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 6a15cc5cb0fce..d3876ecc7c3ad 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -534,6 +534,9 @@ declare_features! ( /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used. (active, cfg_sanitize, "1.41.0", Some(39699), None), + /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern. + (active, half_open_range_patterns, "1.41.0", Some(67264), None), + /// Allows using `&mut` in constant functions. (active, const_mut_refs, "1.41.0", Some(57349), None), diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 603c21188e3ac..550e3654d0800 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -905,7 +905,7 @@ pub enum PatKind<'hir> { Lit(&'hir Expr<'hir>), /// A range pattern (e.g., `1..=2` or `1..2`). - Range(&'hir Expr<'hir>, &'hir Expr<'hir>, RangeEnd), + Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd), /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`. /// diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 4664340b15fb7..3dbc5253a9abf 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -766,8 +766,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) { } PatKind::Lit(ref expression) => visitor.visit_expr(expression), PatKind::Range(ref lower_bound, ref upper_bound, _) => { - visitor.visit_expr(lower_bound); - visitor.visit_expr(upper_bound) + walk_list!(visitor, visit_expr, lower_bound); + walk_list!(visitor, visit_expr, upper_bound); } PatKind::Wild => (), PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => { diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 571bab2cb83f2..759f423070aa0 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -1767,13 +1767,17 @@ impl<'a> State<'a> { } PatKind::Lit(ref e) => self.print_expr(&e), PatKind::Range(ref begin, ref end, ref end_kind) => { - self.print_expr(&begin); - self.s.space(); + if let Some(expr) = begin { + self.print_expr(expr); + self.s.space(); + } match *end_kind { RangeEnd::Included => self.s.word("..."), RangeEnd::Excluded => self.s.word(".."), } - self.print_expr(&end); + if let Some(expr) = end { + self.print_expr(expr); + } } PatKind::Slice(ref before, ref slice, ref after) => { self.s.word("["); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 23740af525971..c8a595267569e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,7 +46,6 @@ use syntax::ast::{self, Expr}; use syntax::attr::{self, HasAttrs}; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::{self, expr_to_string}; -use syntax::ptr::P; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::visit::FnKind; @@ -1309,11 +1308,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { /// If `pat` is a `...` pattern, return the start and end of the range, as well as the span /// corresponding to the ellipsis. - fn matches_ellipsis_pat(pat: &ast::Pat) -> Option<(&P, &P, Span)> { + fn matches_ellipsis_pat(pat: &ast::Pat) -> Option<(Option<&Expr>, &Expr, Span)> { match &pat.kind { - PatKind::Range(a, b, Spanned { span, node: RangeEnd::Included(DotDotDot), .. }) => { - Some((a, b, *span)) - } + PatKind::Range( + a, + Some(b), + Spanned { span, node: RangeEnd::Included(DotDotDot) }, + ) => Some((a.as_deref(), b, *span)), _ => None, } } @@ -1328,11 +1329,16 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { let suggestion = "use `..=` for an inclusive range"; if parenthesise { self.node_id = Some(pat.id); + let end = expr_to_string(&end); + let replace = match start { + Some(start) => format!("&({}..={})", expr_to_string(&start), end), + None => format!("&(..={})", end), + }; let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg); err.span_suggestion( pat.span, suggestion, - format!("&({}..={})", expr_to_string(&start), expr_to_string(&end)), + replace, Applicability::MachineApplicable, ); err.emit(); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 611d3f5b832dc..2598ce2391fb3 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -429,14 +429,87 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> (PatKind<'tcx>, Option>) { match self.lower_lit(expr) { - PatKind::AscribeUserType { - ascription: lo_ascription, - subpattern: Pat { kind: box kind, .. }, - } => (kind, Some(lo_ascription)), + PatKind::AscribeUserType { ascription, subpattern: Pat { kind: box kind, .. } } => { + (kind, Some(ascription)) + } kind => (kind, None), } } + fn lower_pattern_range( + &mut self, + ty: Ty<'tcx>, + lo: &'tcx ty::Const<'tcx>, + hi: &'tcx ty::Const<'tcx>, + end: RangeEnd, + span: Span, + ) -> PatKind<'tcx> { + assert_eq!(lo.ty, ty); + assert_eq!(hi.ty, ty); + let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env, ty); + match (end, cmp) { + // `x..y` where `x < y`. + // Non-empty because the range includes at least `x`. + (RangeEnd::Excluded, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }), + // `x..y` where `x >= y`. The range is empty => error. + (RangeEnd::Excluded, _) => { + struct_span_err!( + self.tcx.sess, + span, + E0579, + "lower range bound must be less than upper" + ) + .emit(); + PatKind::Wild + } + // `x..=y` where `x == y`. + (RangeEnd::Included, Some(Ordering::Equal)) => PatKind::Constant { value: lo }, + // `x..=y` where `x < y`. + (RangeEnd::Included, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }), + // `x..=y` where `x > y` hence the range is empty => error. + (RangeEnd::Included, _) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0030, + "lower range bound must be less than or equal to upper" + ); + err.span_label(span, "lower bound larger than upper bound"); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "When matching against a range, the compiler \ + verifies that the range is non-empty. Range \ + patterns include both end-points, so this is \ + equivalent to requiring the start of the range \ + to be less than or equal to the end of the range.", + ); + } + err.emit(); + PatKind::Wild + } + } + } + + fn normalize_range_pattern_ends( + &self, + ty: Ty<'tcx>, + lo: Option<&PatKind<'tcx>>, + hi: Option<&PatKind<'tcx>>, + ) -> Option<(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>)> { + match (lo, hi) { + (Some(PatKind::Constant { value: lo }), Some(PatKind::Constant { value: hi })) => { + Some((lo, hi)) + } + (Some(PatKind::Constant { value: lo }), None) => { + Some((lo, ty.numeric_max_val(self.tcx)?)) + } + (None, Some(PatKind::Constant { value: hi })) => { + Some((ty.numeric_min_val(self.tcx)?, hi)) + } + _ => None, + } + } + fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> { let mut ty = self.tables.node_type(pat.hir_id); @@ -451,65 +524,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Lit(ref value) => self.lower_lit(value), hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => { - let (lo, lo_ascription) = self.lower_range_expr(lo_expr); - let (hi, hi_ascription) = self.lower_range_expr(hi_expr); - - let mut kind = match (lo, hi) { - (PatKind::Constant { value: lo }, PatKind::Constant { value: hi }) => { - assert_eq!(lo.ty, ty); - assert_eq!(hi.ty, ty); - let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env, ty); - match (end, cmp) { - (RangeEnd::Excluded, Some(Ordering::Less)) => { - PatKind::Range(PatRange { lo, hi, end }) - } - (RangeEnd::Excluded, _) => { - struct_span_err!( - self.tcx.sess, - lo_expr.span, - E0579, - "lower range bound must be less than upper", - ) - .emit(); - PatKind::Wild - } - (RangeEnd::Included, Some(Ordering::Equal)) => { - PatKind::Constant { value: lo } - } - (RangeEnd::Included, Some(Ordering::Less)) => { - PatKind::Range(PatRange { lo, hi, end }) - } - (RangeEnd::Included, _) => { - let mut err = struct_span_err!( - self.tcx.sess, - lo_expr.span, - E0030, - "lower range bound must be less than or equal to upper" - ); - err.span_label(lo_expr.span, "lower bound larger than upper bound"); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "When matching against a range, the compiler \ - verifies that the range is non-empty. Range \ - patterns include both end-points, so this is \ - equivalent to requiring the start of the range \ - to be less than or equal to the end of the range.", - ); - } - err.emit(); - PatKind::Wild - } - } - } - ref pats => { - self.tcx.sess.delay_span_bug( - pat.span, - &format!( - "found bad range pattern `{:?}` outside of error recovery", - pats, - ), + let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref()); + let lo_span = lo_expr.map_or(pat.span, |e| e.span); + let lo = lo_expr.map(|e| self.lower_range_expr(e)); + let hi = hi_expr.map(|e| self.lower_range_expr(e)); + + let (lp, hp) = (lo.as_ref().map(|x| &x.0), hi.as_ref().map(|x| &x.0)); + let mut kind = match self.normalize_range_pattern_ends(ty, lp, hp) { + Some((lc, hc)) => self.lower_pattern_range(ty, lc, hc, end, lo_span), + None => { + let msg = &format!( + "found bad range pattern `{:?}` outside of error recovery", + (&lo, &hi), ); - + self.tcx.sess.delay_span_bug(pat.span, msg); PatKind::Wild } }; @@ -517,12 +545,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // If we are handling a range with associated constants (e.g. // `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated // constants somewhere. Have them on the range pattern. - for ascription in &[lo_ascription, hi_ascription] { - if let Some(ascription) = ascription { - kind = PatKind::AscribeUserType { - ascription: *ascription, - subpattern: Pat { span: pat.span, ty, kind: Box::new(kind) }, - }; + for end in &[lo, hi] { + if let Some((_, Some(ascription))) = end { + let subpattern = Pat { span: pat.span, ty, kind: Box::new(kind) }; + kind = PatKind::AscribeUserType { ascription: *ascription, subpattern }; } } diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 9abfbc698c5cf..d321383424cab 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -51,7 +51,6 @@ pub enum Error { secondary_path: String, }, UselessDocComment, - InclusiveRangeWithNoEnd, } impl Error { @@ -102,11 +101,6 @@ impl Error { ); err } - Error::InclusiveRangeWithNoEnd => { - let mut err = struct_span_err!(handler, sp, E0586, "inclusive range with no end",); - err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)"); - err - } } } } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 90f15375aec42..2d6a94ce620cf 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1,4 +1,3 @@ -use super::diagnostics::Error; use super::pat::{GateOr, PARAM_EXPECTED}; use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; @@ -1967,7 +1966,8 @@ impl<'a> Parser<'a> { limits: RangeLimits, ) -> PResult<'a, ExprKind> { if end.is_none() && limits == RangeLimits::Closed { - Err(self.span_fatal_err(self.token.span, Error::InclusiveRangeWithNoEnd)) + self.error_inclusive_range_with_no_end(self.token.span); + Ok(ExprKind::Err) } else { Ok(ExprKind::Range(start, end, limits)) } diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index bf7f5735f134b..50756ddec9f2d 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -1,6 +1,6 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; -use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult}; use rustc_span::source_map::{respan, Span, Spanned}; use rustc_span::symbol::{kw, sym}; use syntax::ast::{self, AttrVec, Attribute, FieldPat, Mac, Pat, PatKind, RangeEnd, RangeSyntax}; @@ -281,91 +281,73 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPat, |x| x); let lo = self.token.span; - let pat = match self.token.kind { - token::BinOp(token::And) | token::AndAnd => self.parse_pat_deref(expected)?, - token::OpenDelim(token::Paren) => self.parse_pat_tuple_or_parens()?, - token::OpenDelim(token::Bracket) => { - // Parse `[pat, pat,...]` as a slice pattern. - let (pats, _) = - self.parse_delim_comma_seq(token::Bracket, |p| p.parse_pat_with_or_inner())?; - PatKind::Slice(pats) - } - token::DotDot => { - self.bump(); - if self.is_pat_range_end_start() { - // Parse `..42` for recovery. - self.parse_pat_range_to(RangeEnd::Excluded, "..")? - } else { - // A rest pattern `..`. - PatKind::Rest - } - } - token::DotDotEq => { - // Parse `..=42` for recovery. - self.bump(); - self.parse_pat_range_to(RangeEnd::Included(RangeSyntax::DotDotEq), "..=")? - } - token::DotDotDot => { - // Parse `...42` for recovery. - self.bump(); - self.parse_pat_range_to(RangeEnd::Included(RangeSyntax::DotDotDot), "...")? + + let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd { + self.parse_pat_deref(expected)? + } else if self.check(&token::OpenDelim(token::Paren)) { + self.parse_pat_tuple_or_parens()? + } else if self.check(&token::OpenDelim(token::Bracket)) { + // Parse `[pat, pat,...]` as a slice pattern. + let (pats, _) = + self.parse_delim_comma_seq(token::Bracket, |p| p.parse_pat_with_or_inner())?; + PatKind::Slice(pats) + } else if self.check(&token::DotDot) && !self.is_pat_range_end_start(1) { + // A rest pattern `..`. + self.bump(); // `..` + PatKind::Rest + } else if let Some(form) = self.parse_range_end() { + self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`. + } else if self.eat_keyword(kw::Underscore) { + // Parse _ + PatKind::Wild + } else if self.eat_keyword(kw::Mut) { + self.parse_pat_ident_mut()? + } else if self.eat_keyword(kw::Ref) { + // Parse ref ident @ pat / ref mut ident @ pat + let mutbl = self.parse_mutability(); + self.parse_pat_ident(BindingMode::ByRef(mutbl))? + } else if self.eat_keyword(kw::Box) { + // Parse `box pat` + let pat = self.parse_pat_with_range_pat(false, None)?; + self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span)); + PatKind::Box(pat) + } else if self.can_be_ident_pat() { + // Parse `ident @ pat` + // This can give false positives and parse nullary enums, + // they are dealt with later in resolve. + self.parse_pat_ident(BindingMode::ByValue(Mutability::Not))? + } else if self.is_start_of_pat_with_path() { + // Parse pattern starting with a path + let (qself, path) = if self.eat_lt() { + // Parse a qualified path + let (qself, path) = self.parse_qpath(PathStyle::Expr)?; + (Some(qself), path) + } else { + // Parse an unqualified path + (None, self.parse_path(PathStyle::Expr)?) + }; + let span = lo.to(self.prev_span); + + if qself.is_none() && self.check(&token::Not) { + self.parse_pat_mac_invoc(path)? + } else if let Some(form) = self.parse_range_end() { + let begin = self.mk_expr(span, ExprKind::Path(qself, path), AttrVec::new()); + self.parse_pat_range_begin_with(begin, form)? + } else if self.check(&token::OpenDelim(token::Brace)) { + self.parse_pat_struct(qself, path)? + } else if self.check(&token::OpenDelim(token::Paren)) { + self.parse_pat_tuple_struct(qself, path)? + } else { + PatKind::Path(qself, path) } - // At this point, token != `&`, `&&`, `(`, `[`, `..`, `..=`, or `...`. - _ => { - if self.eat_keyword(kw::Underscore) { - // Parse _ - PatKind::Wild - } else if self.eat_keyword(kw::Mut) { - self.parse_pat_ident_mut()? - } else if self.eat_keyword(kw::Ref) { - // Parse ref ident @ pat / ref mut ident @ pat - let mutbl = self.parse_mutability(); - self.parse_pat_ident(BindingMode::ByRef(mutbl))? - } else if self.eat_keyword(kw::Box) { - // Parse `box pat` - let pat = self.parse_pat_with_range_pat(false, None)?; - self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span)); - PatKind::Box(pat) - } else if self.can_be_ident_pat() { - // Parse `ident @ pat` - // This can give false positives and parse nullary enums, - // they are dealt with later in resolve. - self.parse_pat_ident(BindingMode::ByValue(Mutability::Not))? - } else if self.is_start_of_pat_with_path() { - // Parse pattern starting with a path - let (qself, path) = if self.eat_lt() { - // Parse a qualified path - let (qself, path) = self.parse_qpath(PathStyle::Expr)?; - (Some(qself), path) - } else { - // Parse an unqualified path - (None, self.parse_path(PathStyle::Expr)?) - }; - match self.token.kind { - token::Not if qself.is_none() => self.parse_pat_mac_invoc(path)?, - token::DotDotDot | token::DotDotEq | token::DotDot => { - self.parse_pat_range_starting_with_path(lo, qself, path)? - } - token::OpenDelim(token::Brace) => self.parse_pat_struct(qself, path)?, - token::OpenDelim(token::Paren) => { - self.parse_pat_tuple_struct(qself, path)? - } - _ => PatKind::Path(qself, path), - } - } else { - // Try to parse everything else as literal with optional minus - match self.parse_literal_maybe_minus() { - Ok(begin) - if self.check(&token::DotDot) - || self.check(&token::DotDotEq) - || self.check(&token::DotDotDot) => - { - self.parse_pat_range_starting_with_lit(begin)? - } - Ok(begin) => PatKind::Lit(begin), - Err(err) => return self.fatal_unexpected_non_pat(err, expected), - } - } + } else { + // Try to parse everything else as literal with optional minus + match self.parse_literal_maybe_minus() { + Ok(begin) => match self.parse_range_end() { + Some(form) => self.parse_pat_range_begin_with(begin, form)?, + None => PatKind::Lit(begin), + }, + Err(err) => return self.fatal_unexpected_non_pat(err, expected), } }; @@ -374,7 +356,7 @@ impl<'a> Parser<'a> { let pat = self.recover_intersection_pat(pat)?; if !allow_range_pat { - self.ban_pat_range_if_ambiguous(&pat)? + self.ban_pat_range_if_ambiguous(&pat) } Ok(pat) @@ -441,26 +423,25 @@ impl<'a> Parser<'a> { } /// Ban a range pattern if it has an ambiguous interpretation. - fn ban_pat_range_if_ambiguous(&self, pat: &Pat) -> PResult<'a, ()> { + fn ban_pat_range_if_ambiguous(&self, pat: &Pat) { match pat.kind { PatKind::Range( .., Spanned { node: RangeEnd::Included(RangeSyntax::DotDotDot), .. }, - ) => return Ok(()), + ) => return, PatKind::Range(..) => {} - _ => return Ok(()), + _ => return, } - let mut err = - self.struct_span_err(pat.span, "the range pattern here has ambiguous interpretation"); - err.span_suggestion( - pat.span, - "add parentheses to clarify the precedence", - format!("({})", pprust::pat_to_string(&pat)), - // "ambiguous interpretation" implies that we have to be guessing - Applicability::MaybeIncorrect, - ); - Err(err) + self.struct_span_err(pat.span, "the range pattern here has ambiguous interpretation") + .span_suggestion( + pat.span, + "add parentheses to clarify the precedence", + format!("({})", pprust::pat_to_string(&pat)), + // "ambiguous interpretation" implies that we have to be guessing + Applicability::MaybeIncorrect, + ) + .emit(); } /// Parse `&pat` / `&mut pat`. @@ -618,51 +599,6 @@ impl<'a> Parser<'a> { Ok(PatKind::Mac(mac)) } - fn excluded_range_end(&self, span: Span) -> RangeEnd { - self.sess.gated_spans.gate(sym::exclusive_range_pattern, span); - RangeEnd::Excluded - } - - /// Parse a range pattern `$path $form $end?` where `$form = ".." | "..." | "..=" ;`. - /// The `$path` has already been parsed and the next token is the `$form`. - fn parse_pat_range_starting_with_path( - &mut self, - lo: Span, - qself: Option, - path: Path, - ) -> PResult<'a, PatKind> { - let (end_kind, form) = match self.token.kind { - token::DotDot => (self.excluded_range_end(self.token.span), ".."), - token::DotDotDot => (RangeEnd::Included(RangeSyntax::DotDotDot), "..."), - token::DotDotEq => (RangeEnd::Included(RangeSyntax::DotDotEq), "..="), - _ => panic!("can only parse `..`/`...`/`..=` for ranges (checked above)"), - }; - let op_span = self.token.span; - // Parse range - let span = lo.to(self.prev_span); - let begin = self.mk_expr(span, ExprKind::Path(qself, path), AttrVec::new()); - self.bump(); - let end = self.parse_pat_range_end_opt(&begin, form)?; - Ok(PatKind::Range(begin, end, respan(op_span, end_kind))) - } - - /// Parse a range pattern `$literal $form $end?` where `$form = ".." | "..." | "..=" ;`. - /// The `$path` has already been parsed and the next token is the `$form`. - fn parse_pat_range_starting_with_lit(&mut self, begin: P) -> PResult<'a, PatKind> { - let op_span = self.token.span; - let (end_kind, form) = if self.eat(&token::DotDotDot) { - (RangeEnd::Included(RangeSyntax::DotDotDot), "...") - } else if self.eat(&token::DotDotEq) { - (RangeEnd::Included(RangeSyntax::DotDotEq), "..=") - } else if self.eat(&token::DotDot) { - (self.excluded_range_end(op_span), "..") - } else { - panic!("impossible case: we already matched on a range-operator token") - }; - let end = self.parse_pat_range_end_opt(&begin, form)?; - Ok(PatKind::Range(begin, end, respan(op_span, end_kind))) - } - fn fatal_unexpected_non_pat( &mut self, mut err: DiagnosticBuilder<'a>, @@ -684,57 +620,66 @@ impl<'a> Parser<'a> { Err(err) } - /// Is the current token suitable as the start of a range patterns end? - fn is_pat_range_end_start(&self) -> bool { - self.token.is_path_start() // e.g. `MY_CONST`; - || self.token == token::Dot // e.g. `.5` for recovery; - || self.token.can_begin_literal_or_bool() // e.g. `42`. - || self.token.is_whole_expr() - } - - /// Parse a range-to pattern, e.g. `..X` and `..=X` for recovery. - fn parse_pat_range_to(&mut self, re: RangeEnd, form: &str) -> PResult<'a, PatKind> { - let lo = self.prev_span; - let end = self.parse_pat_range_end()?; - let range_span = lo.to(end.span); - let begin = self.mk_expr(range_span, ExprKind::Err, AttrVec::new()); - - self.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form)) - .span_suggestion( - range_span, - "try using the minimum value for the type", - format!("MIN{}{}", form, pprust::expr_to_string(&end)), - Applicability::HasPlaceholders, - ) - .emit(); - - Ok(PatKind::Range(begin, end, respan(lo, re))) + /// Parses the range pattern end form `".." | "..." | "..=" ;`. + fn parse_range_end(&mut self) -> Option> { + let re = if self.eat(&token::DotDotDot) { + RangeEnd::Included(RangeSyntax::DotDotDot) + } else if self.eat(&token::DotDotEq) { + RangeEnd::Included(RangeSyntax::DotDotEq) + } else if self.eat(&token::DotDot) { + self.sess.gated_spans.gate(sym::exclusive_range_pattern, self.prev_span); + RangeEnd::Excluded + } else { + return None; + }; + Some(respan(self.prev_span, re)) } - /// Parse the end of a `X..Y`, `X..=Y`, or `X...Y` range pattern or recover - /// if that end is missing treating it as `X..`, `X..=`, or `X...` respectively. - fn parse_pat_range_end_opt(&mut self, begin: &Expr, form: &str) -> PResult<'a, P> { - if self.is_pat_range_end_start() { + /// Parse a range pattern `$begin $form $end?` where `$form = ".." | "..." | "..=" ;`. + /// `$begin $form` has already been parsed. + fn parse_pat_range_begin_with( + &mut self, + begin: P, + re: Spanned, + ) -> PResult<'a, PatKind> { + let end = if self.is_pat_range_end_start(0) { // Parsing e.g. `X..=Y`. - self.parse_pat_range_end() + Some(self.parse_pat_range_end()?) } else { // Parsing e.g. `X..`. - let range_span = begin.span.to(self.prev_span); + self.sess.gated_spans.gate(sym::half_open_range_patterns, begin.span.to(re.span)); + if let RangeEnd::Included(_) = re.node { + // FIXME(Centril): Consider semantic errors instead in `ast_validation`. + // Possibly also do this for `X..=` in *expression* contexts. + self.error_inclusive_range_with_no_end(re.span); + } + None + }; + Ok(PatKind::Range(Some(begin), end, re)) + } - self.struct_span_err( - range_span, - &format!("`X{}` range patterns are not supported", form), - ) - .span_suggestion( - range_span, - "try using the maximum value for the type", - format!("{}{}MAX", pprust::expr_to_string(&begin), form), - Applicability::HasPlaceholders, - ) + pub(super) fn error_inclusive_range_with_no_end(&self, span: Span) { + use rustc_error_codes::E0586; + struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end") + .help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)") .emit(); + } - Ok(self.mk_expr(range_span, ExprKind::Err, AttrVec::new())) - } + /// Parse a range-to pattern, e.g. `..X` and `..=X` where `X` remains to be parsed. + fn parse_pat_range_to(&mut self, re: Spanned) -> PResult<'a, PatKind> { + let end = self.parse_pat_range_end()?; + self.sess.gated_spans.gate(sym::half_open_range_patterns, re.span.to(self.prev_span)); + Ok(PatKind::Range(None, Some(end), re)) + } + + /// Is the token `dist` away from the current suitable as the start of a range patterns end? + fn is_pat_range_end_start(&self, dist: usize) -> bool { + self.look_ahead(dist, |t| { + t.is_path_start() // e.g. `MY_CONST`; + || t.kind == token::Dot // e.g. `.5` for recovery; + || t.can_begin_literal_or_bool() // e.g. `42`. + || t.is_whole_expr() + }) } fn parse_pat_range_end(&mut self) -> PResult<'a, P> { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 724d717304c20..43c997d34e160 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -920,8 +920,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_expr_within_pat(expr, false); } PatKind::Range(ref start, ref end, _) => { - self.check_expr_within_pat(start, true); - self.check_expr_within_pat(end, true); + if let Some(expr) = start { + self.check_expr_within_pat(expr, true); + } + if let Some(expr) = end { + self.check_expr_within_pat(expr, true); + } } _ => {} } diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index d9f4b72560ceb..a8b2db300a478 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -343,6 +343,7 @@ symbols! { global_allocator, global_asm, globs, + half_open_range_patterns, hash, Hash, HashSet, diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 58c722f1da6f4..c2db165e29d15 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -135,12 +135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = match pat.kind { PatKind::Wild => expected, PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti), - PatKind::Range(begin, end, _) => { - match self.check_pat_range(pat.span, begin, end, expected, ti) { - None => return, - Some(ty) => ty, - } - } + PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti), PatKind::Binding(ba, var_id, _, sub) => { self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, ti) } @@ -395,39 +390,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_range( &self, span: Span, - lhs: &'tcx hir::Expr<'tcx>, - rhs: &'tcx hir::Expr<'tcx>, + lhs: Option<&'tcx hir::Expr<'tcx>>, + rhs: Option<&'tcx hir::Expr<'tcx>>, expected: Ty<'tcx>, ti: TopInfo<'tcx>, - ) -> Option> { - let lhs_ty = self.check_expr(lhs); - let rhs_ty = self.check_expr(rhs); - - // Check that both end-points are of numeric or char type. - let numeric_or_char = |ty: Ty<'_>| ty.is_numeric() || ty.is_char() || ty.references_error(); - let lhs_fail = !numeric_or_char(lhs_ty); - let rhs_fail = !numeric_or_char(rhs_ty); - - if lhs_fail || rhs_fail { - self.emit_err_pat_range(span, lhs.span, rhs.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty); - return None; + ) -> Ty<'tcx> { + let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr { + None => (None, None), + Some(expr) => { + let ty = self.check_expr(expr); + // Check that the end-point is of numeric or char type. + let fail = !(ty.is_numeric() || ty.is_char() || ty.references_error()); + (Some(ty), Some((fail, ty, expr.span))) + } + }; + let (lhs_ty, lhs) = calc_side(lhs); + let (rhs_ty, rhs) = calc_side(rhs); + + if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { + // There exists a side that didn't meet our criteria that the end-point + // be of a numeric or char type, as checked in `calc_side` above. + self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.types.err; } - // Now that we know the types can be unified we find the unified type and use - // it to type the entire expression. - let common_type = self.resolve_vars_if_possible(&lhs_ty); + // Now that we know the types can be unified we find the unified type + // and use it to type the entire expression. + let common_type = self.resolve_vars_if_possible(&lhs_ty.or(rhs_ty).unwrap_or(expected)); // Subtyping doesn't matter here, as the value is some kind of scalar. - let demand_eqtype = |x_span, y_span, x_ty, y_ty| { - self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti).map(|mut err| { - self.endpoint_has_type(&mut err, y_span, y_ty); - err.emit(); - }); + let demand_eqtype = |x, y| { + if let Some((_, x_ty, x_span)) = x { + self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti).map(|mut err| { + if let Some((_, y_ty, y_span)) = y { + self.endpoint_has_type(&mut err, y_span, y_ty); + } + err.emit(); + }); + } }; - demand_eqtype(lhs.span, rhs.span, lhs_ty, rhs_ty); - demand_eqtype(rhs.span, lhs.span, rhs_ty, lhs_ty); + demand_eqtype(lhs, rhs); + demand_eqtype(rhs, lhs); - Some(common_type) + common_type } fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) { @@ -439,21 +444,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn emit_err_pat_range( &self, span: Span, - begin_span: Span, - end_span: Span, - lhs_fail: bool, - rhs_fail: bool, - lhs_ty: Ty<'tcx>, - rhs_ty: Ty<'tcx>, + lhs: Option<(bool, Ty<'tcx>, Span)>, + rhs: Option<(bool, Ty<'tcx>, Span)>, ) { - let span = if lhs_fail && rhs_fail { - span - } else if lhs_fail { - begin_span - } else { - end_span + let span = match (lhs, rhs) { + (Some((true, ..)), Some((true, ..))) => span, + (Some((true, _, sp)), _) => sp, + (_, Some((true, _, sp))) => sp, + _ => span_bug!(span, "emit_err_pat_range: no side failed or exists but still error?"), }; - let mut err = struct_span_err!( self.tcx.sess, span, @@ -461,17 +460,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "only char and numeric types are allowed in range patterns" ); let msg = |ty| format!("this is of type `{}` but it should be `char` or numeric", ty); - let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| { + let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| { err.span_label(first_span, &msg(first_ty)); - self.endpoint_has_type(&mut err, second_span, second_ty); + if let Some((_, ty, sp)) = second { + self.endpoint_has_type(&mut err, sp, ty); + } }; - if lhs_fail && rhs_fail { - err.span_label(begin_span, &msg(lhs_ty)); - err.span_label(end_span, &msg(rhs_ty)); - } else if lhs_fail { - one_side_err(begin_span, lhs_ty, end_span, rhs_ty); - } else { - one_side_err(end_span, rhs_ty, begin_span, lhs_ty); + match (lhs, rhs) { + (Some((true, lhs_ty, lhs_sp)), Some((true, rhs_ty, rhs_sp))) => { + err.span_label(lhs_sp, &msg(lhs_ty)); + err.span_label(rhs_sp, &msg(rhs_ty)); + } + (Some((true, lhs_ty, lhs_sp)), rhs) => one_side_err(lhs_sp, lhs_ty, rhs), + (lhs, Some((true, rhs_ty, rhs_sp))) => one_side_err(rhs_sp, rhs_ty, lhs), + _ => span_bug!(span, "Impossible, verified above."), } if self.tcx.sess.teach(&err.get_code().unwrap()) { err.note( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1d3bb7d87686c..33acba8eba010 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -649,7 +649,7 @@ pub enum PatKind { Lit(P), /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`). - Range(P, P, Spanned), + Range(Option>, Option>, Spanned), /// A slice pattern `[a, b, c]`. Slice(Vec>), diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 52eb20d320f7b..5e4319051728f 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -911,6 +911,7 @@ pub fn check_crate( gate_all!(raw_ref_op, "raw address of syntax is experimental"); gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental"); gate_all!(const_trait_impl, "const trait impls are experimental"); + gate_all!(half_open_range_patterns, "half-open range patterns are unstable"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 264ba25cedecc..58d4e46111b83 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -1075,8 +1075,8 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { PatKind::Box(inner) => vis.visit_pat(inner), PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { - vis.visit_expr(e1); - vis.visit_expr(e2); + visit_opt(e1, |e| vis.visit_expr(e)); + visit_opt(e2, |e| vis.visit_expr(e)); vis.visit_span(span); } PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index dd9976510dccf..11c8cb8ef7500 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2329,14 +2329,18 @@ impl<'a> State<'a> { } PatKind::Lit(ref e) => self.print_expr(&**e), PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { - self.print_expr(begin); - self.s.space(); + if let Some(e) = begin { + self.print_expr(e); + self.s.space(); + } match *end_kind { RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("..."), RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..="), RangeEnd::Excluded => self.s.word(".."), } - self.print_expr(end); + if let Some(e) = end { + self.print_expr(e); + } } PatKind::Slice(ref elts) => { self.s.word("["); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index ebb49abebb01e..3c2ebacbc4e34 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -492,8 +492,8 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { } PatKind::Lit(ref expression) => visitor.visit_expr(expression), PatKind::Range(ref lower_bound, ref upper_bound, _) => { - visitor.visit_expr(lower_bound); - visitor.visit_expr(upper_bound); + walk_list!(visitor, visit_expr, lower_bound); + walk_list!(visitor, visit_expr, upper_bound); } PatKind::Wild | PatKind::Rest => {} PatKind::Tuple(ref elems) | PatKind::Slice(ref elems) | PatKind::Or(ref elems) => { diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs similarity index 59% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs index d97b693f52098..3f4c17836c4fc 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs @@ -1,10 +1,10 @@ +#![feature(half_open_range_patterns)] #![feature(exclusive_range_pattern)] fn main() { match [5..4, 99..105, 43..44] { [_, 99.., _] => {}, - //~^ ERROR `X..` range patterns are not supported - //~| ERROR mismatched types + //~^ ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr similarity index 57% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr index 76ae7241ff277..a6f8563a04785 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr @@ -1,11 +1,5 @@ -error: `X..` range patterns are not supported - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 - | -LL | [_, 99.., _] => {}, - | ^^^^ help: try using the maximum value for the type: `99..MAX` - error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 + --> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -15,6 +9,6 @@ LL | [_, 99.., _] => {}, = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs similarity index 58% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs index 09f459c9862ee..dedc85491b4a9 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs @@ -1,10 +1,10 @@ +#![feature(half_open_range_patterns)] #![feature(exclusive_range_pattern)] fn main() { match [5..4, 99..105, 43..44] { [_, 99..] => {}, - //~^ ERROR `X..` range patterns are not supported - //~| ERROR pattern requires 2 elements but array has 3 + //~^ ERROR pattern requires 2 elements but array has 3 //~| ERROR mismatched types _ => {}, } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr similarity index 62% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr index 5c96f8041feb2..4e0102c930da8 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr @@ -1,17 +1,11 @@ -error: `X..` range patterns are not supported - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 - | -LL | [_, 99..] => {}, - | ^^^^ help: try using the maximum value for the type: `99..MAX` - error[E0527]: pattern requires 2 elements but array has 3 - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:9 | LL | [_, 99..] => {}, | ^^^^^^^^^ expected 3 elements error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -21,7 +15,7 @@ LL | [_, 99..] => {}, = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0308, E0527. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs similarity index 69% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs index 1557f592b2a9b..6a9b562cc3a3b 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs @@ -1,10 +1,10 @@ +#![feature(half_open_range_patterns)] #![feature(exclusive_range_pattern)] fn main() { match [5..4, 99..105, 43..44] { [..9, 99..100, _] => {}, - //~^ ERROR `..X` range patterns are not supported - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| ERROR mismatched types //~| ERROR mismatched types _ => {}, diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr similarity index 75% rename from src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr rename to src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr index 17e10324db181..665eef2fcb96c 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr @@ -1,11 +1,5 @@ -error: `..X` range patterns are not supported - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 - | -LL | [..9, 99..100, _] => {}, - | ^^^ help: try using the minimum value for the type: `MIN..9` - error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:12 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -16,7 +10,7 @@ LL | [..9, 99..100, _] => {}, found type `{integer}` error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -29,7 +23,7 @@ LL | [..9, 99..100, _] => {}, found type `{integer}` error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -41,6 +35,6 @@ LL | [..9, 99..100, _] => {}, = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs new file mode 100644 index 0000000000000..4cb8230a7b620 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs @@ -0,0 +1,21 @@ +#![feature(exclusive_range_pattern)] + +fn main() {} + +#[cfg(FALSE)] +fn foo() { + if let ..=5 = 0 {} + //~^ ERROR half-open range patterns are unstable + if let ...5 = 0 {} + //~^ ERROR half-open range patterns are unstable + if let ..5 = 0 {} + //~^ ERROR half-open range patterns are unstable + if let 5.. = 0 {} + //~^ ERROR half-open range patterns are unstable + if let 5..= = 0 {} + //~^ ERROR half-open range patterns are unstable + //~| ERROR inclusive range with no end + if let 5... = 0 {} + //~^ ERROR half-open range patterns are unstable + //~| ERROR inclusive range with no end +} diff --git a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr new file mode 100644 index 0000000000000..68ba654de76da --- /dev/null +++ b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr @@ -0,0 +1,74 @@ +error[E0586]: inclusive range with no end + --> $DIR/feature-gate-half-open-range-patterns.rs:15:13 + | +LL | if let 5..= = 0 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/feature-gate-half-open-range-patterns.rs:18:13 + | +LL | if let 5... = 0 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:7:12 + | +LL | if let ..=5 = 0 {} + | ^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:9:12 + | +LL | if let ...5 = 0 {} + | ^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:11:12 + | +LL | if let ..5 = 0 {} + | ^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:13:12 + | +LL | if let 5.. = 0 {} + | ^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:15:12 + | +LL | if let 5..= = 0 {} + | ^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: half-open range patterns are unstable + --> $DIR/feature-gate-half-open-range-patterns.rs:18:12 + | +LL | if let 5... = 0 {} + | ^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/67264 + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0586, E0658. +For more information about an error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs new file mode 100644 index 0000000000000..7cddf5f652a31 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs @@ -0,0 +1,8 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + let "a".. = "a"; //~ ERROR only char and numeric types are allowed in range patterns + let .."a" = "a"; //~ ERROR only char and numeric types are allowed in range patterns + let ..="a" = "a"; //~ ERROR only char and numeric types are allowed in range patterns +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr new file mode 100644 index 0000000000000..68ca3637150d3 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr @@ -0,0 +1,21 @@ +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/half-open-range-pats-bad-types.rs:5:9 + | +LL | let "a".. = "a"; + | ^^^ this is of type `&'static str` but it should be `char` or numeric + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/half-open-range-pats-bad-types.rs:6:11 + | +LL | let .."a" = "a"; + | ^^^ this is of type `&'static str` but it should be `char` or numeric + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/half-open-range-pats-bad-types.rs:7:12 + | +LL | let ..="a" = "a"; + | ^^^ this is of type `&'static str` but it should be `char` or numeric + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs new file mode 100644 index 0000000000000..b135891d0b82f --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs @@ -0,0 +1,168 @@ +// Test various non-exhaustive matches for `X..`, `..=X` and `..X` ranges. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] + +fn main() {} + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn floats() { + m!(0f32, core::f32::NEG_INFINITY..); //~ ERROR non-exhaustive patterns: `_` not covered + m!(0f32, ..core::f32::INFINITY); //~ ERROR non-exhaustive patterns: `_` not covered +} + +fn khar() { + const ALMOST_MAX: char = '\u{10fffe}'; + const ALMOST_MIN: char = '\u{1}'; + const VAL: char = 'a'; + const VAL_1: char = 'b'; + const VAL_2: char = 'c'; + m!('a', ..core::char::MAX); //~ ERROR non-exhaustive patterns + m!('a', ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!('a', ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!('a', ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!('a', ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!('a', ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns +} + +mod unsigned { + fn u8() { + const ALMOST_MAX: u8 = core::u8::MAX - 1; + const ALMOST_MIN: u8 = core::u8::MIN + 1; + const VAL: u8 = 42; + const VAL_1: u8 = VAL + 1; + const VAL_2: u8 = VAL + 2; + m!(0, ..core::u8::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn u16() { + const ALMOST_MAX: u16 = core::u16::MAX - 1; + const ALMOST_MIN: u16 = core::u16::MIN + 1; + const VAL: u16 = 42; + const VAL_1: u16 = VAL + 1; + const VAL_2: u16 = VAL + 2; + m!(0, ..core::u16::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn u32() { + const ALMOST_MAX: u32 = core::u32::MAX - 1; + const ALMOST_MIN: u32 = core::u32::MIN + 1; + const VAL: u32 = 42; + const VAL_1: u32 = VAL + 1; + const VAL_2: u32 = VAL + 2; + m!(0, ..core::u32::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn u64() { + const ALMOST_MAX: u64 = core::u64::MAX - 1; + const ALMOST_MIN: u64 = core::u64::MIN + 1; + const VAL: u64 = 42; + const VAL_1: u64 = VAL + 1; + const VAL_2: u64 = VAL + 2; + m!(0, ..core::u64::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn u128() { + const ALMOST_MAX: u128 = core::u128::MAX - 1; + const ALMOST_MIN: u128 = core::u128::MIN + 1; + const VAL: u128 = 42; + const VAL_1: u128 = VAL + 1; + const VAL_2: u128 = VAL + 2; + m!(0, ..core::u128::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } +} + +mod signed { + fn i8() { + const ALMOST_MAX: i8 = core::i8::MAX - 1; + const ALMOST_MIN: i8 = core::i8::MIN + 1; + const VAL: i8 = 42; + const VAL_1: i8 = VAL + 1; + const VAL_2: i8 = VAL + 2; + m!(0, ..core::i8::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn i16() { + const ALMOST_MAX: i16 = core::i16::MAX - 1; + const ALMOST_MIN: i16 = core::i16::MIN + 1; + const VAL: i16 = 42; + const VAL_1: i16 = VAL + 1; + const VAL_2: i16 = VAL + 2; + m!(0, ..core::i16::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn i32() { + const ALMOST_MAX: i32 = core::i32::MAX - 1; + const ALMOST_MIN: i32 = core::i32::MIN + 1; + const VAL: i32 = 42; + const VAL_1: i32 = VAL + 1; + const VAL_2: i32 = VAL + 2; + m!(0, ..core::i32::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn i64() { + const ALMOST_MAX: i64 = core::i64::MAX - 1; + const ALMOST_MIN: i64 = core::i64::MIN + 1; + const VAL: i64 = 42; + const VAL_1: i64 = VAL + 1; + const VAL_2: i64 = VAL + 2; + m!(0, ..core::i64::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } + fn i128() { + const ALMOST_MAX: i128 = core::i128::MAX - 1; + const ALMOST_MIN: i128 = core::i128::MIN + 1; + const VAL: i128 = 42; + const VAL_1: i128 = VAL + 1; + const VAL_2: i128 = VAL + 2; + m!(0, ..core::i128::MAX); //~ ERROR non-exhaustive patterns + m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns + m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns + m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns + } +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr new file mode 100644 index 0000000000000..26d0cf9e9ecba --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr @@ -0,0 +1,547 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:8 + | +LL | m!(0f32, core::f32::NEG_INFINITY..); + | ^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:8 + | +LL | m!(0f32, ..core::f32::INFINITY); + | ^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8 + | +LL | m!('a', ..core::char::MAX); + | ^^^ pattern `'\u{10ffff}'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8 + | +LL | m!('a', ..ALMOST_MAX); + | ^^^ pattern `'\u{10fffe}'..='\u{10ffff}'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'\u{0}'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8 + | +LL | m!('a', ALMOST_MIN..); + | ^^^ pattern `'\u{0}'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8 + | +LL | m!('a', ..=ALMOST_MAX); + | ^^^ pattern `'\u{10ffff}'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'b'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:30:8 + | +LL | m!('a', ..=VAL | VAL_2..); + | ^^^ pattern `'b'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `'b'` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:31:8 + | +LL | m!('a', ..VAL_1 | VAL_2..); + | ^^^ pattern `'b'` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12 + | +LL | m!(0, ..core::u8::MAX); + | ^ pattern `std::u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `254u8..=std::u8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `254u8..=std::u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u8` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `0u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u8` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:45:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u8` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:46:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12 + | +LL | m!(0, ..core::u16::MAX); + | ^ pattern `std::u16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `65534u16..=std::u16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `65534u16..=std::u16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u16` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `0u16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::u16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u16` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:58:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43u16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u16` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:59:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43u16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12 + | +LL | m!(0, ..core::u32::MAX); + | ^ pattern `std::u32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `4294967294u32..=std::u32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `4294967294u32..=std::u32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u32` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `0u32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::u32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u32` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:71:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43u32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u32` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:72:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43u32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12 + | +LL | m!(0, ..core::u64::MAX); + | ^ pattern `std::u64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `18446744073709551614u64..=std::u64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `18446744073709551614u64..=std::u64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u64` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `0u64` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::u64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u64` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:84:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43u64` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u64` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:85:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43u64` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12 + | +LL | m!(0, ..core::u128::MAX); + | ^ pattern `std::u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454u128..=std::u128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `340282366920938463463374607431768211454u128..=std::u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u128` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `0u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::u128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u128` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:97:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43u128` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:98:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12 + | +LL | m!(0, ..core::i8::MAX); + | ^ pattern `std::i8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `126i8..=std::i8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `126i8..=std::i8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i8::MIN` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `std::i8::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i8::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::i8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i8` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:113:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43i8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i8` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:114:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43i8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12 + | +LL | m!(0, ..core::i16::MAX); + | ^ pattern `std::i16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `32766i16..=std::i16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `32766i16..=std::i16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i16::MIN` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `std::i16::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i16::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::i16::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i16` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:126:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43i16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i16` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:127:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43i16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12 + | +LL | m!(0, ..core::i32::MAX); + | ^ pattern `std::i32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `2147483646i32..=std::i32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `2147483646i32..=std::i32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i32::MIN` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `std::i32::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i32::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::i32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i32` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:139:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43i32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i32` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:140:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43i32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12 + | +LL | m!(0, ..core::i64::MAX); + | ^ pattern `std::i64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `9223372036854775806i64..=std::i64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `9223372036854775806i64..=std::i64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i64::MIN` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `std::i64::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i64::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::i64::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i64` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:152:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43i64` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i64` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:153:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43i64` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12 + | +LL | m!(0, ..core::i128::MAX); + | ^ pattern `std::i128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726i128..=std::i128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12 + | +LL | m!(0, ..ALMOST_MAX); + | ^ pattern `170141183460469231731687303715884105726i128..=std::i128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i128::MIN` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12 + | +LL | m!(0, ALMOST_MIN..); + | ^ pattern `std::i128::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i128::MAX` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12 + | +LL | m!(0, ..=ALMOST_MAX); + | ^ pattern `std::i128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i128` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:165:12 + | +LL | m!(0, ..=VAL | VAL_2..); + | ^ pattern `43i128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `43i128` not covered + --> $DIR/half-open-range-pats-exhaustive-fail.rs:166:12 + | +LL | m!(0, ..VAL_1 | VAL_2..); + | ^ pattern `43i128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 68 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs new file mode 100644 index 0000000000000..efac0df2a430d --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs @@ -0,0 +1,49 @@ +// check-pass + +// Test various exhaustive matches for `X..`, `..=X` and `..X` ranges. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() {} + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +macro_rules! test_int { + ($s:expr, $min:path, $max:path) => { + m!($s, $min..); + m!($s, $min..5 | 5..); + m!($s, ..5 | 5..); + m!($s, ..=4 | 5..); + m!($s, ..=$max); + m!($s, ..$max | $max); + m!(($s, true), (..5, true) | (5.., true) | ($min.., false)); + } +} + +fn unsigned_int() { + test_int!(0u8, core::u8::MIN, core::u8::MAX); + test_int!(0u16, core::u16::MIN, core::u16::MAX); + test_int!(0u32, core::u32::MIN, core::u32::MAX); + test_int!(0u64, core::u64::MIN, core::u64::MAX); + test_int!(0u128, core::u128::MIN, core::u128::MAX); +} + +fn signed_int() { + test_int!(0i8, core::i8::MIN, core::i8::MAX); + test_int!(0i16, core::i16::MIN, core::i16::MAX); + test_int!(0i32, core::i32::MIN, core::i32::MAX); + test_int!(0i64, core::i64::MIN, core::i64::MAX); + test_int!(0i128, core::i128::MIN, core::i128::MAX); +} + +fn khar() { + m!('a', ..=core::char::MAX); + m!('a', '\u{0}'..); + m!('a', ..='\u{D7FF}' | '\u{E000}'..); + m!('a', ..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..); +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs new file mode 100644 index 0000000000000..904efda903c69 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs @@ -0,0 +1,54 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn main() { + m!(0, ..core::u8::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::u16::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::u32::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::u64::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::u128::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + + m!(0, ..core::i8::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::i16::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::i32::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::i64::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0, ..core::i128::MIN); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + + m!(0f32, ..core::f32::NEG_INFINITY); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + m!(0f64, ..core::f64::NEG_INFINITY); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + + m!('a', ..'\u{0}'); + //~^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr new file mode 100644 index 0000000000000..b536e1b5548d0 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr @@ -0,0 +1,159 @@ +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:12:11 + | +LL | m!(0, ..core::u8::MIN); + | ^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:15:11 + | +LL | m!(0, ..core::u16::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:18:11 + | +LL | m!(0, ..core::u32::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:21:11 + | +LL | m!(0, ..core::u64::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:24:11 + | +LL | m!(0, ..core::u128::MIN); + | ^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:28:11 + | +LL | m!(0, ..core::i8::MIN); + | ^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:31:11 + | +LL | m!(0, ..core::i16::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:34:11 + | +LL | m!(0, ..core::i32::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:37:11 + | +LL | m!(0, ..core::i64::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:40:11 + | +LL | m!(0, ..core::i128::MIN); + | ^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 + | +LL | m!(0f32, ..core::f32::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 + | +LL | m!(0f64, ..core::f64::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:51:13 + | +LL | m!('a', ..'\u{0}'); + | ^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:12:11 + | +LL | m!(0, ..core::u8::MIN); + | ^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:15:11 + | +LL | m!(0, ..core::u16::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:18:11 + | +LL | m!(0, ..core::u32::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:21:11 + | +LL | m!(0, ..core::u64::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:24:11 + | +LL | m!(0, ..core::u128::MIN); + | ^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:28:11 + | +LL | m!(0, ..core::i8::MIN); + | ^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:31:11 + | +LL | m!(0, ..core::i16::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:34:11 + | +LL | m!(0, ..core::i32::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:37:11 + | +LL | m!(0, ..core::i64::MIN); + | ^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:40:11 + | +LL | m!(0, ..core::i128::MIN); + | ^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 + | +LL | m!(0f32, ..core::f32::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 + | +LL | m!(0f64, ..core::f64::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-hair-lower-empty.rs:51:13 + | +LL | m!('a', ..'\u{0}'); + | ^^^^^^^^^ + +error: aborting due to 26 previous errors + +For more information about this error, try `rustc --explain E0579`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs new file mode 100644 index 0000000000000..03166e3675571 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs @@ -0,0 +1,15 @@ +// Test `X...` and `X..=` range patterns not being allowed syntactically. +// FIXME(Centril): perhaps these should be semantic restrictions. + +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn foo() { + if let 0... = 1 {} //~ ERROR inclusive range with no end + if let 0..= = 1 {} //~ ERROR inclusive range with no end + const X: u8 = 0; + if let X... = 1 {} //~ ERROR inclusive range with no end + if let X..= = 1 {} //~ ERROR inclusive range with no end +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr new file mode 100644 index 0000000000000..2b4d95f684284 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr @@ -0,0 +1,35 @@ +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:10:13 + | +LL | if let 0... = 1 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:11:13 + | +LL | if let 0..= = 1 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:13:13 + | +LL | if let X... = 1 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:14:13 + | +LL | if let X..= = 1 {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs new file mode 100644 index 0000000000000..e9a5361e63d27 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs @@ -0,0 +1,24 @@ +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match &0 { + &0.. | _ => {} + //~^ ERROR the range pattern here has ambiguous interpretation + &0..= | _ => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~| ERROR inclusive range with no end + &0... | _ => {} + //~^ ERROR inclusive range with no end + } + + match &0 { + &..0 | _ => {} + //~^ ERROR the range pattern here has ambiguous interpretation + &..=0 | _ => {} + //~^ ERROR the range pattern here has ambiguous interpretation + &...0 | _ => {} + } +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr new file mode 100644 index 0000000000000..5d3aded022224 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr @@ -0,0 +1,43 @@ +error: the range pattern here has ambiguous interpretation + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:8:10 + | +LL | &0.. | _ => {} + | ^^^ help: add parentheses to clarify the precedence: `(0 ..)` + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:11 + | +LL | &0..= | _ => {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: the range pattern here has ambiguous interpretation + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:10 + | +LL | &0..= | _ => {} + | ^^^^ help: add parentheses to clarify the precedence: `(0 ..=)` + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:13:11 + | +LL | &0... | _ => {} + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: the range pattern here has ambiguous interpretation + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:18:10 + | +LL | &..0 | _ => {} + | ^^^ help: add parentheses to clarify the precedence: `(..0)` + +error: the range pattern here has ambiguous interpretation + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:20:10 + | +LL | &..=0 | _ => {} + | ^^^^ help: add parentheses to clarify the precedence: `(..=0)` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-semantics.rs new file mode 100644 index 0000000000000..416c59af3fd3e --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -0,0 +1,160 @@ +// run-pass + +// Test half-open range patterns against their expression equivalents +// via `.contains(...)` and make sure the dynamic semantics match. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] +#![allow(unreachable_patterns)] + +macro_rules! yes { + ($scrutinee:expr, $($t:tt)+) => { + { + let m = match $scrutinee { $($t)+ => true, _ => false, }; + let c = ($($t)+).contains(&$scrutinee); + assert_eq!(m, c); + m + } + } +} + +fn range_to_inclusive() { + // `..=X` (`RangeToInclusive`-equivalent): + //--------------------------------------- + + // u8; `..=X` + assert!(yes!(core::u8::MIN, ..=core::u8::MIN)); + assert!(yes!(core::u8::MIN, ..=5)); + assert!(yes!(5u8, ..=5)); + assert!(!yes!(6u8, ..=5)); + + // i16; `..=X` + assert!(yes!(core::i16::MIN, ..=core::i16::MIN)); + assert!(yes!(core::i16::MIN, ..=0)); + assert!(yes!(core::i16::MIN, ..=-5)); + assert!(yes!(-5, ..=-5)); + assert!(!yes!(-4, ..=-5)); + + // char; `..=X` + assert!(yes!('\u{0}', ..='\u{0}')); + assert!(yes!('\u{0}', ..='a')); + assert!(yes!('a', ..='a')); + assert!(!yes!('b', ..='a')); + + // f32; `..=X` + assert!(yes!(core::f32::NEG_INFINITY, ..=core::f32::NEG_INFINITY)); + assert!(yes!(core::f32::NEG_INFINITY, ..=1.0f32)); + assert!(yes!(1.5f32, ..=1.5f32)); + assert!(!yes!(1.6f32, ..=-1.5f32)); + + // f64; `..=X` + assert!(yes!(core::f64::NEG_INFINITY, ..=core::f64::NEG_INFINITY)); + assert!(yes!(core::f64::NEG_INFINITY, ..=1.0f64)); + assert!(yes!(1.5f64, ..=1.5f64)); + assert!(!yes!(1.6f64, ..=-1.5f64)); +} + +fn range_to() { + // `..X` (`RangeTo`-equivalent): + //----------------------------- + + // u8; `..X` + assert!(yes!(0u8, ..1)); + assert!(yes!(0u8, ..5)); + assert!(!yes!(5u8, ..5)); + assert!(!yes!(6u8, ..5)); + + // u8; `..X` + const NU8: u8 = core::u8::MIN + 1; + assert!(yes!(core::u8::MIN, ..NU8)); + assert!(yes!(0u8, ..5)); + assert!(!yes!(5u8, ..5)); + assert!(!yes!(6u8, ..5)); + + // i16; `..X` + const NI16: i16 = core::i16::MIN + 1; + assert!(yes!(core::i16::MIN, ..NI16)); + assert!(yes!(core::i16::MIN, ..5)); + assert!(yes!(-6, ..-5)); + assert!(!yes!(-5, ..-5)); + + // char; `..X` + assert!(yes!('\u{0}', ..'\u{1}')); + assert!(yes!('\u{0}', ..'a')); + assert!(yes!('a', ..'b')); + assert!(!yes!('a', ..'a')); + assert!(!yes!('b', ..'a')); + + // f32; `..X` + assert!(yes!(core::f32::NEG_INFINITY, ..1.0f32)); + assert!(!yes!(1.5f32, ..1.5f32)); + const E32: f32 = 1.5f32 + core::f32::EPSILON; + assert!(yes!(1.5f32, ..E32)); + assert!(!yes!(1.6f32, ..1.5f32)); + + // f64; `..X` + assert!(yes!(core::f64::NEG_INFINITY, ..1.0f64)); + assert!(!yes!(1.5f64, ..1.5f64)); + const E64: f64 = 1.5f64 + core::f64::EPSILON; + assert!(yes!(1.5f64, ..E64)); + assert!(!yes!(1.6f64, ..1.5f64)); +} + +fn range_from() { + // `X..` (`RangeFrom`-equivalent): + //-------------------------------- + + // u8; `X..` + assert!(yes!(core::u8::MIN, core::u8::MIN..)); + assert!(yes!(core::u8::MAX, core::u8::MIN..)); + assert!(!yes!(core::u8::MIN, 1..)); + assert!(!yes!(4, 5..)); + assert!(yes!(5, 5..)); + assert!(yes!(6, 5..)); + assert!(yes!(core::u8::MAX, core::u8::MAX..)); + + // i16; `X..` + assert!(yes!(core::i16::MIN, core::i16::MIN..)); + assert!(yes!(core::i16::MAX, core::i16::MIN..)); + const NI16: i16 = core::i16::MIN + 1; + assert!(!yes!(core::i16::MIN, NI16..)); + assert!(!yes!(-4, 5..)); + assert!(yes!(-4, -4..)); + assert!(yes!(-3, -4..)); + assert!(yes!(core::i16::MAX, core::i16::MAX..)); + + // char; `X..` + assert!(yes!('\u{0}', '\u{0}'..)); + assert!(yes!(core::char::MAX, '\u{0}'..)); + assert!(yes!('a', 'a'..)); + assert!(yes!('b', 'a'..)); + assert!(!yes!('a', 'b'..)); + assert!(yes!(core::char::MAX, core::char::MAX..)); + + // f32; `X..` + assert!(yes!(core::f32::NEG_INFINITY, core::f32::NEG_INFINITY..)); + assert!(yes!(core::f32::INFINITY, core::f32::NEG_INFINITY..)); + assert!(!yes!(core::f32::NEG_INFINITY, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, 1.0f32..)); + assert!(!yes!(1.0f32 - core::f32::EPSILON, 1.0f32..)); + assert!(yes!(1.0f32, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, core::f32::INFINITY..)); + + // f64; `X..` + assert!(yes!(core::f64::NEG_INFINITY, core::f64::NEG_INFINITY..)); + assert!(yes!(core::f64::INFINITY, core::f64::NEG_INFINITY..)); + assert!(!yes!(core::f64::NEG_INFINITY, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, 1.0f64..)); + assert!(!yes!(1.0f64 - core::f64::EPSILON, 1.0f64..)); + assert!(yes!(1.0f64, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, core::f64::INFINITY..)); +} + +fn main() { + range_to_inclusive(); + range_to(); + range_from(); +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs new file mode 100644 index 0000000000000..a663acd2d191c --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs @@ -0,0 +1,32 @@ +// check-pass + +// Test the parsing of half-open ranges. + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match scrutinee { + X.. | 0.. | 'a'.. | 0.0f32.. => {} + ..=X | ...X | ..X => {} + ..=0 | ...0 | ..0 => {} + ..='a' | ...'a' | ..'a' => {} + ..=0.0f32 | ...0.0f32 | ..0.0f32 => {} + } + + macro_rules! mac { + ($e:expr) => { + let ..$e; + let ...$e; + let ..=$e; + let $e..; + let $e...; + let $e..=; + } + } + + mac!(0); +} diff --git a/src/test/ui/half-open-range-patterns/pat-tuple-4.rs b/src/test/ui/half-open-range-patterns/pat-tuple-4.rs new file mode 100644 index 0000000000000..bd795368205fc --- /dev/null +++ b/src/test/ui/half-open-range-patterns/pat-tuple-4.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + const PAT: u8 = 1; + + match 0 { + (.. PAT) => {} + _ => {} + } +} diff --git a/src/test/ui/half-open-range-patterns/pat-tuple-5.rs b/src/test/ui/half-open-range-patterns/pat-tuple-5.rs new file mode 100644 index 0000000000000..613d907cfe329 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/pat-tuple-5.rs @@ -0,0 +1,10 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + const PAT: u8 = 1; + + match (0, 1) { + (PAT ..) => {} //~ ERROR mismatched types + } +} diff --git a/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr new file mode 100644 index 0000000000000..307ad711b74d9 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/pat-tuple-5.rs:8:10 + | +LL | match (0, 1) { + | ------ this expression has type `({integer}, {integer})` +LL | (PAT ..) => {} + | ^^^ expected tuple, found `u8` + | + = note: expected tuple `({integer}, {integer})` + found type `u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-41255.rs b/src/test/ui/issues/issue-41255.rs index 478e13bb177f6..5b95a73791355 100644 --- a/src/test/ui/issues/issue-41255.rs +++ b/src/test/ui/issues/issue-41255.rs @@ -1,6 +1,7 @@ // Matching against float literals should result in a linter error #![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] #![allow(unused)] #![forbid(illegal_floating_point_literal_pattern)] @@ -35,6 +36,22 @@ fn main() { //~| WARNING hard error //~| WARNING hard error //~| WARNING hard error + + ..71.0 => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| WARNING this was previously accepted by the compiler + ..=72.0 => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| WARNING this was previously accepted by the compiler + 71.0.. => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| WARNING this was previously accepted by the compiler _ => {}, }; let y = 5.0; diff --git a/src/test/ui/issues/issue-41255.stderr b/src/test/ui/issues/issue-41255.stderr index 4f24456c169b8..1ff58153c8864 100644 --- a/src/test/ui/issues/issue-41255.stderr +++ b/src/test/ui/issues/issue-41255.stderr @@ -1,11 +1,11 @@ error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:10:9 + --> $DIR/issue-41255.rs:11:9 | LL | 5.0 => {}, | ^^^ | note: lint level defined here - --> $DIR/issue-41255.rs:5:11 + --> $DIR/issue-41255.rs:6:11 | LL | #![forbid(illegal_floating_point_literal_pattern)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![forbid(illegal_floating_point_literal_pattern)] = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:14:9 + --> $DIR/issue-41255.rs:15:9 | LL | 5.0f32 => {}, | ^^^^^^ @@ -22,7 +22,7 @@ LL | 5.0f32 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:18:10 + --> $DIR/issue-41255.rs:19:10 | LL | -5.0 => {}, | ^^^ @@ -31,7 +31,7 @@ LL | -5.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:9 + --> $DIR/issue-41255.rs:23:9 | LL | 1.0 .. 33.0 => {}, | ^^^ @@ -40,7 +40,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:16 + --> $DIR/issue-41255.rs:23:16 | LL | 1.0 .. 33.0 => {}, | ^^^^ @@ -49,7 +49,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:30:9 + --> $DIR/issue-41255.rs:31:9 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -58,7 +58,7 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:30:18 + --> $DIR/issue-41255.rs:31:18 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -67,7 +67,34 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:43:10 + --> $DIR/issue-41255.rs:40:11 + | +LL | ..71.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:45:12 + | +LL | ..=72.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:50:9 + | +LL | 71.0.. => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:60:10 | LL | (3.14, 1) => {}, | ^^^^ @@ -76,7 +103,7 @@ LL | (3.14, 1) => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:52:18 + --> $DIR/issue-41255.rs:69:18 | LL | Foo { x: 2.0 } => {}, | ^^^ @@ -85,7 +112,7 @@ LL | Foo { x: 2.0 } => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:10:9 + --> $DIR/issue-41255.rs:11:9 | LL | 5.0 => {}, | ^^^ @@ -94,7 +121,7 @@ LL | 5.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:14:9 + --> $DIR/issue-41255.rs:15:9 | LL | 5.0f32 => {}, | ^^^^^^ @@ -103,7 +130,7 @@ LL | 5.0f32 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:18:10 + --> $DIR/issue-41255.rs:19:10 | LL | -5.0 => {}, | ^^^ @@ -112,7 +139,7 @@ LL | -5.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:9 + --> $DIR/issue-41255.rs:23:9 | LL | 1.0 .. 33.0 => {}, | ^^^ @@ -121,7 +148,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:22:16 + --> $DIR/issue-41255.rs:23:16 | LL | 1.0 .. 33.0 => {}, | ^^^^ @@ -130,7 +157,7 @@ LL | 1.0 .. 33.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:30:9 + --> $DIR/issue-41255.rs:31:9 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -139,7 +166,7 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:30:18 + --> $DIR/issue-41255.rs:31:18 | LL | 39.0 ..= 70.0 => {}, | ^^^^ @@ -148,7 +175,34 @@ LL | 39.0 ..= 70.0 => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:43:10 + --> $DIR/issue-41255.rs:40:11 + | +LL | ..71.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:45:12 + | +LL | ..=72.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:50:9 + | +LL | 71.0.. => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:60:10 | LL | (3.14, 1) => {}, | ^^^^ @@ -157,7 +211,7 @@ LL | (3.14, 1) => {}, = note: for more information, see issue #41620 error: floating-point types cannot be used in patterns - --> $DIR/issue-41255.rs:52:18 + --> $DIR/issue-41255.rs:69:18 | LL | Foo { x: 2.0 } => {}, | ^^^ @@ -165,5 +219,5 @@ LL | Foo { x: 2.0 } => {}, = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 -error: aborting due to 18 previous errors +error: aborting due to 24 previous errors diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs index f6d2bee0e1560..118bff8144c7f 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs @@ -1,3 +1,5 @@ +#![feature(half_open_range_patterns)] + fn main() {} #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } @@ -90,15 +92,15 @@ fn main() {} // note: requires parens in patterns to allow disambiguation #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } -//~^ ERROR `X..=` range patterns are not supported +//~^ ERROR inclusive range with no end //~| ERROR expected one of `=>`, `if`, or `|`, found `#` #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } -//~^ ERROR `X..=` range patterns are not supported +//~^ ERROR inclusive range with no end //~| ERROR expected one of `=>`, `if`, or `|`, found `#` #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } //~^ ERROR unexpected token: `#` #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } -//~^ ERROR `X..=` range patterns are not supported +//~^ ERROR inclusive range with no end //~| ERROR expected one of `=>`, `if`, or `|`, found `#` #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index 0123006418a3a..654b49ab62022 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -1,5 +1,5 @@ error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:3:36 + --> $DIR/attr-stmt-expr-attr-bad.rs:5:36 | LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } | ^^^^^^^^ @@ -7,19 +7,19 @@ LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected expression, found `]` - --> $DIR/attr-stmt-expr-attr-bad.rs:5:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:7:40 | LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; } | ^ expected expression error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:7:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:9:35 | LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); } | ^ expected one of 7 possible tokens error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:9:36 + --> $DIR/attr-stmt-expr-attr-bad.rs:11:36 | LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | ^^^^^^^^ @@ -27,13 +27,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected expression, found `)` - --> $DIR/attr-stmt-expr-attr-bad.rs:9:44 + --> $DIR/attr-stmt-expr-attr-bad.rs:11:44 | LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | ^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:12:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:14:38 | LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^^^^^^^^ @@ -41,13 +41,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected expression, found `)` - --> $DIR/attr-stmt-expr-attr-bad.rs:12:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:14:46 | LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:15:36 + --> $DIR/attr-stmt-expr-attr-bad.rs:17:36 | LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } | ^^^^^^^^ @@ -55,7 +55,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:17:33 + --> $DIR/attr-stmt-expr-attr-bad.rs:19:33 | LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } | ^^^^^^^^ @@ -63,7 +63,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:19:33 + --> $DIR/attr-stmt-expr-attr-bad.rs:21:33 | LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } | ^^^^^^^^ @@ -71,13 +71,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:21:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:23:34 | LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } | ^ expected one of 7 possible tokens error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:23:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:25:35 | LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } | ^^^^^^^^ @@ -85,7 +85,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:25:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:27:40 | LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } | ^^^^^^^^ @@ -93,7 +93,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:27:35 + --> $DIR/attr-stmt-expr-attr-bad.rs:29:35 | LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } | ^^^^^^^^ @@ -101,7 +101,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:29:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 | LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } | ^^^^^^^^ @@ -109,19 +109,19 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:33:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } | ^^ expected expression error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:33:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:35:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } | ^^ expected expression error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:35:41 + --> $DIR/attr-stmt-expr-attr-bad.rs:37:41 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } | ^^^^^^^^ @@ -129,7 +129,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:37:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:39:45 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } | ^^^^^^^^ @@ -137,13 +137,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: attributes are not yet allowed on `if` expressions - --> $DIR/attr-stmt-expr-attr-bad.rs:39:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:41:32 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if 0 {}; } | ^^^^^^^ error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:41:37 + --> $DIR/attr-stmt-expr-attr-bad.rs:43:37 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } | -- ^ --- help: try placing this code inside a block: `{ {}; }` @@ -152,7 +152,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } | this `if` expression has a condition, but no block error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:43:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:45:38 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } | ^^^^^^^^ @@ -160,13 +160,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:45:40 + --> $DIR/attr-stmt-expr-attr-bad.rs:47:40 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:47:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:49:45 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } | ^ --- help: try placing this code inside a block: `{ {}; }` @@ -174,7 +174,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } | expected `{` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:49:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:51:46 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } | ^^^^^^^^ @@ -182,13 +182,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: attributes are not yet allowed on `if` expressions - --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:53:45 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } | ^^^^^^^ error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:53:45 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } | ^ -------- help: try placing this code inside a block: `{ if 0 {}; }` @@ -196,7 +196,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } | expected `{` error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:54:50 + --> $DIR/attr-stmt-expr-attr-bad.rs:56:50 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } | -- ^ --- help: try placing this code inside a block: `{ {}; }` @@ -205,7 +205,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } | this `if` expression has a condition, but no block error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:56:51 + --> $DIR/attr-stmt-expr-attr-bad.rs:58:51 | LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } | ^^^^^^^^ @@ -213,13 +213,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: attributes are not yet allowed on `if` expressions - --> $DIR/attr-stmt-expr-attr-bad.rs:58:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:60:32 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if let _ = 0 {}; } | ^^^^^^^ error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:60:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:62:45 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } | -- ^ --- help: try placing this code inside a block: `{ {}; }` @@ -228,7 +228,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } | this `if` expression has a condition, but no block error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:62:46 + --> $DIR/attr-stmt-expr-attr-bad.rs:64:46 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } | ^^^^^^^^ @@ -236,13 +236,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:64:48 + --> $DIR/attr-stmt-expr-attr-bad.rs:66:48 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } | ^ expected one of `.`, `;`, `?`, `else`, or an operator error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:66:53 + --> $DIR/attr-stmt-expr-attr-bad.rs:68:53 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } | ^ --- help: try placing this code inside a block: `{ {}; }` @@ -250,7 +250,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } | expected `{` error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:68:54 + --> $DIR/attr-stmt-expr-attr-bad.rs:70:54 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } | ^^^^^^^^ @@ -258,13 +258,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: attributes are not yet allowed on `if` expressions - --> $DIR/attr-stmt-expr-attr-bad.rs:70:53 + --> $DIR/attr-stmt-expr-attr-bad.rs:72:53 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } | ^^^^^^^ error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:70:53 + --> $DIR/attr-stmt-expr-attr-bad.rs:72:53 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } | ^ ---------------- help: try placing this code inside a block: `{ if let _ = 0 {}; }` @@ -272,7 +272,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {} | expected `{` error: expected `{`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:73:66 + --> $DIR/attr-stmt-expr-attr-bad.rs:75:66 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } | -- ^ --- help: try placing this code inside a block: `{ {}; }` @@ -281,7 +281,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {} | this `if` expression has a condition, but no block error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:75:67 + --> $DIR/attr-stmt-expr-attr-bad.rs:77:67 | LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } | ^^^^^^^^ @@ -289,7 +289,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]} = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:78:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:80:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } | ------- ^^^^^^^^ not permitted following an outer attibute @@ -299,7 +299,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:80:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:82:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } | ------- ^^^^^^^^ not permitted following an outer attibute @@ -309,7 +309,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:82:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:84:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } | ------- ^^^^^^^^ not permitted following an outer attibute @@ -319,7 +319,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:84:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:86:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } | ------- ^^^^^^^^ not permitted following an outer attibute @@ -329,7 +329,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:86:32 + --> $DIR/attr-stmt-expr-attr-bad.rs:88:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } | ------- ^^^^^^^^ not permitted following an outer attibute @@ -338,83 +338,90 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. -error: `X..=` range patterns are not supported - --> $DIR/attr-stmt-expr-attr-bad.rs:92:34 +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:94:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } - | ^^^^ help: try using the maximum value for the type: `0..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:92:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:94:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } | ^ expected one of `=>`, `if`, or `|` -error: `X..=` range patterns are not supported - --> $DIR/attr-stmt-expr-attr-bad.rs:95:34 +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:97:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } - | ^^^^ help: try using the maximum value for the type: `0..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:95:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:97:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } | ^ expected one of `=>`, `if`, or `|` error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:98:39 + --> $DIR/attr-stmt-expr-attr-bad.rs:100:39 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } | ^ -error: `X..=` range patterns are not supported - --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:102:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } - | ^^^^ help: try using the maximum value for the type: `0..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:100:38 + --> $DIR/attr-stmt-expr-attr-bad.rs:102:38 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } | ^ expected one of `=>`, `if`, or `|` error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:104:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:106:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } | ^ error: expected one of `.`, `;`, `?`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:104:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:106:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } | ^ expected one of `.`, `;`, `?`, or an operator error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:107:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:109:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } | ^ error: expected one of `.`, `;`, `?`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:107:34 + --> $DIR/attr-stmt-expr-attr-bad.rs:109:34 | LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } | ^ expected one of `.`, `;`, `?`, or an operator error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:112:44 + --> $DIR/attr-stmt-expr-attr-bad.rs:114:44 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } | ^ error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:114:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:116:45 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } | ^ error: aborting due to 57 previous errors +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/parser/issue-63115-range-pat-interpolated.rs b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs index a7d10ca9320a6..8efb3c73f034f 100644 --- a/src/test/ui/parser/issue-63115-range-pat-interpolated.rs +++ b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs @@ -1,6 +1,7 @@ // check-pass #![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] #![allow(ellipsis_inclusive_range_patterns)] @@ -10,6 +11,11 @@ fn main() { if let 2...$e = 3 {} if let 2..=$e = 3 {} if let 2..$e = 3 {} + if let ..$e = 3 {} + if let ..=$e = 3 {} + if let $e.. = 5 {} + if let $e..5 = 4 {} + if let $e..=5 = 4 {} } } mac_expr!(4); diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs index 1730adfa91419..5ec143fae2344 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + // The problem in #66357 was that the call trace: // // - parse_fn_block_decl @@ -11,4 +13,4 @@ fn f() { |[](* } //~^ ERROR expected one of `,` or `:`, found `(` -//~| ERROR expected one of `)`, `-`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` +//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr index 00d84e2afe353..c3810999d2395 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr @@ -1,11 +1,11 @@ error: expected one of `,` or `:`, found `(` - --> $DIR/issue-66357-unexpected-unreachable.rs:12:13 + --> $DIR/issue-66357-unexpected-unreachable.rs:14:13 | LL | fn f() { |[](* } | ^ expected one of `,` or `:` -error: expected one of `)`, `-`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` - --> $DIR/issue-66357-unexpected-unreachable.rs:12:14 +error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` + --> $DIR/issue-66357-unexpected-unreachable.rs:14:14 | LL | fn f() { |[](* } | -^ help: `)` may belong here diff --git a/src/test/ui/parser/pat-tuple-4.rs b/src/test/ui/parser/pat-tuple-4.rs deleted file mode 100644 index 2f03160430a22..0000000000000 --- a/src/test/ui/parser/pat-tuple-4.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn main() { - const PAT: u8 = 0; - - match 0 { - (.. PAT) => {} - //~^ ERROR `..X` range patterns are not supported - //~| ERROR exclusive range pattern syntax is experimental - } -} - -const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr deleted file mode 100644 index 6c64290e144c2..0000000000000 --- a/src/test/ui/parser/pat-tuple-4.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: `..X` range patterns are not supported - --> $DIR/pat-tuple-4.rs:5:10 - | -LL | (.. PAT) => {} - | ^^^^^^ help: try using the minimum value for the type: `MIN..PAT` - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/pat-tuple-4.rs:5:10 - | -LL | (.. PAT) => {} - | ^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/37854 - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - -error[E0308]: mismatched types - --> $DIR/pat-tuple-4.rs:11:30 - | -LL | const RECOVERY_WITNESS: () = 0; - | ^ expected `()`, found integer - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-tuple-5.rs b/src/test/ui/parser/pat-tuple-5.rs deleted file mode 100644 index 5334ef93bb3bd..0000000000000 --- a/src/test/ui/parser/pat-tuple-5.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - const PAT: u8 = 0; - - match (0, 1) { - (PAT ..) => {} - //~^ ERROR `X..` range patterns are not supported - //~| ERROR exclusive range pattern syntax is experimental - //~| ERROR mismatched types - } -} diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr deleted file mode 100644 index 8ff4f948a05ec..0000000000000 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error: `X..` range patterns are not supported - --> $DIR/pat-tuple-5.rs:5:10 - | -LL | (PAT ..) => {} - | ^^^^^^ help: try using the maximum value for the type: `PAT..MAX` - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/pat-tuple-5.rs:5:10 - | -LL | (PAT ..) => {} - | ^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/37854 - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - -error[E0308]: mismatched types - --> $DIR/pat-tuple-5.rs:5:10 - | -LL | match (0, 1) { - | ------ this expression has type `({integer}, {integer})` -LL | (PAT ..) => {} - | ^^^ expected tuple, found `u8` - | - = note: expected tuple `({integer}, {integer})` - found type `u8` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs index 260e108315973..a5aae2861b282 100644 --- a/src/test/ui/parser/recover-range-pats.rs +++ b/src/test/ui/parser/recover-range-pats.rs @@ -4,6 +4,7 @@ // 2. Or at least we have parser recovery if they don't. #![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] #![deny(ellipsis_inclusive_range_patterns)] fn main() {} @@ -55,68 +56,64 @@ fn inclusive2_from_to() { } fn exclusive_from() { - if let 0.. = 0 {} //~ ERROR `X..` range patterns are not supported - if let X.. = 0 {} //~ ERROR `X..` range patterns are not supported - if let true.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let 0.. = 0 {} + if let X.. = 0 {} + if let true.. = 0 {} //~^ ERROR only char and numeric types - if let .0.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let .0.. = 0 {} //~^ ERROR float literals must have an integer part //~| ERROR mismatched types } fn inclusive_from() { - if let 0..= = 0 {} //~ ERROR `X..=` range patterns are not supported - if let X..= = 0 {} //~ ERROR `X..=` range patterns are not supported - if let true..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let 0..= = 0 {} //~ ERROR inclusive range with no end + if let X..= = 0 {} //~ ERROR inclusive range with no end + if let true..= = 0 {} //~ ERROR inclusive range with no end //~| ERROR only char and numeric types - if let .0..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let .0..= = 0 {} //~ ERROR inclusive range with no end //~^ ERROR float literals must have an integer part //~| ERROR mismatched types } fn inclusive2_from() { - if let 0... = 0 {} //~ ERROR `X...` range patterns are not supported - //~^ ERROR `...` range patterns are deprecated - if let X... = 0 {} //~ ERROR `X...` range patterns are not supported - //~^ ERROR `...` range patterns are deprecated - if let true... = 0 {} //~ ERROR `X...` range patterns are not supported - //~^ ERROR `...` range patterns are deprecated + if let 0... = 0 {} //~ ERROR inclusive range with no end + if let X... = 0 {} //~ ERROR inclusive range with no end + if let true... = 0 {} //~ ERROR inclusive range with no end //~| ERROR only char and numeric types - if let .0... = 0 {} //~ ERROR `X...` range patterns are not supported + if let .0... = 0 {} //~ ERROR inclusive range with no end //~^ ERROR float literals must have an integer part - //~| ERROR `...` range patterns are deprecated //~| ERROR mismatched types } fn exclusive_to() { - if let ..0 = 0 {} //~ ERROR `..X` range patterns are not supported - if let ..Y = 0 {} //~ ERROR `..X` range patterns are not supported - if let ..true = 0 {} //~ ERROR `..X` range patterns are not supported - //~| ERROR only char and numeric types - if let .. .0 = 0 {} //~ ERROR `..X` range patterns are not supported + if let ..0 = 0 {} + if let ..Y = 0 {} + if let ..true = 0 {} + //~^ ERROR only char and numeric types + if let .. .0 = 0 {} //~^ ERROR float literals must have an integer part //~| ERROR mismatched types } fn inclusive_to() { - if let ..=3 = 0 {} //~ ERROR `..=X` range patterns are not supported - if let ..=Y = 0 {} //~ ERROR `..=X` range patterns are not supported - if let ..=true = 0 {} //~ ERROR `..=X` range patterns are not supported - //~| ERROR only char and numeric types - if let ..=.0 = 0 {} //~ ERROR `..=X` range patterns are not supported + if let ..=3 = 0 {} + if let ..=Y = 0 {} + if let ..=true = 0 {} + //~^ ERROR only char and numeric types + if let ..=.0 = 0 {} //~^ ERROR float literals must have an integer part //~| ERROR mismatched types } fn inclusive2_to() { - if let ...3 = 0 {} //~ ERROR `...X` range patterns are not supported + if let ...3 = 0 {} //~^ ERROR `...` range patterns are deprecated - if let ...Y = 0 {} //~ ERROR `...X` range patterns are not supported + if let ...Y = 0 {} //~^ ERROR `...` range patterns are deprecated - if let ...true = 0 {} //~ ERROR `...X` range patterns are not supported + if let ...true = 0 {} //~^ ERROR `...` range patterns are deprecated //~| ERROR only char and numeric types - if let ....3 = 0 {} //~ ERROR `...X` range patterns are not supported + if let ....3 = 0 {} //~^ ERROR float literals must have an integer part //~| ERROR `...` range patterns are deprecated //~| ERROR mismatched types @@ -136,14 +133,13 @@ fn with_macro_expr_var() { macro_rules! mac { ($e:expr) => { - let ..$e; //~ ERROR `..X` range patterns are not supported - let ...$e; //~ ERROR `...X` range patterns are not supported - //~^ ERROR `...` range patterns are deprecated - let ..=$e; //~ ERROR `..=X` range patterns are not supported - let $e..; //~ ERROR `X..` range patterns are not supported - let $e...; //~ ERROR `X...` range patterns are not supported + let ..$e; + let ...$e; //~^ ERROR `...` range patterns are deprecated - let $e..=; //~ ERROR `X..=` range patterns are not supported + let ..=$e; + let $e..; + let $e...; //~ ERROR inclusive range with no end + let $e..=; //~ ERROR inclusive range with no end } } diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index 3fed64c191a8a..d3d3169022a65 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -1,377 +1,241 @@ error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:21:12 + --> $DIR/recover-range-pats.rs:22:12 | LL | if let .0..Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:23:16 + --> $DIR/recover-range-pats.rs:24:16 | LL | if let X.. .0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:34:12 + --> $DIR/recover-range-pats.rs:35:12 | LL | if let .0..=Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:36:16 + --> $DIR/recover-range-pats.rs:37:16 | LL | if let X..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:49:12 + --> $DIR/recover-range-pats.rs:50:12 | LL | if let .0...Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:52:17 + --> $DIR/recover-range-pats.rs:53:17 | LL | if let X... .0 = 0 {} | ^^ help: must have an integer part: `0.0` -error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:58:12 - | -LL | if let 0.. = 0 {} - | ^^^ help: try using the maximum value for the type: `0..MAX` - -error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:59:12 - | -LL | if let X.. = 0 {} - | ^^^ help: try using the maximum value for the type: `X..MAX` - -error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:60:12 - | -LL | if let true.. = 0 {} - | ^^^^^^ help: try using the maximum value for the type: `true..MAX` - error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:62:12 + --> $DIR/recover-range-pats.rs:63:12 | LL | if let .0.. = 0 {} | ^^ help: must have an integer part: `0.0` -error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:62:12 - | -LL | if let .0.. = 0 {} - | ^^^^ help: try using the maximum value for the type: `0.0..MAX` - -error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:68:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:69:13 | LL | if let 0..= = 0 {} - | ^^^^ help: try using the maximum value for the type: `0..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:69:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:70:13 | LL | if let X..= = 0 {} - | ^^^^ help: try using the maximum value for the type: `X..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:70:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:71:16 | LL | if let true..= = 0 {} - | ^^^^^^^ help: try using the maximum value for the type: `true..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:72:12 + --> $DIR/recover-range-pats.rs:73:12 | LL | if let .0..= = 0 {} | ^^ help: must have an integer part: `0.0` -error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:72:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:73:14 | LL | if let .0..= = 0 {} - | ^^^^^ help: try using the maximum value for the type: `0.0..=MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:78:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:79:13 | LL | if let 0... = 0 {} - | ^^^^ help: try using the maximum value for the type: `0...MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:80:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:80:13 | LL | if let X... = 0 {} - | ^^^^ help: try using the maximum value for the type: `X...MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:82:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:81:16 | LL | if let true... = 0 {} - | ^^^^^^^ help: try using the maximum value for the type: `true...MAX` + | ^^^ + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:85:12 + --> $DIR/recover-range-pats.rs:83:12 | LL | if let .0... = 0 {} | ^^ help: must have an integer part: `0.0` -error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:85:12 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:83:14 | LL | if let .0... = 0 {} - | ^^^^^ help: try using the maximum value for the type: `0.0...MAX` - -error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:92:12 - | -LL | if let ..0 = 0 {} - | ^^^ help: try using the minimum value for the type: `MIN..0` - -error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:93:12 + | ^^^ | -LL | if let ..Y = 0 {} - | ^^^ help: try using the minimum value for the type: `MIN..Y` - -error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:94:12 - | -LL | if let ..true = 0 {} - | ^^^^^^ help: try using the minimum value for the type: `MIN..true` + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:96:15 + --> $DIR/recover-range-pats.rs:93:15 | LL | if let .. .0 = 0 {} | ^^ help: must have an integer part: `0.0` -error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:96:12 - | -LL | if let .. .0 = 0 {} - | ^^^^^ help: try using the minimum value for the type: `MIN..0.0` - -error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:102:12 - | -LL | if let ..=3 = 0 {} - | ^^^^ help: try using the minimum value for the type: `MIN..=3` - -error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:103:12 - | -LL | if let ..=Y = 0 {} - | ^^^^ help: try using the minimum value for the type: `MIN..=Y` - -error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:104:12 - | -LL | if let ..=true = 0 {} - | ^^^^^^^ help: try using the minimum value for the type: `MIN..=true` - error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:106:15 + --> $DIR/recover-range-pats.rs:103:15 | LL | if let ..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` -error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:106:12 - | -LL | if let ..=.0 = 0 {} - | ^^^^^ help: try using the minimum value for the type: `MIN..=0.0` - -error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:112:12 - | -LL | if let ...3 = 0 {} - | ^^^^ help: try using the minimum value for the type: `MIN...3` - -error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:114:12 - | -LL | if let ...Y = 0 {} - | ^^^^ help: try using the minimum value for the type: `MIN...Y` - -error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:116:12 - | -LL | if let ...true = 0 {} - | ^^^^^^^ help: try using the minimum value for the type: `MIN...true` - error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:119:15 + --> $DIR/recover-range-pats.rs:116:15 | LL | if let ....3 = 0 {} | ^^ help: must have an integer part: `0.3` -error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:119:12 - | -LL | if let ....3 = 0 {} - | ^^^^^ help: try using the minimum value for the type: `MIN...0.3` - -error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:139:17 - | -LL | let ..$e; - | ^^ help: try using the minimum value for the type: `MIN..0` -... -LL | mac!(0); - | -------- in this macro invocation - -error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:140:17 - | -LL | let ...$e; - | ^^^ help: try using the minimum value for the type: `MIN...0` -... -LL | mac!(0); - | -------- in this macro invocation - -error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:142:17 - | -LL | let ..=$e; - | ^^^ help: try using the minimum value for the type: `MIN..=0` -... -LL | mac!(0); - | -------- in this macro invocation - -error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:143:19 - | -LL | let $e..; - | ^^ help: try using the maximum value for the type: `0..MAX` -... -LL | mac!(0); - | -------- in this macro invocation - -error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:144:19 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:141:19 | LL | let $e...; - | ^^^ help: try using the maximum value for the type: `0...MAX` + | ^^^ ... LL | mac!(0); | -------- in this macro invocation + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:146:19 +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:142:19 | LL | let $e..=; - | ^^^ help: try using the maximum value for the type: `0..=MAX` + | ^^^ ... LL | mac!(0); | -------- in this macro invocation + | + = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:41:13 + --> $DIR/recover-range-pats.rs:42:13 | LL | if let 0...3 = 0 {} | ^^^ help: use `..=` for an inclusive range | note: lint level defined here - --> $DIR/recover-range-pats.rs:7:9 + --> $DIR/recover-range-pats.rs:8:9 | LL | #![deny(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:42:13 + --> $DIR/recover-range-pats.rs:43:13 | LL | if let 0...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:43:13 + --> $DIR/recover-range-pats.rs:44:13 | LL | if let X...3 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:44:13 + --> $DIR/recover-range-pats.rs:45:13 | LL | if let X...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:45:16 + --> $DIR/recover-range-pats.rs:46:16 | LL | if let true...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:47:13 + --> $DIR/recover-range-pats.rs:48:13 | LL | if let X...true = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:49:14 + --> $DIR/recover-range-pats.rs:50:14 | LL | if let .0...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:52:13 + --> $DIR/recover-range-pats.rs:53:13 | LL | if let X... .0 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:78:13 - | -LL | if let 0... = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:80:13 - | -LL | if let X... = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:82:16 - | -LL | if let true... = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:85:14 - | -LL | if let .0... = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:112:12 + --> $DIR/recover-range-pats.rs:109:12 | LL | if let ...3 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:114:12 + --> $DIR/recover-range-pats.rs:111:12 | LL | if let ...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:116:12 + --> $DIR/recover-range-pats.rs:113:12 | LL | if let ...true = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:119:12 + --> $DIR/recover-range-pats.rs:116:12 | LL | if let ....3 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:129:20 + --> $DIR/recover-range-pats.rs:126:20 | LL | let $e1...$e2; | ^^^ help: use `..=` for an inclusive range @@ -380,7 +244,7 @@ LL | mac2!(0, 1); | ------------ in this macro invocation error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:140:17 + --> $DIR/recover-range-pats.rs:137:17 | LL | let ...$e; | ^^^ help: use `..=` for an inclusive range @@ -388,17 +252,8 @@ LL | let ...$e; LL | mac!(0); | -------- in this macro invocation -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:144:19 - | -LL | let $e...; - | ^^^ help: use `..=` for an inclusive range -... -LL | mac!(0); - | -------- in this macro invocation - error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:19:12 + --> $DIR/recover-range-pats.rs:20:12 | LL | if let true..Y = 0 {} | ^^^^ - this is of type `u8` @@ -406,7 +261,7 @@ LL | if let true..Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:20:15 + --> $DIR/recover-range-pats.rs:21:15 | LL | if let X..true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -414,7 +269,7 @@ LL | if let X..true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:21:12 + --> $DIR/recover-range-pats.rs:22:12 | LL | if let .0..Y = 0 {} | ^^ - this is of type `u8` @@ -422,7 +277,7 @@ LL | if let .0..Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:23:16 + --> $DIR/recover-range-pats.rs:24:16 | LL | if let X.. .0 = 0 {} | - ^^ - this expression has type `u8` @@ -431,7 +286,7 @@ LL | if let X.. .0 = 0 {} | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:32:12 + --> $DIR/recover-range-pats.rs:33:12 | LL | if let true..=Y = 0 {} | ^^^^ - this is of type `u8` @@ -439,7 +294,7 @@ LL | if let true..=Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:33:16 + --> $DIR/recover-range-pats.rs:34:16 | LL | if let X..=true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -447,7 +302,7 @@ LL | if let X..=true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:34:12 + --> $DIR/recover-range-pats.rs:35:12 | LL | if let .0..=Y = 0 {} | ^^ - this is of type `u8` @@ -455,7 +310,7 @@ LL | if let .0..=Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:36:16 + --> $DIR/recover-range-pats.rs:37:16 | LL | if let X..=.0 = 0 {} | - ^^ - this expression has type `u8` @@ -464,7 +319,7 @@ LL | if let X..=.0 = 0 {} | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:45:12 + --> $DIR/recover-range-pats.rs:46:12 | LL | if let true...Y = 0 {} | ^^^^ - this is of type `u8` @@ -472,7 +327,7 @@ LL | if let true...Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:47:16 + --> $DIR/recover-range-pats.rs:48:16 | LL | if let X...true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -480,7 +335,7 @@ LL | if let X...true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:49:12 + --> $DIR/recover-range-pats.rs:50:12 | LL | if let .0...Y = 0 {} | ^^ - this is of type `u8` @@ -488,7 +343,7 @@ LL | if let .0...Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:52:17 + --> $DIR/recover-range-pats.rs:53:17 | LL | if let X... .0 = 0 {} | - ^^ - this expression has type `u8` @@ -497,78 +352,78 @@ LL | if let X... .0 = 0 {} | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:60:12 + --> $DIR/recover-range-pats.rs:61:12 | LL | if let true.. = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:62:12 + --> $DIR/recover-range-pats.rs:63:12 | LL | if let .0.. = 0 {} | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:70:12 + --> $DIR/recover-range-pats.rs:71:12 | LL | if let true..= = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:72:12 + --> $DIR/recover-range-pats.rs:73:12 | LL | if let .0..= = 0 {} | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:82:12 + --> $DIR/recover-range-pats.rs:81:12 | LL | if let true... = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:85:12 + --> $DIR/recover-range-pats.rs:83:12 | LL | if let .0... = 0 {} | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:94:14 + --> $DIR/recover-range-pats.rs:91:14 | LL | if let ..true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:96:15 + --> $DIR/recover-range-pats.rs:93:15 | LL | if let .. .0 = 0 {} | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:104:15 + --> $DIR/recover-range-pats.rs:101:15 | LL | if let ..=true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:106:15 + --> $DIR/recover-range-pats.rs:103:15 | LL | if let ..=.0 = 0 {} | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:116:15 + --> $DIR/recover-range-pats.rs:113:15 | LL | if let ...true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:119:15 + --> $DIR/recover-range-pats.rs:116:15 | LL | if let ....3 = 0 {} | ^^ expected integer, found floating-point number -error: aborting due to 85 previous errors +error: aborting due to 60 previous errors -Some errors have detailed explanations: E0029, E0308. +Some errors have detailed explanations: E0029, E0308, E0586. For more information about an error, try `rustc --explain E0029`. From 8bd3d240e3fbfe5ad39585faef1fcfb4ae42ac59 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 11:18:47 +0100 Subject: [PATCH 0142/1253] nix syntax::errors & prefer rustc_errors over errors --- Cargo.lock | 1 + src/librustc/Cargo.toml | 2 +- src/librustc/dep_graph/graph.rs | 2 +- src/librustc/hir/check_attr.rs | 2 +- src/librustc/infer/error_reporting/mod.rs | 10 ++++------ .../infer/error_reporting/need_type_info.rs | 12 +++++------ .../nice_region_error/different_lifetimes.rs | 2 +- .../error_reporting/nice_region_error/mod.rs | 2 +- .../nice_region_error/named_anon_conflict.rs | 2 +- .../nice_region_error/placeholder_error.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 2 +- src/librustc/infer/error_reporting/note.rs | 2 +- src/librustc/infer/mod.rs | 2 +- src/librustc/infer/opaque_types/mod.rs | 2 +- src/librustc/lint/builtin.rs | 2 +- src/librustc/lint/context.rs | 2 +- src/librustc/lint/internal.rs | 2 +- src/librustc/lint/levels.rs | 2 +- src/librustc/lint/mod.rs | 2 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/stability.rs | 3 +-- src/librustc/middle/weak_lang_items.rs | 2 +- src/librustc/mir/interpret/error.rs | 2 +- src/librustc/traits/coherence.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/on_unimplemented.rs | 2 +- src/librustc/traits/query/dropck_outlives.rs | 2 +- src/librustc/traits/select.rs | 2 +- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/traits/util.rs | 2 +- src/librustc/ty/context.rs | 4 ++-- src/librustc/ty/error.rs | 4 +--- src/librustc/ty/query/on_disk_cache.rs | 2 +- src/librustc/ty/query/plumbing.rs | 2 +- src/librustc/util/common.rs | 2 +- src/librustc_builtin_macros/Cargo.toml | 2 +- src/librustc_builtin_macros/asm.rs | 2 +- src/librustc_builtin_macros/assert.rs | 2 +- src/librustc_builtin_macros/cfg.rs | 8 ++++---- .../deriving/default.rs | 2 +- src/librustc_builtin_macros/format.rs | 7 ++----- src/librustc_builtin_macros/global_asm.rs | 20 +++++++++---------- .../proc_macro_harness.rs | 4 ++-- src/librustc_builtin_macros/test_harness.rs | 4 ++-- src/librustc_driver/Cargo.toml | 2 +- src/librustc_driver/lib.rs | 14 ++++++------- src/librustc_expand/Cargo.toml | 2 +- src/librustc_expand/base.rs | 13 ++++++------ src/librustc_expand/expand.rs | 5 ++--- src/librustc_expand/lib.rs | 2 +- src/librustc_expand/mbe/macro_parser.rs | 2 +- src/librustc_expand/mbe/macro_rules.rs | 9 +++------ src/librustc_expand/mbe/transcribe.rs | 12 +++++------ src/librustc_expand/parse/lexer/tests.rs | 2 +- src/librustc_expand/parse/tests.rs | 2 +- src/librustc_expand/proc_macro.rs | 7 +++---- src/librustc_expand/proc_macro_server.rs | 17 ++++++++-------- src/librustc_expand/tests.rs | 4 ++-- src/librustc_lint/Cargo.toml | 1 + src/librustc_lint/array_into_iter.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/nonstandard_style.rs | 2 +- src/librustc_lint/redundant_semicolon.rs | 2 +- src/librustc_lint/types.rs | 2 +- src/librustc_lint/unused.rs | 3 +-- src/librustc_metadata/Cargo.toml | 2 +- src/librustc_metadata/creader.rs | 18 ++++++++--------- src/librustc_metadata/locator.rs | 2 +- src/librustc_metadata/native_libs.rs | 2 +- .../borrow_check/diagnostics/region_errors.rs | 3 +-- .../lexer/unescape_error_reporting.rs | 3 +-- src/librustc_passes/Cargo.toml | 2 +- src/librustc_passes/ast_validation.rs | 6 +++--- src/librustc_passes/check_const.rs | 2 +- src/librustc_passes/entry.rs | 2 +- src/librustc_passes/intrinsicck.rs | 2 +- src/librustc_passes/lib_features.rs | 2 +- src/librustc_passes/liveness.rs | 4 ++-- src/librustc_passes/loops.rs | 2 +- src/librustc_passes/stability.rs | 2 +- src/librustc_resolve/Cargo.toml | 6 +++--- src/librustc_resolve/build_reduced_graph.rs | 18 +++++++---------- src/librustc_resolve/check_unused.rs | 2 +- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/imports.rs | 2 +- src/librustc_resolve/late.rs | 6 +++--- src/librustc_resolve/late/diagnostics.rs | 10 +++++----- src/librustc_resolve/lib.rs | 2 +- src/librustc_resolve/lifetimes.rs | 2 +- src/librustc_typeck/Cargo.toml | 2 +- src/librustc_typeck/astconv.rs | 3 +-- src/librustc_typeck/check/autoderef.rs | 2 +- src/librustc_typeck/check/callee.rs | 12 +++++------ src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 2 +- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/expr.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 4 ++-- src/librustc_typeck/check/op.rs | 8 ++++---- src/librustc_typeck/check/pat.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/check_unused.rs | 8 +++----- src/librustc_typeck/coherence/builtin.rs | 2 +- .../coherence/inherent_impls.rs | 2 +- .../coherence/inherent_impls_overlap.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 7 +++---- src/librustc_typeck/coherence/orphan.rs | 2 +- src/librustc_typeck/coherence/unsafety.rs | 2 +- src/librustc_typeck/collect.rs | 4 ++-- src/librustc_typeck/impl_wf_check.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/librustc_typeck/outlives/test.rs | 2 +- src/librustc_typeck/structured_errors.rs | 6 +++--- src/librustc_typeck/variance/test.rs | 2 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/config.rs | 3 +-- src/librustdoc/core.rs | 13 +++++++----- src/librustdoc/docfs.rs | 4 +--- src/librustdoc/externalfiles.rs | 7 +++---- src/librustdoc/html/render.rs | 5 ++--- src/librustdoc/lib.rs | 4 ++-- src/librustdoc/markdown.rs | 5 ++--- .../passes/check_code_block_syntax.rs | 2 +- .../passes/collect_intra_doc_links.rs | 2 +- src/librustdoc/test.rs | 4 ++-- src/librustdoc/theme.rs | 2 +- src/libsyntax/Cargo.toml | 2 +- src/libsyntax/attr/builtin.rs | 2 +- src/libsyntax/attr/mod.rs | 2 +- src/libsyntax/feature_gate/check.rs | 2 +- src/libsyntax/lib.rs | 1 - src/libsyntax/show_span.rs | 4 ++-- 138 files changed, 242 insertions(+), 276 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a2223814918a..40dad13df6b21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3653,6 +3653,7 @@ dependencies = [ "log", "rustc", "rustc_data_structures", + "rustc_errors", "rustc_feature", "rustc_hir", "rustc_index", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 1a04a9d86b58b..21ab5c75c026d 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -26,8 +26,8 @@ rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_index = { path = "../librustc_index" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0d03c834e0f7b..78895340b07c3 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,10 +1,10 @@ use crate::ty::{self, TyCtxt}; -use errors::Diagnostic; use parking_lot::{Condvar, Mutex}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; +use rustc_errors::Diagnostic; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::collections::hash_map::Entry; diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 06b7b3194defd..c6a996f84f461 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -9,8 +9,8 @@ use crate::lint::builtin::UNUSED_ATTRIBUTES; use crate::ty::query::Providers; use crate::ty::TyCtxt; -use errors::struct_span_err; use rustc_error_codes::*; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5e5f39e6c7a22..c52d4335ea184 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -64,15 +64,13 @@ use crate::ty::{ subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable, }; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_error_codes::*; +use rustc_errors::{pluralize, struct_span_err}; +use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::Node; - -use errors::{ - pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString, -}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_error_codes::*; use rustc_span::{DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::{cmp, fmt}; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 16cfaec5ee91b..70f7987faf4cc 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -3,7 +3,7 @@ use crate::infer::type_variable::TypeVariableOriginKind; use crate::infer::InferCtxt; use crate::ty::print::Print; use crate::ty::{self, DefIdTree, Infer, Ty, TyVar}; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -151,12 +151,12 @@ pub enum TypeAnnotationNeeded { E0284, } -impl Into for TypeAnnotationNeeded { - fn into(self) -> errors::DiagnosticId { +impl Into for TypeAnnotationNeeded { + fn into(self) -> rustc_errors::DiagnosticId { match self { - Self::E0282 => errors::error_code!(E0282), - Self::E0283 => errors::error_code!(E0283), - Self::E0284 => errors::error_code!(E0284), + Self::E0282 => rustc_errors::error_code!(E0282), + Self::E0283 => rustc_errors::error_code!(E0283), + Self::E0284 => rustc_errors::error_code!(E0284), } } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index b73fb40f637ed..d6e50209f72dd 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -5,8 +5,8 @@ use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::util::common::ErrorReported; -use errors::struct_span_err; use rustc_error_codes::*; +use rustc_errors::struct_span_err; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when both the concerned regions are anonymous. diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index 5da65a3019395..8749d6cd34bed 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -3,7 +3,7 @@ use crate::infer::lexical_region_resolve::RegionResolutionError::*; use crate::infer::InferCtxt; use crate::ty::{self, TyCtxt}; use crate::util::common::ErrorReported; -use errors::DiagnosticBuilder; +use rustc_errors::DiagnosticBuilder; use rustc_span::source_map::Span; mod different_lifetimes; diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index dacd2025da53b..2344d408a43a5 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -2,7 +2,7 @@ //! where one region is named and the other is anonymous. use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::ty; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::{FunctionRetTy, TyKind}; use rustc_error_codes::*; diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index f276dab5000bc..7b31fe7cd7e4d 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -7,7 +7,7 @@ use crate::ty::error::ExpectedFound; use crate::ty::print::{FmtPrinter, Print, RegionHighlightMode}; use crate::ty::subst::SubstsRef; use crate::ty::{self, TyCtxt}; -use errors::DiagnosticBuilder; +use rustc_errors::DiagnosticBuilder; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 6c78e70a4444d..c6fc4cd3c15f7 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -5,7 +5,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::ty::{BoundRegion, FreeRegion, RegionKind}; use crate::util::common::ErrorReported; -use errors::Applicability; +use rustc_errors::Applicability; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the return type is a static impl Trait. diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index a3fdcb44f996f..6303104e39dd3 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -3,7 +3,7 @@ use crate::infer::{self, InferCtxt, SubregionOrigin}; use crate::middle::region; use crate::ty::error::TypeError; use crate::ty::{self, Region}; -use errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_error_codes::*; diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4eb8d79a067ef..f67669e367f00 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -21,10 +21,10 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use crate::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; use crate::ty::{ConstVid, FloatVid, IntVid, TyVid}; -use errors::DiagnosticBuilder; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::unify as ut; +use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::Symbol; diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 839e8588ff090..a1afb1a86be44 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -6,10 +6,10 @@ use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::free_region_map::FreeRegionRelations; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt}; -use errors::{struct_span_err, DiagnosticBuilder}; use rustc::session::config::nightly_options; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_hir::Node; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3726e6ace54b1..f5845dcae1288 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -7,7 +7,7 @@ use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass}; use crate::middle::stability; use crate::session::Session; -use errors::{pluralize, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_session::declare_lint; use rustc_span::edition::Edition; use rustc_span::source_map::Span; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ea96b15a162aa..bd561b41c57f5 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -25,10 +25,10 @@ use crate::middle::privacy::AccessLevels; use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; -use errors::{struct_span_err, DiagnosticBuilder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; use rustc_error_codes::*; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 69f212a9a3098..7b99b4af4f9ab 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -4,8 +4,8 @@ use crate::lint::{ EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass, }; -use errors::Applicability; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; use rustc_session::declare_tool_lint; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index abd52a9de50d5..6ca98b44bf80c 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -5,9 +5,9 @@ use crate::lint::builtin; use crate::lint::context::{CheckLintNameResult, LintStore}; use crate::lint::{self, Level, Lint, LintId, LintSource}; use crate::session::Session; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::HirId; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 3f43800590353..a8c1f9a664f18 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -23,8 +23,8 @@ pub use self::LintSource::*; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::ty::TyCtxt; -use errors::{DiagnosticBuilder, DiagnosticId}; use rustc_data_structures::sync; +use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; use rustc_session::node_id::NodeMap; use rustc_session::{DiagnosticMessageId, Session}; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6f59df01a5205..42fc3e030e7bb 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -14,8 +14,8 @@ use crate::middle::cstore::ExternCrate; use crate::middle::weak_lang_items; use crate::ty::{self, TyCtxt}; -use errors::struct_span_err; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index f2474faa75e44..93c23e40d2e2b 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -7,8 +7,8 @@ use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::{self, in_derive_expansion, Lint}; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; -use errors::DiagnosticBuilder; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::GateIssue; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -18,7 +18,6 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability}; -use syntax::errors::Applicability; use syntax::feature_gate::feature_err_issue; use std::num::NonZeroU32; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 89f385a51bc6a..fdffd1251ce8f 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -5,8 +5,8 @@ use crate::session::config; use crate::hir::map::Map; use crate::ty::TyCtxt; -use errors::struct_span_err; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index cb11ac49cec35..ed61534d54519 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -7,8 +7,8 @@ use crate::ty::query::TyCtxtAt; use crate::ty::{self, layout, Ty}; use backtrace::Backtrace; -use errors::{struct_span_err, DiagnosticBuilder}; use hir::GeneratorKind; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_macros::HashStable; use rustc_span::symbol::Symbol; diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index db7cda3b95bb2..29ea47809a077 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -38,7 +38,7 @@ pub struct OverlapResult<'tcx> { pub involves_placeholder: bool, } -pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) { +pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) { err.note(&format!( "this behavior recently changed as a result of a bug fix; \ see rust-lang/rust#56105 for details" diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b9bb68798e588..0c9a73d78a5eb 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -21,8 +21,8 @@ use crate::ty::SubtypePredicate; use crate::ty::TypeckTables; use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Node; diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index f1b830e43fc1d..1afe153bb1361 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -3,8 +3,8 @@ use fmt_macros::{Parser, Piece, Position}; use crate::ty::{self, GenericParamDefKind, TyCtxt}; use crate::util::common::ErrorReported; -use errors::struct_span_err; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 370acb53896d3..34866b684de01 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -76,7 +76,7 @@ pub struct DropckOutlivesResult<'tcx> { impl<'tcx> DropckOutlivesResult<'tcx> { pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) { if let Some(overflow_ty) = self.overflows.iter().next() { - errors::struct_span_err!( + rustc_errors::struct_span_err!( tcx.sess, span, E0320, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 1b1cb1b36e09a..8b66f4926e0c8 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -102,7 +102,7 @@ pub enum IntercrateAmbiguityCause { impl IntercrateAmbiguityCause { /// Emits notes when the overlap is caused by complex intercrate ambiguities. /// See #23980 for details. - pub fn add_intercrate_ambiguity_hint(&self, err: &mut errors::DiagnosticBuilder<'_>) { + pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) { err.note(&self.intercrate_ambiguity_hint()); } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index d189714883845..7b66341ef1c96 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -17,8 +17,8 @@ use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::{self, TyCtxt, TypeFoldable}; -use errors::struct_span_err; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; use rustc_span::DUMMY_SP; diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 8355239af87a4..65fd809657bd0 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -1,4 +1,4 @@ -use errors::DiagnosticBuilder; +use rustc_errors::DiagnosticBuilder; use rustc_span::Span; use smallvec::SmallVec; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 17f5b98ab208b..1b0b5fc4d078d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -51,7 +51,6 @@ use rustc_hir::{HirId, Node, TraitCandidate}; use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; use arena::SyncDroplessArena; -use errors::DiagnosticBuilder; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::ShardedHashMap; @@ -59,6 +58,7 @@ use rustc_data_structures::stable_hasher::{ hash_stable_hashmap, HashStable, StableHasher, StableVec, }; use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal}; +use rustc_errors::DiagnosticBuilder; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_session::node_id::NodeMap; @@ -1613,10 +1613,10 @@ pub mod tls { use crate::dep_graph::TaskDeps; use crate::ty::query; - use errors::Diagnostic; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::OnDrop; + use rustc_errors::Diagnostic; use std::mem; #[cfg(not(parallel_compiler))] diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 25fc484cd5301..f7612874e05b6 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -1,12 +1,10 @@ use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt}; +use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; - -use errors::{Applicability, DiagnosticBuilder}; use rustc_span::Span; use rustc_target::spec::abi; use syntax::ast; -use syntax::errors::pluralize; use std::borrow::Cow; use std::fmt; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 5d968811addd8..a81fe33831c96 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -7,10 +7,10 @@ use crate::session::{CrateDisambiguator, Session}; use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; use crate::ty::context::TyCtxt; use crate::ty::{self, Ty}; -use errors::Diagnostic; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, Once}; use rustc_data_structures::thin_vec::ThinVec; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_index::vec::{Idx, IndexVec}; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 35608540383b0..49028107df758 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -9,13 +9,13 @@ use crate::ty::query::Query; use crate::ty::tls; use crate::ty::{self, TyCtxt}; -use errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, Handler, Level}; #[cfg(not(parallel_compiler))] use rustc_data_structures::cold_path; use rustc_data_structures::fx::{FxHashMap, FxHasher}; use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::thin_vec::ThinVec; +use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, Handler, Level}; use rustc_span::source_map::DUMMY_SP; use rustc_span::Span; use std::collections::hash_map::Entry; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 9324b26a09b6f..19b43bfd16241 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -8,7 +8,7 @@ use std::time::{Duration, Instant}; #[cfg(test)] mod tests; -pub use errors::ErrorReported; +pub use rustc_errors::ErrorReported; pub fn to_readable_str(mut val: usize) -> String { let mut groups = vec![]; diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index f56cc938f4a2f..ca57068fb9a33 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -10,10 +10,10 @@ path = "lib.rs" doctest = false [dependencies] -errors = { path = "../librustc_errors", package = "rustc_errors" } fmt_macros = { path = "../libfmt_macros" } log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_parse = { path = "../librustc_parse" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs index 78d2d37ef56d3..a6b45e0567c72 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/src/librustc_builtin_macros/asm.rs @@ -2,7 +2,7 @@ // use State::*; -use errors::{struct_span_err, DiagnosticBuilder, PResult}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult}; use rustc_expand::base::*; use rustc_parse::parser::Parser; use rustc_span::symbol::{kw, sym, Symbol}; diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs index 9043db4742bf7..c96ba516f0ced 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/src/librustc_builtin_macros/assert.rs @@ -1,4 +1,4 @@ -use errors::{Applicability, DiagnosticBuilder}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_expand::base::*; use rustc_parse::parser::Parser; diff --git a/src/librustc_builtin_macros/cfg.rs b/src/librustc_builtin_macros/cfg.rs index 62a4dc06b1fe2..cee62a54f0088 100644 --- a/src/librustc_builtin_macros/cfg.rs +++ b/src/librustc_builtin_macros/cfg.rs @@ -1,8 +1,8 @@ -/// The compiler code necessary to support the cfg! extension, which expands to -/// a literal `true` or `false` based on whether the given cfg matches the -/// current compilation environment. -use errors::DiagnosticBuilder; +//! The compiler code necessary to support the cfg! extension, which expands to +//! a literal `true` or `false` based on whether the given cfg matches the +//! current compilation environment. +use rustc_errors::DiagnosticBuilder; use rustc_expand::base::{self, *}; use rustc_span::Span; use syntax::ast; diff --git a/src/librustc_builtin_macros/deriving/default.rs b/src/librustc_builtin_macros/deriving/default.rs index 8d3f195137375..72c41ad9745c1 100644 --- a/src/librustc_builtin_macros/deriving/default.rs +++ b/src/librustc_builtin_macros/deriving/default.rs @@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use errors::struct_span_err; +use rustc_errors::struct_span_err; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index e2662faab6cb5..6fca74e223944 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -3,10 +3,8 @@ use Position::*; use fmt_macros as parse; -use errors::pluralize; -use errors::Applicability; -use errors::DiagnosticBuilder; - +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_expand::base::{self, *}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; @@ -15,7 +13,6 @@ use syntax::ptr::P; use syntax::token; use syntax::tokenstream::TokenStream; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::collections::hash_map::Entry; diff --git a/src/librustc_builtin_macros/global_asm.rs b/src/librustc_builtin_macros/global_asm.rs index 2bcd76e669971..052e62ee9ffd3 100644 --- a/src/librustc_builtin_macros/global_asm.rs +++ b/src/librustc_builtin_macros/global_asm.rs @@ -1,14 +1,14 @@ -/// Module-level assembly support. -/// -/// The macro defined here allows you to specify "top-level", -/// "file-scoped", or "module-level" assembly. These synonyms -/// all correspond to LLVM's module-level inline assembly instruction. -/// -/// For example, `global_asm!("some assembly here")` codegens to -/// LLVM's `module asm "some assembly here"`. All of LLVM's caveats -/// therefore apply. -use errors::DiagnosticBuilder; +//! Module-level assembly support. +//! +//! The macro defined here allows you to specify "top-level", +//! "file-scoped", or "module-level" assembly. These synonyms +//! all correspond to LLVM's module-level inline assembly instruction. +//! +//! For example, `global_asm!("some assembly here")` codegens to +//! LLVM's `module asm "some assembly here"`. All of LLVM's caveats +//! therefore apply. +use rustc_errors::DiagnosticBuilder; use rustc_expand::base::{self, *}; use rustc_span::source_map::respan; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index 44968d6df9693..ae70608505130 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -40,7 +40,7 @@ enum ProcMacro { struct CollectProcMacros<'a> { macros: Vec, in_root: bool, - handler: &'a errors::Handler, + handler: &'a rustc_errors::Handler, is_proc_macro_crate: bool, is_test_crate: bool, } @@ -53,7 +53,7 @@ pub fn inject( has_proc_macro_decls: bool, is_test_crate: bool, num_crate_types: usize, - handler: &errors::Handler, + handler: &rustc_errors::Handler, ) -> ast::Crate { let ecfg = ExpansionConfig::default("proc_macro".to_string()); let mut cx = ExtCtxt::new(sess, ecfg, resolver); diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index eddf492720336..17d180da6bfda 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -40,7 +40,7 @@ pub fn inject( resolver: &mut dyn Resolver, should_test: bool, krate: &mut ast::Crate, - span_diagnostic: &errors::Handler, + span_diagnostic: &rustc_errors::Handler, features: &Features, panic_strategy: PanicStrategy, platform_panic_strategy: PanicStrategy, @@ -351,7 +351,7 @@ fn is_test_case(i: &ast::Item) -> bool { attr::contains_name(&i.attrs, sym::rustc_test_marker) } -fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option { +fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option { let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?; test_attr.meta_item_list().map(|meta_list| { if meta_list.len() != 1 { diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 5e0c853ed2473..37449f9402eff 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -17,7 +17,7 @@ rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_lint = { path = "../librustc_lint" } rustc_data_structures = { path = "../librustc_data_structures" } -errors = { path = "../librustc_errors", package = "rustc_errors" } +rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a5277bcd120ed..a1318d3506711 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -24,7 +24,6 @@ extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; //use rustc_resolve as resolve; -use errors::{registry::Registry, PResult}; use rustc::lint; use rustc::lint::Lint; use rustc::middle::cstore::MetadataLoader; @@ -37,6 +36,7 @@ use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::profiling::print_time_passes_entry; use rustc_data_structures::sync::SeqCst; +use rustc_errors::{registry::Registry, PResult}; use rustc_feature::{find_gated_cfg, UnstableFeatures}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::get_builtin_codegen_backend; @@ -1134,7 +1134,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { /// the panic into a `Result` instead. pub fn catch_fatal_errors R, R>(f: F) -> Result { catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { - if value.is::() { + if value.is::() { ErrorReported } else { panic::resume_unwind(value); @@ -1163,20 +1163,20 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Separate the output with an empty line eprintln!(); - let emitter = Box::new(errors::emitter::EmitterWriter::stderr( - errors::ColorConfig::Auto, + let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( + rustc_errors::ColorConfig::Auto, None, false, false, None, false, )); - let handler = errors::Handler::with_emitter(true, None, emitter); + let handler = rustc_errors::Handler::with_emitter(true, None, emitter); // a .span_bug or .bug call has already printed what // it wants to print. - if !info.payload().is::() { - let d = errors::Diagnostic::new(errors::Level::Bug, "unexpected panic"); + if !info.payload().is::() { + let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); handler.emit_diagnostic(&d); } diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index f9c15fbed362f..c23846063c1dc 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -14,8 +14,8 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" rustc_span = { path = "../librustc_span" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } rustc_parse = { path = "../librustc_parse" } diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index fe08c85249a2e..52ba14dbc3df0 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1,9 +1,15 @@ use crate::expand::{self, AstFragment, Invocation}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::{self, Lrc}; +use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_parse::{self, parser, DirectoryOwnership, MACRO_ARGUMENTS}; use rustc_span::edition::Edition; +use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::{FileName, MultiSpan, Span, DUMMY_SP}; +use smallvec::{smallvec, SmallVec}; use syntax::ast::{self, Attribute, Name, NodeId, PatKind}; use syntax::attr::{self, Deprecation, HasAttrs, Stability}; use syntax::mut_visit::{self, MutVisitor}; @@ -13,13 +19,6 @@ use syntax::token; use syntax::tokenstream::{self, TokenStream}; use syntax::visit::Visitor; -use errors::{DiagnosticBuilder, DiagnosticId}; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::{self, Lrc}; -use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind}; -use rustc_span::{FileName, MultiSpan, Span, DUMMY_SP}; -use smallvec::{smallvec, SmallVec}; - use std::default::Default; use std::iter; use std::path::PathBuf; diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 6eead11ccb7ba..8426391a2f389 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -5,6 +5,8 @@ use crate::mbe::macro_rules::annotate_err_with_kind; use crate::placeholders::{placeholder, PlaceholderExpander}; use crate::proc_macro::collect_derives; +use rustc_data_structures::sync::Lrc; +use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; use rustc_parse::configure; use rustc_parse::parser::Parser; @@ -26,10 +28,7 @@ use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::util::map_in_place::MapInPlace; use syntax::visit::{self, Visitor}; -use errors::{Applicability, FatalError, PResult}; use smallvec::{smallvec, SmallVec}; - -use rustc_data_structures::sync::Lrc; use std::io::ErrorKind; use std::ops::DerefMut; use std::path::PathBuf; diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs index feba7f633ed80..4fe7c268c4f0b 100644 --- a/src/librustc_expand/lib.rs +++ b/src/librustc_expand/lib.rs @@ -13,7 +13,7 @@ extern crate proc_macro as pm; #[macro_export] macro_rules! panictry { ($e:expr) => {{ - use errors::FatalError; + use rustc_errors::FatalError; use std::result::Result::{Err, Ok}; match $e { Ok(e) => e, diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index c0e34a30c54e9..441c1b75a7c73 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -85,7 +85,7 @@ use syntax::sess::ParseSess; use syntax::token::{self, DocComment, Nonterminal, Token}; use syntax::tokenstream::TokenStream; -use errors::{FatalError, PResult}; +use rustc_errors::{FatalError, PResult}; use rustc_span::Span; use smallvec::{smallvec, SmallVec}; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 6e965346d30e9..d72317af9eb67 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -8,6 +8,9 @@ use crate::mbe::macro_parser::{Error, Failure, Success}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; use crate::mbe::transcribe::transcribe; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; +use rustc_errors::{Applicability, DiagnosticBuilder, FatalError}; use rustc_feature::Features; use rustc_parse::parser::Parser; use rustc_parse::Directory; @@ -22,17 +25,11 @@ use syntax::sess::ParseSess; use syntax::token::{self, NtTT, Token, TokenKind::*}; use syntax::tokenstream::{DelimSpan, TokenStream}; -use errors::{DiagnosticBuilder, FatalError}; use log::debug; - -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::{mem, slice}; -use errors::Applicability; - const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ `literal`, `path`, `meta`, `tt`, `item` and `vis`"; diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs index 4fd68a80de81d..104a5233c9d8c 100644 --- a/src/librustc_expand/mbe/transcribe.rs +++ b/src/librustc_expand/mbe/transcribe.rs @@ -2,19 +2,17 @@ use crate::base::ExtCtxt; use crate::mbe; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; +use rustc_errors::pluralize; +use rustc_span::hygiene::{ExpnId, Transparency}; +use rustc_span::Span; use syntax::ast::{Ident, Mac}; use syntax::mut_visit::{self, MutVisitor}; use syntax::token::{self, NtTT, Token}; use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use smallvec::{smallvec, SmallVec}; - -use errors::pluralize; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; -use rustc_span::hygiene::{ExpnId, Transparency}; -use rustc_span::Span; - use std::mem; // A Marker adds the given mark to the syntax context. diff --git a/src/librustc_expand/parse/lexer/tests.rs b/src/librustc_expand/parse/lexer/tests.rs index 835f0b0108ead..2ef81d80a1412 100644 --- a/src/librustc_expand/parse/lexer/tests.rs +++ b/src/librustc_expand/parse/lexer/tests.rs @@ -1,4 +1,5 @@ use rustc_data_structures::sync::Lrc; +use rustc_errors::{emitter::EmitterWriter, Handler}; use rustc_parse::lexer::StringReader; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::symbol::Symbol; @@ -8,7 +9,6 @@ use syntax::token::{self, Token, TokenKind}; use syntax::util::comments::is_doc_comment; use syntax::with_default_globals; -use errors::{emitter::EmitterWriter, Handler}; use std::io; use std::path::PathBuf; diff --git a/src/librustc_expand/parse/tests.rs b/src/librustc_expand/parse/tests.rs index 25cd5dabe57ec..b79e2894126dd 100644 --- a/src/librustc_expand/parse/tests.rs +++ b/src/librustc_expand/parse/tests.rs @@ -1,6 +1,6 @@ use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; -use errors::PResult; +use rustc_errors::PResult; use rustc_parse::new_parser_from_source_str; use rustc_span::source_map::FilePathMapping; use rustc_span::symbol::{kw, sym, Symbol}; diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs index 25e2bbb34678e..cb6249e936976 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/src/librustc_expand/proc_macro.rs @@ -1,15 +1,14 @@ use crate::base::{self, *}; use crate::proc_macro_server; +use rustc_data_structures::sync::Lrc; +use rustc_errors::{Applicability, FatalError}; use rustc_span::symbol::sym; +use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, ItemKind, MetaItemKind, NestedMetaItem}; -use syntax::errors::{Applicability, FatalError}; use syntax::token; use syntax::tokenstream::{self, TokenStream}; -use rustc_data_structures::sync::Lrc; -use rustc_span::{Span, DUMMY_SP}; - const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread; pub struct BangProcMacro { diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index cf5749f506856..d441613ac58f4 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -1,5 +1,7 @@ use crate::base::ExtCtxt; +use rustc_data_structures::sync::Lrc; +use rustc_errors::Diagnostic; use rustc_parse::lexer::nfc_normalize; use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -11,9 +13,6 @@ use syntax::token; use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; use syntax::util::comments; -use errors::Diagnostic; -use rustc_data_structures::sync::Lrc; - use pm::bridge::{server, TokenTree}; use pm::{Delimiter, Level, LineColumn, Spacing}; use std::ops::Bound; @@ -265,13 +264,13 @@ impl ToInternal for TokenTree { } } -impl ToInternal for Level { - fn to_internal(self) -> errors::Level { +impl ToInternal for Level { + fn to_internal(self) -> rustc_errors::Level { match self { - Level::Error => errors::Level::Error, - Level::Warning => errors::Level::Warning, - Level::Note => errors::Level::Note, - Level::Help => errors::Level::Help, + Level::Error => rustc_errors::Level::Error, + Level::Warning => rustc_errors::Level::Warning, + Level::Note => rustc_errors::Level::Note, + Level::Help => rustc_errors::Level::Help, _ => unreachable!("unknown proc_macro::Level variant: {:?}", self), } } diff --git a/src/librustc_expand/tests.rs b/src/librustc_expand/tests.rs index 18dc605c9e754..82ab74ac15004 100644 --- a/src/librustc_expand/tests.rs +++ b/src/librustc_expand/tests.rs @@ -6,9 +6,9 @@ use syntax::sess::ParseSess; use syntax::tokenstream::TokenStream; use syntax::with_default_globals; -use errors::emitter::EmitterWriter; -use errors::{Handler, PResult}; use rustc_data_structures::sync::Lrc; +use rustc_errors::emitter::EmitterWriter; +use rustc_errors::{Handler, PResult}; use std::io; use std::io::prelude::*; diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 5ca8fc97ac422..7e23e70577975 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" log = "0.4" unicode-security = "0.0.2" rustc = { path = "../librustc" } +rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 46202cda16d50..d8ddf7435b458 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -2,9 +2,9 @@ use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass}; use rustc::lint::FutureIncompatibleInfo; use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_span::symbol::sym; -use syntax::errors::Applicability; declare_lint! { pub ARRAY_INTO_ITER, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 23740af525971..b77dea463f96f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -31,6 +31,7 @@ use rustc::lint::FutureIncompatibleInfo; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::Stability; use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; use rustc_hir as hir; @@ -44,7 +45,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, Span}; use syntax::ast::{self, Expr}; use syntax::attr::{self, HasAttrs}; -use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::{self, expr_to_string}; use syntax::ptr::P; use syntax::tokenstream::{TokenStream, TokenTree}; diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 13e57ecf1469c..7e5ad0976989e 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -2,6 +2,7 @@ use lint::{EarlyContext, LateContext, LintArray, LintContext}; use lint::{EarlyLintPass, LateLintPass, LintPass}; use rustc::lint; use rustc::ty; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::FnKind; @@ -11,7 +12,6 @@ use rustc_span::{symbol::Ident, BytePos, Span}; use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; -use syntax::errors::Applicability; #[derive(PartialEq)] pub enum MethodLateContext { diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index 8dbf96a155825..9fc147f2a0c5a 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,6 +1,6 @@ use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc_errors::Applicability; use syntax::ast::{ExprKind, Stmt, StmtKind}; -use syntax::errors::Applicability; declare_lint! { pub REDUNDANT_SEMICOLON, diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f740bdb271619..f128e25f35bf2 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -9,6 +9,7 @@ use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{is_range_literal, ExprKind, Node}; use rustc_index::vec::Idx; @@ -16,7 +17,6 @@ use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi::Abi; -use syntax::errors::Applicability; use syntax::{ast, attr}; use log::debug; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 184651e3ad564..d57f565d919be 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -5,17 +5,16 @@ use rustc::lint::builtin::UNUSED_ATTRIBUTES; use rustc::ty::adjustment; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{pluralize, Applicability}; use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; - use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; use syntax::ast; use syntax::attr; -use syntax::errors::{pluralize, Applicability}; use syntax::print::pprust; use syntax::util::parser; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index d998e82d4890b..48767c377a94c 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -16,8 +16,8 @@ memmap = "0.7" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } rustc_index = { path = "../librustc_index" } rustc_serialize = { path = "../libserialize", package = "serialize" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 30d049d143eab..17c2e3303cb56 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,25 +12,23 @@ use rustc::session::{CrateDisambiguator, Session}; use rustc::ty::TyCtxt; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; +use rustc_error_codes::*; +use rustc_errors::struct_span_err; +use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_index::vec::IndexVec; -use rustc_target::spec::{PanicStrategy, TargetTriple}; - -use std::path::Path; -use std::{cmp, fs}; - -use errors::struct_span_err; -use log::{debug, info, log_enabled}; -use proc_macro::bridge::client::ProcMacro; -use rustc_expand::base::SyntaxExtension; use rustc_span::edition::Edition; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::spec::{PanicStrategy, TargetTriple}; use syntax::ast; use syntax::attr; use syntax::expand::allocator::{global_allocator_spans, AllocatorKind}; -use rustc_error_codes::*; +use log::{debug, info, log_enabled}; +use proc_macro::bridge::client::ProcMacro; +use std::path::Path; +use std::{cmp, fs}; #[derive(Clone)] pub struct CStore { diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 9f9a2187eced8..4745ad02a3aa4 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -215,7 +215,6 @@ use crate::creader::Library; use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER}; -use errors::{struct_span_err, DiagnosticBuilder}; use rustc::middle::cstore::{CrateSource, MetadataLoader}; use rustc::session::filesearch::{FileDoesntMatch, FileMatches, FileSearch}; use rustc::session::search_paths::PathKind; @@ -223,6 +222,7 @@ use rustc::session::{config, CrateDisambiguator, Session}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use rustc_target::spec::{Target, TargetTriple}; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index c9f47475af851..ae67efb966c96 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -1,9 +1,9 @@ -use errors::struct_span_err; use rustc::middle::cstore::{self, NativeLibrary}; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashSet; use rustc_error_codes::*; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::source_map::Span; diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 9a301a6ad32a8..dc63fa80275e1 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -6,13 +6,12 @@ use rustc::infer::{ }; use rustc::mir::{Body, ConstraintCategory, Location}; use rustc::ty::{self, RegionVid, Ty}; -use rustc_errors::DiagnosticBuilder; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_index::vec::IndexVec; use rustc_span::symbol::kw; use rustc_span::Span; use std::collections::VecDeque; -use syntax::errors::Applicability; use crate::util::borrowck_errors; diff --git a/src/librustc_parse/lexer/unescape_error_reporting.rs b/src/librustc_parse/lexer/unescape_error_reporting.rs index 151c63a49b57c..88762dabd8a29 100644 --- a/src/librustc_parse/lexer/unescape_error_reporting.rs +++ b/src/librustc_parse/lexer/unescape_error_reporting.rs @@ -3,11 +3,10 @@ use std::iter::once; use std::ops::Range; +use rustc_errors::{Applicability, Handler}; use rustc_lexer::unescape::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; -use syntax::errors::{Applicability, Handler}; - pub(crate) fn emit_unescape_error( handler: &Handler, // interior part of the literal, without quotes diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index ced933ba3ee42..4adc6dabb9fdb 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" log = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } @@ -19,5 +20,4 @@ rustc_parse = { path = "../librustc_parse" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 724d717304c20..b68687009da59 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -6,10 +6,10 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. -use errors::{struct_span_err, Applicability, FatalError}; use rustc::lint; use rustc::session::Session; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; @@ -158,7 +158,7 @@ impl<'a> AstValidator<'a> { } } - fn err_handler(&self) -> &errors::Handler { + fn err_handler(&self) -> &rustc_errors::Handler { &self.session.diagnostic() } @@ -409,7 +409,7 @@ enum GenericPosition { fn validate_generics_order<'a>( sess: &Session, - handler: &errors::Handler, + handler: &rustc_errors::Handler, generics: impl Iterator, Span, Option)>, pos: GenericPosition, span: Span, diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index 47e6e5ccc24fe..a2944918a4748 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -7,12 +7,12 @@ //! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips //! through, but errors for structured control flow in a `const` should be emitted here. -use errors::struct_span_err; use rustc::hir::map::Map; use rustc::session::config::nightly_options; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_error_codes::*; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs index 8273504715dba..028d7c662758a 100644 --- a/src/librustc_passes/entry.rs +++ b/src/librustc_passes/entry.rs @@ -1,9 +1,9 @@ -use errors::struct_span_err; use rustc::hir::map as hir_map; use rustc::session::config::EntryFnType; use rustc::session::{config, Session}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{HirId, ImplItem, Item, ItemKind, TraitItem}; diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs index ae8ac2e2c2e35..2c26707a51850 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -1,8 +1,8 @@ -use errors::struct_span_err; use rustc::hir::map::Map; use rustc::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; use rustc::ty::query::Providers; use rustc::ty::{self, Ty, TyCtxt}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs index e7d490d6d8ddb..8ae7291289786 100644 --- a/src/librustc_passes/lib_features.rs +++ b/src/librustc_passes/lib_features.rs @@ -4,11 +4,11 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use errors::struct_span_err; use rustc::hir::map::Map; use rustc::middle::lib_features::LibFeatures; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_span::symbol::Symbol; diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 5c1bc4d1eaa87..0426f3fbea236 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -96,12 +96,12 @@ use self::LiveNodeKind::*; use self::VarKind::*; -use errors::Applicability; use rustc::hir::map::Map; use rustc::lint; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::DefId; @@ -1064,7 +1064,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { .sess .struct_span_err(expr.span, "`break` to unknown label") .emit(); - errors::FatalError.raise() + rustc_errors::FatalError.raise() } } } diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 333b39c3bb302..5ad5795c777d4 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -2,10 +2,10 @@ use Context::*; use rustc::session::Session; -use errors::{struct_span_err, Applicability}; use rustc::hir::map::Map; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index be098543a2ff2..588386e6f8d69 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -1,7 +1,6 @@ //! A pass that annotates every item and method with its stability level, //! propagating default levels lexically from parent to children ast nodes. -use errors::struct_span_err; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::privacy::AccessLevels; @@ -11,6 +10,7 @@ use rustc::traits::misc::can_type_implement_copy; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 01e5d75d2b57d..af37e7b5b76ac 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -14,16 +14,16 @@ doctest = false bitflags = "1.2.1" log = "0.4" syntax = { path = "../libsyntax" } -rustc_expand = { path = "../librustc_expand" } arena = { path = "../libarena" } -errors = { path = "../librustc_errors", package = "rustc_errors" } -rustc_span = { path = "../librustc_span" } rustc = { path = "../librustc" } rustc_ast_lowering = { path = "../librustc_ast_lowering" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } +rustc_expand = { path = "../librustc_expand" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_metadata = { path = "../librustc_metadata" } rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } +rustc_span = { path = "../librustc_span" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 6472f39e844a1..291386413d647 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -20,18 +20,14 @@ use rustc::bug; use rustc::hir::exports::Export; use rustc::middle::cstore::CrateStore; use rustc::ty; -use rustc_hir::def::{self, *}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc_metadata::creader::LoadedMacro; - use rustc_data_structures::sync::Lrc; -use std::cell::Cell; -use std::ptr; - -use errors::{struct_span_err, Applicability}; - +use rustc_error_codes::*; +use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::SyntaxExtension; use rustc_expand::expand::AstFragment; +use rustc_hir::def::{self, *}; +use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_metadata::creader::LoadedMacro; use rustc_span::hygiene::{ExpnId, MacroKind}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym}; @@ -44,8 +40,8 @@ use syntax::token::{self, Token}; use syntax::visit::{self, Visitor}; use log::debug; - -use rustc_error_codes::*; +use std::cell::Cell; +use std::ptr; type Res = def::Res; diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 6561072a21bce..d6f365fce7929 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -26,9 +26,9 @@ use crate::imports::ImportDirectiveSubclass; use crate::Resolver; -use errors::pluralize; use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::pluralize; use rustc_session::node_id::NodeMap; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use syntax::ast; diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b81e71f0acfd7..9942804909380 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1,11 +1,11 @@ use std::cmp::Reverse; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; use log::debug; use rustc::bug; use rustc::session::Session; use rustc::ty::{self, DefIdTree}; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 72de895f350f8..813e6ac96911e 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -11,7 +11,6 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak}; use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; -use errors::{pluralize, struct_span_err, Applicability}; use rustc::hir::exports::Export; use rustc::lint::builtin::BuiltinLintDiagnostics; use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS}; @@ -20,6 +19,7 @@ use rustc::ty; use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; +use rustc_errors::{pluralize, struct_span_err, Applicability}; use rustc_hir::def::{self, PartialRes}; use rustc_hir::def_id::DefId; use rustc_span::hygiene::ExpnId; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 29a1be6bb7461..defca4944bcd8 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -11,10 +11,9 @@ use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding}; use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; -use errors::DiagnosticId; -use log::debug; use rustc::{bug, lint, span_bug}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; @@ -28,6 +27,7 @@ use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit::{self, FnKind, Visitor}; use syntax::{unwrap_or, walk_list}; +use log::debug; use std::collections::BTreeSet; use std::mem::replace; @@ -306,7 +306,7 @@ impl<'a> PathSource<'a> { } fn error_code(self, has_unexpected_resolution: bool) -> DiagnosticId { - use errors::error_code; + use rustc_errors::error_code; match (self, has_unexpected_resolution) { (PathSource::Trait(_), true) => error_code!(E0404), (PathSource::Trait(_), false) => error_code!(E0405), diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 029f8421475e5..151f3e834e5de 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -4,10 +4,10 @@ use crate::path_names_to_string; use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; -use errors::{Applicability, DiagnosticBuilder}; -use log::debug; use rustc::session::config::nightly_options; use rustc_data_structures::fx::FxHashSet; +use rustc_error_codes::*; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; @@ -18,7 +18,7 @@ use rustc_span::Span; use syntax::ast::{self, Expr, ExprKind, Ident, NodeId, Path, Ty, TyKind}; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_error_codes::*; +use log::debug; type Res = def::Res; @@ -139,7 +139,7 @@ impl<'a> LateResolutionVisitor<'a, '_> { // Emit special messages for unresolved `Self` and `self`. if is_self_type(path, ns) { - err.code(errors::error_code!(E0411)); + err.code(rustc_errors::error_code!(E0411)); err.span_label( span, format!("`Self` is only available in impls, traits, and type definitions"), @@ -149,7 +149,7 @@ impl<'a> LateResolutionVisitor<'a, '_> { if is_self_value(path, ns) { debug!("smart_resolve_path_fragment: E0424, source={:?}", source); - err.code(errors::error_code!(E0424)); + err.code(rustc_errors::error_code!(E0424)); err.span_label(span, match source { PathSource::Pat => format!( "`self` value is a keyword and may not be bound to variables or shadowed", diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 9e4486e16f2cc..e6be9f6d328c0 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -20,7 +20,6 @@ pub use rustc_hir::def::{Namespace, PerNS}; use Determinacy::*; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc::hir::exports::ExportMap; use rustc::hir::map::{DefKey, Definitions}; use rustc::lint; @@ -32,6 +31,7 @@ use rustc::ty::{self, DefIdTree, ResolverOutputs}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_expand::base::SyntaxExtension; use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 469e1b9aa6207..d6143eec73c00 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -5,7 +5,6 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::resolve_lifetime::*; @@ -13,6 +12,7 @@ use rustc::session::Session; use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use rustc::{bug, span_bug}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index a489d0cd02b40..84e5f56d9c208 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -15,8 +15,8 @@ arena = { path = "../libarena" } log = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7c7480339a5ee..c6f36c66a3aa4 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -9,7 +9,6 @@ use crate::middle::resolve_lifetime as rl; use crate::namespace::Namespace; use crate::require_c_abi_if_c_variadic; use crate::util::common::ErrorReported; -use errors::{struct_span_err, Applicability, DiagnosticId}; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; use rustc::traits::astconv_object_safety_violations; @@ -19,6 +18,7 @@ use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -30,7 +30,6 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; use smallvec::SmallVec; use syntax::ast; -use syntax::errors::pluralize; use syntax::feature_gate::feature_err; use syntax::util::lev_distance::find_best_match_for_name; diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 3d02889d2ddd3..8d6b74c3015c9 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -1,13 +1,13 @@ use super::method::MethodCallee; use super::{FnCtxt, Needs, PlaceOp}; -use errors::struct_span_err; use rustc::infer::{InferCtxt, InferOk}; use rustc::session::DiagnosticMessageId; use rustc::traits::{self, TraitEngine}; use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc::ty::{self, TraitRef, Ty, TyCtxt}; use rustc::ty::{ToPredicate, TypeFoldable}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_span::Span; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a1915bc025f79..bff6765314ab8 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -3,22 +3,20 @@ use super::method::MethodCallee; use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag}; use crate::type_error_struct; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; -use hir::def::Res; -use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::{infer, traits}; +use rustc_error_codes::*; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_hir as hir; +use rustc_hir::def::Res; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_span::Span; use rustc_target::spec::abi; use syntax::ast::Ident; -use rustc_hir as hir; - -use rustc_error_codes::*; - /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific /// method that is called). diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 9dbf55c494831..ba5e5fd8ac188 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -34,7 +34,6 @@ use crate::hir::def_id::DefId; use crate::lint; use crate::type_error_struct; use crate::util::common::ErrorReported; -use errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc::middle::lang_items; use rustc::session::Session; use rustc::traits; @@ -45,6 +44,7 @@ use rustc::ty::cast::{CastKind, CastTy}; use rustc::ty::error::TypeError; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TypeAndMut, TypeFoldable}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_span::Span; use syntax::ast; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index ec298ca697183..feab31523f265 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -51,7 +51,6 @@ //! we may want to adjust precisely when coercions occur. use crate::check::{FnCtxt, Needs}; -use errors::{struct_span_err, DiagnosticBuilder}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; @@ -63,6 +62,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::ty::relate::RelateResult; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TypeAndMut}; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span; diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 449c2e90ff202..c35661ac649fc 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -1,4 +1,3 @@ -use errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; use rustc::hir::map::Map; use rustc::infer::{self, InferOk}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; @@ -7,6 +6,7 @@ use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::util::ExplicitSelf; use rustc::ty::{self, GenericParamDefKind, TyCtxt}; use rustc::util::common::ErrorReported; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 1be65b5f1894b..e0f9fcc69325c 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -2,9 +2,9 @@ use crate::check::FnCtxt; use rustc::infer::InferOk; use rustc::traits::{self, ObligationCause}; -use errors::{Applicability, DiagnosticBuilder}; use rustc::ty::adjustment::AllowTwoPhase; use rustc::ty::{self, AssocItem, Ty}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::{is_range_literal, print, Node}; use rustc_span::symbol::sym; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 33a07423c2502..88e7a265ebbcf 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -2,7 +2,6 @@ use crate::check::regionck::RegionCtxt; use crate::hir; use crate::hir::def_id::DefId; use crate::util::common::ErrorReported; -use errors::struct_span_err; use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::infer::{InferOk, SuppressRegionErrors}; use rustc::middle::region; @@ -11,6 +10,7 @@ use rustc::ty::error::TypeError; use rustc::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc::ty::subst::{Subst, SubstsRef}; use rustc::ty::{self, Predicate, Ty, TyCtxt}; +use rustc_errors::struct_span_err; use rustc_span::Span; diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 01795ef39665f..35342de59a082 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -17,7 +17,6 @@ use crate::check::TupleArgumentsFlag::DontTupleArguments; use crate::type_error_struct; use crate::util::common::ErrorReported; -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::middle::lang_items; @@ -28,6 +27,7 @@ use rustc::ty::Ty; use rustc::ty::TypeFoldable; use rustc::ty::{AdtKind, Visibility}; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2b731947aa0fa..0441514c83c9d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -3,11 +3,11 @@ use crate::require_same_types; -use errors::struct_span_err; use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::subst::Subst; use rustc::ty::{self, Ty, TyCtxt}; use rustc_error_codes::*; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e9356a04c01d4..711c285d17e88 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -12,7 +12,6 @@ pub use self::MethodError::*; use crate::check::FnCtxt; use crate::namespace::Namespace; -use errors::{Applicability, DiagnosticBuilder}; use rustc::infer::{self, InferOk}; use rustc::traits; use rustc::ty::subst::Subst; @@ -20,6 +19,7 @@ use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::GenericParamDefKind; use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable}; use rustc_data_structures::sync::Lrc; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; use rustc_hir::def_id::DefId; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4f0467b78b252..b2542cc27a551 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -9,7 +9,6 @@ use crate::hir::def::DefKind; use crate::hir::def_id::DefId; use crate::namespace::Namespace; -use errors::struct_span_err; use rustc::infer::canonical::OriginalQueryValues; use rustc::infer::canonical::{Canonical, QueryResponse}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -29,6 +28,7 @@ use rustc::ty::{ }; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_span::{symbol::Symbol, Span, DUMMY_SP}; use std::cmp::max; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4f55d9ab70ede..97f652383fb6e 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -4,7 +4,6 @@ use crate::check::FnCtxt; use crate::middle::lang_items::FnOnceTraitLangItem; use crate::namespace::Namespace; -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc::hir::map as hir_map; use rustc::hir::map::Map; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -12,6 +11,7 @@ use rustc::traits::Obligation; use rustc::ty::print::with_crate_prefix; use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5e73f8e3e128f..32225cd417f2d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -90,7 +90,6 @@ pub mod writeback; use crate::astconv::{AstConv, PathSeg}; use crate::middle::lang_items; use crate::namespace::Namespace; -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::hir::map::Map; use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282; @@ -116,6 +115,7 @@ use rustc::ty::{ }; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE}; @@ -164,7 +164,7 @@ macro_rules! type_error_struct { if $typ.references_error() { $session.diagnostic().struct_dummy() } else { - errors::struct_span_err!($session, $span, $code, $($message)*) + rustc_errors::struct_span_err!($session, $span, $code, $($message)*) } }) } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index d746b97472735..edf9d19dea377 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -2,11 +2,11 @@ use super::method::MethodCallee; use super::{FnCtxt, Needs}; -use errors::{self, struct_span_err, Applicability}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint}; use rustc::ty::{self, Ty, TypeFoldable}; +use rustc_errors::{self, struct_span_err, Applicability}; use rustc_hir as hir; use rustc_span::Span; use syntax::ast::Ident; @@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs_expr.span, msg, format!("*{}", lstring), - errors::Applicability::MachineApplicable, + rustc_errors::Applicability::MachineApplicable, ); suggested_deref = true; } @@ -482,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// suggest calling the function. Returns wether a suggestion was given. fn add_type_neq_err_label( &self, - err: &mut errors::DiagnosticBuilder<'_>, + err: &mut rustc_errors::DiagnosticBuilder<'_>, span: Span, ty: Ty<'tcx>, other_ty: Ty<'tcx>, @@ -565,7 +565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rhs_expr: &'tcx hir::Expr<'tcx>, lhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>, - err: &mut errors::DiagnosticBuilder<'_>, + err: &mut rustc_errors::DiagnosticBuilder<'_>, is_assign: bool, op: hir::BinOp, ) -> bool { diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 58c722f1da6f4..a19caefc107e7 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1,11 +1,11 @@ use crate::check::FnCtxt; -use errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::Pattern; use rustc::ty::subst::GenericArg; use rustc::ty::{self, BindingMode, Ty, TypeFoldable}; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index c57eb67218964..df1eecdcfa8c5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1,13 +1,13 @@ use crate::check::{FnCtxt, Inherited}; use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; -use errors::{struct_span_err, DiagnosticBuilder}; use rustc::infer::opaque_types::may_define_opaque_type; use rustc::middle::lang_items; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; use rustc_span::symbol::sym; diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index ab8e4ce6975a9..ec098c1d89679 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -1,15 +1,13 @@ use crate::lint; use rustc::ty::TyCtxt; - -use errors::Applicability; -use rustc_span::Span; -use syntax::ast; - use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::print::visibility_qualified; +use rustc_span::Span; +use syntax::ast; pub fn check_crate(tcx: TyCtxt<'_>) { let mut used_trait_imports = DefIdSet::default(); diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 5af5acda14379..8b3db15c02b4e 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -1,7 +1,6 @@ //! Check properties that are required by built-in traits and set //! up data structures required by type-checking/codegen. -use errors::struct_span_err; use rustc::infer; use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::infer::SuppressRegionErrors; @@ -14,6 +13,7 @@ use rustc::ty::adjustment::CoerceUnsizedInfo; use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty, TyCtxt}; use rustc_error_codes::*; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 73d03f9244721..673c1bd9fd831 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -7,8 +7,8 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. -use errors::struct_span_err; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index 01d2f528d4563..a9228c7f6bb4c 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -1,7 +1,7 @@ use crate::namespace::Namespace; -use errors::struct_span_err; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index ca10601f4135b..fd685e77b418c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -5,14 +5,13 @@ // done by the orphan and overlap modules. Then we build up various // mappings. That mapping code resides here. -use crate::hir::def_id::{DefId, LOCAL_CRATE}; -use crate::hir::HirId; -use errors::struct_span_err; use rustc::traits; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, TypeFoldable}; - use rustc_error_codes::*; +use rustc_errors::struct_span_err; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::HirId; mod builtin; mod inherent_impls; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index cf9935143b2d7..1878f9385a891 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -1,9 +1,9 @@ //! Orphan checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. -use errors::struct_span_err; use rustc::traits; use rustc::ty::{self, TyCtxt}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 9257aa759b4cf..3f4035b0998d6 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -1,8 +1,8 @@ //! Unsafety checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. -use errors::struct_span_err; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::Unsafety; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3bb06d7634983..64e71cc42e0ca 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -20,7 +20,6 @@ use crate::constrained_generic_params as cgp; use crate::lint; use crate::middle::resolve_lifetime as rl; use crate::middle::weak_lang_items; -use errors::{struct_span_err, Applicability, StashKey}; use rustc::hir::map::Map; use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::mir::mono::Linkage; @@ -34,6 +33,7 @@ use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{struct_span_err, Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -255,7 +255,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { fn bad_placeholder_type( tcx: TyCtxt<'tcx>, mut spans: Vec, -) -> errors::DiagnosticBuilder<'tcx> { +) -> rustc_errors::DiagnosticBuilder<'tcx> { spans.sort(); let mut err = struct_span_err!( tcx.sess, diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index e3e61ebb93607..fb87b285fa29f 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -9,10 +9,10 @@ //! fixed, but for the moment it's easier to do these checks early. use crate::constrained_generic_params as cgp; -use errors::struct_span_err; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 0d9940cbf92c7..b951883ac195a 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -91,7 +91,6 @@ mod outlives; mod structured_errors; mod variance; -use errors::struct_span_err; use rustc::infer::InferOk; use rustc::lint; use rustc::middle; @@ -103,6 +102,7 @@ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util; use rustc::util::common::ErrorReported; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Node; diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index b693743e47496..908429c8dc48a 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -1,5 +1,5 @@ -use errors::struct_span_err; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::symbol::sym; diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs index dc6c45b41842c..068814723f52d 100644 --- a/src/librustc_typeck/structured_errors.rs +++ b/src/librustc_typeck/structured_errors.rs @@ -1,6 +1,6 @@ -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::session::Session; use rustc::ty::{Ty, TypeFoldable}; +use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_span::Span; use rustc_error_codes::*; @@ -50,7 +50,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> { } fn code(&self) -> DiagnosticId { - errors::error_code!(E0617) + rustc_errors::error_code!(E0617) } fn common(&self) -> DiagnosticBuilder<'tcx> { @@ -111,7 +111,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> { } fn code(&self) -> DiagnosticId { - errors::error_code!(E0607) + rustc_errors::error_code!(E0607) } fn common(&self) -> DiagnosticBuilder<'tcx> { diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index 860bfe79395ff..2f41bee1819cd 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -1,5 +1,5 @@ -use errors::struct_span_err; use rustc::ty::TyCtxt; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::symbol::sym; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c8f1dff703fb4..5d8e27ecadb82 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -497,7 +497,7 @@ impl Attributes { false } - pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes { + pub fn from_ast(diagnostic: &::rustc_errors::Handler, attrs: &[ast::Attribute]) -> Attributes { let mut doc_strings = vec![]; let mut sp = None; let mut cfg = Cfg::True; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 26b49d2f9624e..22f5d0dc2c078 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -3,7 +3,6 @@ use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; -use errors; use getopts; use rustc::lint::Level; use rustc::session; @@ -566,7 +565,7 @@ impl Options { } /// Prints deprecation warnings for deprecated options -fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler) { +fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Handler) { let deprecated_flags = ["input-format", "output-format", "no-defaults", "passes"]; for flag in deprecated_flags.iter() { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index be7f7ea364f47..3cda1b3be75f1 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,8 +15,8 @@ use rustc_interface::interface; use rustc_lint; use rustc_resolve as resolve; -use errors::emitter::{Emitter, EmitterWriter}; -use errors::json::JsonEmitter; +use rustc_errors::emitter::{Emitter, EmitterWriter}; +use rustc_errors::json::JsonEmitter; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; @@ -171,7 +171,7 @@ pub fn new_handler( error_format: ErrorOutputType, source_map: Option>, debugging_opts: &DebuggingOptions, -) -> errors::Handler { +) -> rustc_errors::Handler { let emitter: Box = match error_format { ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -198,7 +198,10 @@ pub fn new_handler( } }; - errors::Handler::with_emitter_and_flags(emitter, debugging_opts.diagnostic_handler_flags(true)) + rustc_errors::Handler::with_emitter_and_flags( + emitter, + debugging_opts.diagnostic_handler_flags(true), + ) } pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) { @@ -409,7 +412,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let mut krate = clean::krate(&mut ctxt); - fn report_deprecated_attr(name: &str, diag: &errors::Handler) { + fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler) { let mut msg = diag.struct_warn(&format!( "the `#![doc({})]` attribute is \ considered deprecated", diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs index 2a107e828f75f..ecc394a2bc992 100644 --- a/src/librustdoc/docfs.rs +++ b/src/librustdoc/docfs.rs @@ -9,8 +9,6 @@ //! needs to read-after-write from a file, then it would be added to this //! abstraction. -use errors; - use std::fs; use std::io; use std::path::Path; @@ -42,7 +40,7 @@ impl ErrorStorage { } /// Prints all stored errors. Returns the number of printed errors. - pub fn write_errors(&mut self, diag: &errors::Handler) -> usize { + pub fn write_errors(&mut self, diag: &rustc_errors::Handler) -> usize { let mut printed = 0; // In order to drop the sender part of the channel. self.sender = None; diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index e0ed02c11c71a..8b5a3a2ba6131 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -1,6 +1,5 @@ use crate::html::markdown::{ErrorCodes, IdMap, Markdown, Playground}; use crate::rustc_span::edition::Edition; -use errors; use rustc_feature::UnstableFeatures; use std::fs; use std::path::Path; @@ -26,7 +25,7 @@ impl ExternalHtml { after_content: &[String], md_before_content: &[String], md_after_content: &[String], - diag: &errors::Handler, + diag: &rustc_errors::Handler, id_map: &mut IdMap, edition: Edition, playground: &Option, @@ -58,7 +57,7 @@ pub enum LoadStringError { pub fn load_string>( file_path: P, - diag: &errors::Handler, + diag: &rustc_errors::Handler, ) -> Result { let file_path = file_path.as_ref(); let contents = match fs::read(file_path) { @@ -77,7 +76,7 @@ pub fn load_string>( } } -fn load_external_files(names: &[String], diag: &errors::Handler) -> Option { +fn load_external_files(names: &[String], diag: &rustc_errors::Handler) -> Option { let mut out = String::new(); for name in names { let s = match load_string(name, diag) { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a01e2f793948e..2d932eb7668c4 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -42,7 +42,6 @@ use std::rc::Rc; use std::str; use std::sync::Arc; -use errors; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc_data_structures::flock; @@ -394,7 +393,7 @@ pub fn run( mut krate: clean::Crate, options: RenderOptions, renderinfo: RenderInfo, - diag: &errors::Handler, + diag: &rustc_errors::Handler, edition: Edition, ) -> Result<(), Error> { // need to save a copy of the options for rendering the index page @@ -528,7 +527,7 @@ fn write_shared( krate: &clean::Crate, search_index: String, options: &RenderOptions, - diag: &errors::Handler, + diag: &rustc_errors::Handler, ) -> Result<(), Error> { // Write out the shared files. Note that these are shared among all rustdoc // docs placed in the output directory, so this needs to be a synchronized diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 91150899877fe..b15dae452ff05 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -24,6 +24,7 @@ extern crate rustc; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_error_codes; +extern crate rustc_errors; extern crate rustc_expand; extern crate rustc_feature; extern crate rustc_hir; @@ -42,7 +43,6 @@ extern crate syntax; extern crate test as testing; #[macro_use] extern crate log; -extern crate rustc_errors as errors; use std::default::Default; use std::env; @@ -518,6 +518,6 @@ where match result { Ok(output) => output, - Err(_) => panic::resume_unwind(Box::new(errors::FatalErrorMarker)), + Err(_) => panic::resume_unwind(Box::new(rustc_errors::FatalErrorMarker)), } } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 69aa248aa8e98..912a40722b8af 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -2,7 +2,6 @@ use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; -use errors; use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; use rustc_span::source_map::DUMMY_SP; @@ -39,7 +38,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) { pub fn render( input: PathBuf, options: RenderOptions, - diag: &errors::Handler, + diag: &rustc_errors::Handler, edition: Edition, ) -> i32 { let mut output = options.output; @@ -128,7 +127,7 @@ pub fn render( } /// Runs any tests/code examples in the markdown file `input`. -pub fn test(mut options: Options, diag: &errors::Handler) -> i32 { +pub fn test(mut options: Options, diag: &rustc_errors::Handler) -> i32 { let input_str = match load_string(&options.input, diag) { Ok(s) => s, Err(LoadStringError::ReadFail) => return 1, diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 79548eb6d647a..0bab4423b3dfd 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -1,5 +1,5 @@ -use errors::{emitter::Emitter, Applicability, Diagnostic, Handler}; use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler}; use rustc_parse::lexer::StringReader as Lexer; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileName, InnerSpan}; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index b1cd3deecb479..50d5f70f4889a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1,6 +1,6 @@ -use errors::Applicability; use rustc::lint; use rustc::ty; +use rustc_errors::Applicability; use rustc_expand::base::SyntaxExtensionKind; use rustc_feature::UnstableFeatures; use rustc_hir as hir; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 94e31108901ea..cc5359b53d17c 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -389,8 +389,8 @@ pub fn make_test( // crate already is included. let result = rustc_driver::catch_fatal_errors(|| { with_globals(edition, || { - use errors::emitter::EmitterWriter; - use errors::Handler; + use rustc_errors::emitter::EmitterWriter; + use rustc_errors::Handler; use rustc_parse::maybe_new_parser_from_source_str; use rustc_span::source_map::FilePathMapping; use syntax::sess::ParseSess; diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index b45531d7252a1..af1c50acb0a35 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -3,7 +3,7 @@ use std::fs; use std::hash::{Hash, Hasher}; use std::path::Path; -use errors::Handler; +use rustc_errors::Handler; #[cfg(test)] mod tests; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index e4f0398fb42d2..7d9f715e9feb8 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -13,8 +13,8 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" scoped-tls = "1.0" +rustc_errors = { path = "../librustc_errors" } rustc_span = { path = "../librustc_span" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_index = { path = "../librustc_index" } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index b308d479545be..958e4373cc0ed 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -6,7 +6,7 @@ use crate::feature_gate::feature_err; use crate::print::pprust; use crate::sess::ParseSess; -use errors::{struct_span_err, Applicability, Handler}; +use rustc_errors::{struct_span_err, Applicability, Handler}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; use rustc_span::hygiene::Transparency; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 8449b61f7b0bb..ec05dab451af8 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -384,7 +384,7 @@ pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { pub fn allow_internal_unstable<'a>( attrs: &[Attribute], - span_diagnostic: &'a errors::Handler, + span_diagnostic: &'a rustc_errors::Handler, ) -> Option + 'a> { find_by_name(attrs, sym::allow_internal_unstable).and_then(|attr| { attr.meta_item_list() diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 52eb20d320f7b..92fbb86506008 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -4,9 +4,9 @@ use crate::attr; use crate::sess::ParseSess; use crate::visit::{self, FnKind, Visitor}; -use errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Handler}; use rustc_data_structures::fx::FxHashMap; use rustc_error_codes::*; +use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Handler}; use rustc_feature::{find_feature_issue, GateIssue}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Feature, Features, State as FeatureState, UnstableFeatures}; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b197eab739427..7ee4ca4603c9c 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -18,7 +18,6 @@ #![recursion_limit = "256"] use ast::AttrId; -pub use errors; use rustc_data_structures::sync::Lock; use rustc_index::bit_set::GrowableBitSet; use rustc_span::edition::{Edition, DEFAULT_EDITION}; diff --git a/src/libsyntax/show_span.rs b/src/libsyntax/show_span.rs index fb641239dfa4f..b70e2ce0d3eb7 100644 --- a/src/libsyntax/show_span.rs +++ b/src/libsyntax/show_span.rs @@ -29,7 +29,7 @@ impl FromStr for Mode { } struct ShowSpanVisitor<'a> { - span_diagnostic: &'a errors::Handler, + span_diagnostic: &'a rustc_errors::Handler, mode: Mode, } @@ -60,7 +60,7 @@ impl<'a> Visitor<'a> for ShowSpanVisitor<'a> { } } -pub fn run(span_diagnostic: &errors::Handler, mode: &str, krate: &ast::Crate) { +pub fn run(span_diagnostic: &rustc_errors::Handler, mode: &str, krate: &ast::Crate) { let mode = match mode.parse().ok() { Some(mode) => mode, None => return, From afced941555ecaa7fff2e11c8396bca58384d760 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Thu, 9 Jan 2020 16:40:40 +0100 Subject: [PATCH 0143/1253] Allow specifying LLVM args in target specifications --- src/librustc_codegen_llvm/llvm_util.rs | 15 ++++++--------- src/librustc_target/spec/mod.rs | 6 ++++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index b3c58b2402065..52613fef7e612 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -46,7 +46,7 @@ fn require_inited() { } unsafe fn configure_llvm(sess: &Session) { - let n_args = sess.opts.cg.llvm_args.len(); + let n_args = sess.opts.cg.llvm_args.len() + sess.target.target.options.llvm_args.len(); let mut llvm_c_strs = Vec::with_capacity(n_args + 1); let mut llvm_args = Vec::with_capacity(n_args + 1); @@ -56,14 +56,11 @@ unsafe fn configure_llvm(sess: &Session) { full_arg.trim().split(|c: char| c == '=' || c.is_whitespace()).next().unwrap_or("") } - let user_specified_args: FxHashSet<_> = sess - .opts - .cg - .llvm_args - .iter() - .map(|s| llvm_arg_to_arg_name(s)) - .filter(|s| s.len() > 0) - .collect(); + let cg_opts = sess.opts.cg.llvm_args.iter(); + let tg_opts = sess.target.target.options.llvm_args.iter(); + + let user_specified_args: FxHashSet<_> = + cg_opts.chain(tg_opts).map(|s| llvm_arg_to_arg_name(s)).filter(|s| s.len() > 0).collect(); { // This adds the given argument to LLVM. Unless `force` is true diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f08634cc770e0..528ffdf93a01a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -805,6 +805,9 @@ pub struct TargetOptions { /// Whether or not RelaxElfRelocation flag will be passed to the linker pub relax_elf_relocations: bool, + + /// Additional arguments to pass to LLVM, similar to the `-C llvm-args` codegen option. + pub llvm_args: Vec, } impl Default for TargetOptions { @@ -893,6 +896,7 @@ impl Default for TargetOptions { target_mcount: "mcount".to_string(), llvm_abiname: "".to_string(), relax_elf_relocations: false, + llvm_args: vec![], } } } @@ -1206,6 +1210,7 @@ impl Target { key!(target_mcount); key!(llvm_abiname); key!(relax_elf_relocations, bool); + key!(llvm_args, list); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1433,6 +1438,7 @@ impl ToJson for Target { target_option_val!(target_mcount); target_option_val!(llvm_abiname); target_option_val!(relax_elf_relocations); + target_option_val!(llvm_args); if default.abi_blacklist != self.options.abi_blacklist { d.insert( From a59abfa450cf9d18d725c2b757686fd4b65ccbe5 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Dec 2019 11:47:33 -0300 Subject: [PATCH 0144/1253] Revert const_eval call to use const_eval_raw to avoid const validation cycles --- src/librustc_mir/interpret/operand.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index ddd9776e89383..94a774d646a75 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -542,7 +542,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // happening. // FIXME(oli-obk): eliminate all the `const_eval_raw` usages when we get rid of // `StaticKind` once and for all. - return self.const_eval(GlobalId { instance, promoted: None }); + // FIXME the following line should have been: + // return self.const_eval(GlobalId { instance, promoted }); + // but since the addition of Promoteds being Constants is causing const validation + // cycles. Promoteds being Constants exercise const validation more often and it + // may have made show up a pre-existing bug. + return Ok(OpTy::from(self.const_eval_raw(GlobalId { instance, promoted })?)); } ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) From 1688719214ef8a0638e1df543b1a6e77a0909244 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 22 Nov 2019 17:26:09 -0300 Subject: [PATCH 0145/1253] Promote `Ref`s to constants instead of static --- src/librustc/mir/interpret/queries.rs | 7 +- src/librustc/mir/mod.rs | 11 ++ src/librustc/traits/fulfill.rs | 1 + src/librustc/traits/select.rs | 9 +- src/librustc/traits/wf.rs | 4 +- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/print/pretty.rs | 36 ++++-- src/librustc/ty/relate.rs | 8 +- src/librustc/ty/structural_impls.rs | 6 +- src/librustc/ty/sty.rs | 13 +- src/librustc/ty/walk.rs | 3 +- src/librustc_codegen_ssa/mir/constant.rs | 9 +- .../borrow_check/type_check/mod.rs | 59 +++++++-- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/const_eval/eval_queries.rs | 18 ++- src/librustc_mir/hair/cx/expr.rs | 25 ++-- src/librustc_mir/hair/pattern/mod.rs | 1 + src/librustc_mir/interpret/intern.rs | 25 ++-- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 4 +- .../transform/check_consts/qualifs.rs | 4 +- src/librustc_mir/transform/const_prop.rs | 38 +++--- src/librustc_mir/transform/promote_consts.rs | 121 ++++++++++++++---- src/librustc_typeck/astconv.rs | 6 +- src/librustdoc/clean/utils.rs | 8 +- src/test/codegen/consts.rs | 6 +- .../promoted_div_by_zero.rs | 2 +- src/test/mir-opt/const_prop/ref_deref.rs | 6 +- src/test/mir-opt/const_prop/slice_len.rs | 6 +- src/test/mir-opt/inline/inline-retag.rs | 10 +- src/test/mir-opt/match_false_edges.rs | 3 +- src/test/ui/consts/array-literal-index-oob.rs | 1 + .../ui/consts/array-literal-index-oob.stderr | 9 +- .../const-eval/conditional_array_execution.rs | 1 + .../conditional_array_execution.stderr | 8 +- .../consts/const-eval/const_fn_ptr_fail2.rs | 2 + .../const-eval/const_fn_ptr_fail2.stderr | 20 ++- src/test/ui/consts/const-eval/issue-43197.rs | 2 + .../ui/consts/const-eval/issue-43197.stderr | 14 +- src/test/ui/consts/const-eval/issue-44578.rs | 3 +- .../ui/consts/const-eval/issue-44578.stderr | 8 +- src/test/ui/consts/const-eval/issue-50814.rs | 6 +- .../ui/consts/const-eval/issue-50814.stderr | 2 +- .../ui/consts/const-eval/promoted_errors.rs | 2 + .../consts/const-eval/promoted_errors.stderr | 23 +++- .../ui/consts/const-eval/promoted_errors2.rs | 2 + .../consts/const-eval/promoted_errors2.stderr | 23 +++- .../ui/consts/const-eval/ub-nonnull.stderr | 2 +- .../ui/consts/miri_unleashed/non_const_fn.rs | 4 +- .../consts/miri_unleashed/non_const_fn.stderr | 8 +- src/test/ui/consts/zst_no_llvm_alloc.rs | 10 +- src/test/ui/invalid_const_promotion.rs | 61 --------- src/test/ui/symbol-names/impl1.legacy.stderr | 4 +- 53 files changed, 447 insertions(+), 223 deletions(-) rename src/test/{run-fail => compile-fail}/promoted_div_by_zero.rs (57%) delete mode 100644 src/test/ui/invalid_const_promotion.rs diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs index 161c9a3fcc1f7..2b094bf911f88 100644 --- a/src/librustc/mir/interpret/queries.rs +++ b/src/librustc/mir/interpret/queries.rs @@ -36,11 +36,16 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, + promoted: Option, span: Option, ) -> ConstEvalResult<'tcx> { let instance = ty::Instance::resolve(self, param_env, def_id, substs); if let Some(instance) = instance { - self.const_eval_instance(param_env, instance, span) + if let Some(promoted) = promoted { + self.const_eval_promoted(instance, promoted) + } else { + self.const_eval_instance(param_env, instance, span) + } } else { Err(ErrorHandled::TooGeneric) } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ff64302b1e506..0f909dc148fcb 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -166,6 +166,16 @@ pub struct Body<'tcx> { /// A span representing this MIR, for error reporting. pub span: Span, + + /// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because + /// we'd statically know that no thing with interior mutability will ever be available to the + /// user without some serious unsafe code. Now this means that our promoted is actually + /// &[(SOME_CELL, 42)] and the MIR using it will do the &promoted[i].1 projection because the + /// index may be a runtime value. Such a promoted value is illegal because it has reachable + /// interior mutability. This flag just makes this situation very obvious where the previous + /// implementation without the flag hid this situation silently. + /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components. + pub ignore_interior_mut_in_const_validation: bool, } impl<'tcx> Body<'tcx> { @@ -202,6 +212,7 @@ impl<'tcx> Body<'tcx> { spread_arg: None, var_debug_info, span, + ignore_interior_mut_in_const_validation: false, control_flow_destroyed, } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index b0b6994945c5f..46ece6fc40593 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -515,6 +515,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { obligation.param_env, def_id, substs, + None, Some(obligation.cause.span), ) { Ok(_) => ProcessResult::Changed(vec![]), diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 1b1cb1b36e09a..b7643efdc899e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -802,8 +802,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Predicate::ConstEvaluatable(def_id, substs) => { if !(obligation.param_env, substs).has_local_value() { - match self.tcx().const_eval_resolve(obligation.param_env, def_id, substs, None) - { + match self.tcx().const_eval_resolve( + obligation.param_env, + def_id, + substs, + None, + None, + ) { Ok(_) => Ok(EvaluatedToOk), Err(_) => Ok(EvaluatedToErr), } diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 551f8fde12b18..2301395f557f1 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -359,7 +359,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an array length to be WF /// into `self.out`. fn compute_array_len(&mut self, constant: ty::Const<'tcx>) { - if let ty::ConstKind::Unevaluated(def_id, substs) = constant.val { + if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.val { + assert!(promoted.is_none()); + let obligations = self.nominal_obligations(def_id, substs); self.out.extend(obligations); diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index b9aa12b466589..4a4280ba7dc4d 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -219,7 +219,7 @@ impl FlagComputation { fn add_const(&mut self, c: &ty::Const<'_>) { self.add_ty(c.ty); match c.val { - ty::ConstKind::Unevaluated(_, substs) => { + ty::ConstKind::Unevaluated(_, substs, _) => { self.add_substs(substs); self.add_flags(TypeFlags::HAS_PROJECTION); } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 16d8934359687..8b1b2bb586597 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -841,23 +841,31 @@ pub trait PrettyPrinter<'tcx>: match (ct.val, &ct.ty.kind) { (_, ty::FnDef(did, substs)) => p!(print_value_path(*did, substs)), - (ty::ConstKind::Unevaluated(did, substs), _) => match self.tcx().def_kind(did) { - Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => { - p!(print_value_path(did, substs)) - } - _ => { - if did.is_local() { - let span = self.tcx().def_span(did); - if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { - p!(write("{}", snip)) - } else { - p!(write("_: "), print(ct.ty)) + (ty::ConstKind::Unevaluated(did, substs, promoted), _) => { + if let Some(promoted) = promoted { + p!(print_value_path(did, substs)); + p!(write("::{:?}", promoted)); + } else { + match self.tcx().def_kind(did) { + Some(DefKind::Static) + | Some(DefKind::Const) + | Some(DefKind::AssocConst) => p!(print_value_path(did, substs)), + _ => { + if did.is_local() { + let span = self.tcx().def_span(did); + if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) + { + p!(write("{}", snip)) + } else { + p!(write("_: "), print(ct.ty)) + } + } else { + p!(write("_: "), print(ct.ty)) + } } - } else { - p!(write("_: "), print(ct.ty)) } } - }, + } (ty::ConstKind::Infer(..), _) => p!(write("_: "), print(ct.ty)), (ty::ConstKind::Param(ParamConst { name, .. }), _) => p!(write("{}", name)), (ty::ConstKind::Value(value), _) => return self.pretty_print_const_value(value, ct.ty), diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 9472281b56fec..3b9df72266f09 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -568,12 +568,12 @@ pub fn super_relate_consts>( // FIXME(const_generics): this is wrong, as it is a projection ( - ty::ConstKind::Unevaluated(a_def_id, a_substs), - ty::ConstKind::Unevaluated(b_def_id, b_substs), - ) if a_def_id == b_def_id => { + ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted), + ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted), + ) if a_def_id == b_def_id && a_promoted == b_promoted => { let substs = relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?; - Ok(ty::ConstKind::Unevaluated(a_def_id, &substs)) + Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted)) } _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), }; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 5e24c843025bf..62e895af7f355 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1037,8 +1037,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(did, substs) => { - ty::ConstKind::Unevaluated(did, substs.fold_with(folder)) + ty::ConstKind::Unevaluated(did, substs, promoted) => { + ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted) } ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => { *self @@ -1050,7 +1050,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), - ty::ConstKind::Unevaluated(_, substs) => substs.visit_with(visitor), + ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { false } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index c89d045cebb73..842361284823d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -9,6 +9,7 @@ use crate::infer::canonical::Canonical; use crate::middle::region; use crate::mir::interpret::ConstValue; use crate::mir::interpret::Scalar; +use crate::mir::Promoted; use crate::ty::layout::VariantIdx; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable}; @@ -2375,7 +2376,7 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { - let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs| { + let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs, promoted| { let param_env_and_substs = param_env.with_reveal_all().and(substs); // Avoid querying `tcx.const_eval(...)` with any e.g. inference vars. @@ -2387,11 +2388,11 @@ impl<'tcx> Const<'tcx> { // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - tcx.const_eval_resolve(param_env, did, substs, None).ok() + tcx.const_eval_resolve(param_env, did, substs, promoted, None).ok() }; match self.val { - ConstKind::Unevaluated(did, substs) => { + ConstKind::Unevaluated(did, substs, promoted) => { // HACK(eddyb) when substs contain e.g. inference variables, // attempt using identity substs instead, that will succeed // when the expression doesn't depend on any parameters. @@ -2401,12 +2402,12 @@ impl<'tcx> Const<'tcx> { let identity_substs = InternalSubsts::identity_for_item(tcx, did); // The `ParamEnv` needs to match the `identity_substs`. let identity_param_env = tcx.param_env(did); - match try_const_eval(did, identity_param_env, identity_substs) { + match try_const_eval(did, identity_param_env, identity_substs, promoted) { Some(ct) => ct.subst(tcx, substs), None => self, } } else { - try_const_eval(did, param_env, substs).unwrap_or(self) + try_const_eval(did, param_env, substs, promoted).unwrap_or(self) } } _ => self, @@ -2470,7 +2471,7 @@ pub enum ConstKind<'tcx> { /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. - Unevaluated(DefId, SubstsRef<'tcx>), + Unevaluated(DefId, SubstsRef<'tcx>, Option), /// Used to hold computed value. Value(ConstValue<'tcx>), diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 9e0dd8e067a20..da08fbcf14432 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -81,7 +81,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { | ty::Bound(..) | ty::Foreign(..) => {} ty::Array(ty, len) => { - if let ty::ConstKind::Unevaluated(_, substs) = len.val { + if let ty::ConstKind::Unevaluated(_, substs, promoted) = len.val { + assert!(promoted.is_none()); stack.extend(substs.types().rev()); } stack.push(len.ty); diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index f508ed90de42d..c6adbc81ce0b0 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -20,7 +20,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // use `get_static` to get at their id. // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics // always produce `&STATIC`. This may also simplify how const eval works with statics. - ty::ConstKind::Unevaluated(def_id, substs) if self.cx.tcx().is_static(def_id) => { + ty::ConstKind::Unevaluated(def_id, substs, promoted) + if self.cx.tcx().is_static(def_id) => + { + assert!(promoted.is_none()); assert!(substs.is_empty(), "we don't support generic statics yet"); let static_ = bx.get_static(def_id); // we treat operands referring to statics as if they were `&STATIC` instead @@ -40,11 +43,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> { match constant.literal.val { - ty::ConstKind::Unevaluated(def_id, substs) => { + ty::ConstKind::Unevaluated(def_id, substs, promoted) => { let substs = self.monomorphize(&substs); self.cx .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, None) + .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None) .map_err(|err| { self.cx .tcx() diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index b1df198406d3b..fa6ce3aa4a1f7 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -310,17 +310,54 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ); } } else { - if let ty::ConstKind::Unevaluated(def_id, substs) = constant.literal.val { - if let Err(terr) = self.cx.fully_perform_op( - location.to_locations(), - ConstraintCategory::Boring, - self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( - constant.literal.ty, - def_id, - UserSubsts { substs, user_self_ty: None }, - )), - ) { - span_mirbug!(self, constant, "bad constant type {:?} ({:?})", constant, terr); + if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val { + if let Some(promoted) = promoted { + let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, + promoted: &ReadOnlyBodyAndCache<'_, 'tcx>, + ty, + san_ty| { + if let Err(terr) = verifier.cx.eq_types( + san_ty, + ty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!( + verifier, + promoted, + "bad promoted type ({:?}: {:?}): {:?}", + ty, + san_ty, + terr + ); + }; + }; + + if !self.errors_reported { + let promoted_body = self.promoted[promoted]; + self.sanitize_promoted(promoted_body, location); + + let promoted_ty = promoted_body.return_ty(); + check_err(self, &promoted_body, ty, promoted_ty); + } + } else { + if let Err(terr) = self.cx.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( + constant.literal.ty, + def_id, + UserSubsts { substs, user_self_ty: None }, + )), + ) { + span_mirbug!( + self, + constant, + "bad constant type {:?} ({:?})", + constant, + terr + ); + } } } if let ty::FnDef(def_id, substs) = constant.literal.ty.kind { diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 7b2ce7f9ac7be..eb89553b77036 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -52,7 +52,7 @@ pub(crate) fn const_caller_location<'tcx>( let loc_ty = tcx.caller_location_ty(); let loc_place = ecx.alloc_caller_location(file, line, col); - intern_const_alloc_recursive(&mut ecx, None, loc_place).unwrap(); + intern_const_alloc_recursive(&mut ecx, None, loc_place, false).unwrap(); let loc_const = ty::Const { ty: loc_ty, val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())), diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 53f3b539bdaa0..d260a6808d120 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -56,7 +56,12 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.run()?; // Intern the result - intern_const_alloc_recursive(ecx, tcx.static_mutability(cid.instance.def_id()), ret)?; + intern_const_alloc_recursive( + ecx, + tcx.static_mutability(cid.instance.def_id()), + ret, + body.ignore_interior_mut_in_const_validation, + )?; debug!("eval_body_using_ecx done: {:?}", *ret); Ok(ret) @@ -171,9 +176,14 @@ fn validate_and_turn_into_const<'tcx>( let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); let val = (|| { let mplace = ecx.raw_const_to_mplace(constant)?; - let mut ref_tracking = RefTracking::new(mplace); - while let Some((mplace, path)) = ref_tracking.todo.pop() { - ecx.validate_operand(mplace.into(), path, Some(&mut ref_tracking))?; + + // FIXME do not validate promoteds until a decision on + // https://github.com/rust-lang/rust/issues/67465 is made + if cid.promoted.is_none() { + let mut ref_tracking = RefTracking::new(mplace); + while let Some((mplace, path)) = ref_tracking.todo.pop() { + ecx.validate_operand(mplace.into(), path, Some(&mut ref_tracking))?; + } } // Now that we validated, turn this into a proper constant. // Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 8fd8143ee374f..471e09fc03b28 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -411,15 +411,18 @@ fn make_mirror_unadjusted<'a, 'tcx>( let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let span = cx.tcx.def_span(def_id); - let count = match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, Some(span)) { - Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), - Err(ErrorHandled::Reported) => 0, - Err(ErrorHandled::TooGeneric) => { - let span = cx.tcx.def_span(def_id); - cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); - 0 - } - }; + let count = + match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, None, Some(span)) { + Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), + Err(ErrorHandled::Reported) => 0, + Err(ErrorHandled::TooGeneric) => { + let span = cx.tcx.def_span(def_id); + cx.tcx + .sess + .span_err(span, "array lengths can't depend on generic parameters"); + 0 + } + }; ExprKind::Repeat { value: v.to_ref(), count } } @@ -523,7 +526,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(cx.tcx(), did); let lhs = mk_const(cx.tcx().mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(did, substs), + val: ty::ConstKind::Unevaluated(did, substs, None), ty: var_ty, })); let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset }; @@ -719,7 +722,7 @@ fn convert_path_expr<'a, 'tcx>( debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: cx.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(def_id, substs), + val: ty::ConstKind::Unevaluated(def_id, substs, None), ty: cx.tables().node_type(expr.hir_id), }), user_ty, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 611d3f5b832dc..73644a4ca3f06 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -749,6 +749,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { self.param_env.with_reveal_all(), def_id, substs, + None, Some(span), ) { Ok(value) => { diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 9b3a2fa36f794..220761ce28d81 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -41,6 +41,11 @@ struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> { /// despite the nested mutable reference! /// The field gets updated when an `UnsafeCell` is encountered. mutability: Mutability, + + /// This flag is to avoid triggering UnsafeCells are not allowed behind references in constants + /// for promoteds. + /// It's a copy of `mir::Body`'s ignore_interior_mut_in_const_validation field + ignore_interior_mut_in_const_validation: bool, } #[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)] @@ -164,14 +169,16 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx // References we encounter inside here are interned as pointing to mutable // allocations. let old = std::mem::replace(&mut self.mutability, Mutability::Mut); - assert_ne!( - self.mode, - InternMode::Const, - "UnsafeCells are not allowed behind references in constants. This should have \ - been prevented statically by const qualification. If this were allowed one \ - would be able to change a constant at one use site and other use sites could \ - observe that mutation.", - ); + if !self.ignore_interior_mut_in_const_validation { + assert_ne!( + self.mode, + InternMode::Const, + "UnsafeCells are not allowed behind references in constants. This should \ + have been prevented statically by const qualification. If this were \ + allowed one would be able to change a constant at one use site and other \ + use sites could observe that mutation.", + ); + } let walked = self.walk_aggregate(mplace, fields); self.mutability = old; return walked; @@ -266,6 +273,7 @@ pub fn intern_const_alloc_recursive>( // The `mutability` of the place, ignoring the type. place_mut: Option, ret: MPlaceTy<'tcx>, + ignore_interior_mut_in_const_validation: bool, ) -> InterpResult<'tcx> { let tcx = ecx.tcx; let (base_mutability, base_intern_mode) = match place_mut { @@ -302,6 +310,7 @@ pub fn intern_const_alloc_recursive>( mode, leftover_allocations, mutability, + ignore_interior_mut_in_const_validation, } .visit_value(mplace); if let Err(error) = interned { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 94a774d646a75..ebe600f25dad1 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -532,7 +532,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Early-return cases. let val_val = match val.val { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), - ty::ConstKind::Unevaluated(def_id, substs) => { + ty::ConstKind::Unevaluated(def_id, substs, promoted) => { let instance = self.resolve(def_id, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. // The reason we use `const_eval_raw` everywhere else is to prevent cycles during diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 41fbfd22e50af..99df9456a6f4b 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1249,8 +1249,8 @@ fn collect_const<'tcx>( collect_miri(tcx, id, output); } } - ty::ConstKind::Unevaluated(def_id, substs) => { - match tcx.const_eval_resolve(param_env, def_id, substs, None) { + ty::ConstKind::Unevaluated(def_id, substs, promoted) => { + match tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) { Ok(val) => collect_const(tcx, val, param_substs, output), Err(ErrorHandled::Reported) => {} Err(ErrorHandled::TooGeneric) => { diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 0799cc2374ad4..253a5899768b2 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -102,7 +102,9 @@ pub trait Qualif { // Note: this uses `constant.literal.ty` which is a reference or pointer to the // type of the actual `static` item. Self::in_any_value_of_ty(cx, constant.literal.ty) - } else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val { + } else if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val + { + assert!(promoted.is_none()); // Don't peek inside trait associated constants. if cx.tcx.trait_of_item(def_id).is_some() { Self::in_any_value_of_ty(cx, constant.literal.ty) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index d5d56b36cf4c3..9614137b7e7bf 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -17,7 +17,7 @@ use rustc::mir::{ use rustc::ty::layout::{ HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; -use rustc::ty::subst::InternalSubsts; +use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; @@ -33,7 +33,6 @@ use crate::interpret::{ LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, ScalarMaybeUndef, StackPopCleanup, }; -use crate::rustc::ty::subst::Subst; use crate::transform::{MirPass, MirSource}; /// The maximum number of bytes that we'll allocate space for a return value. @@ -265,6 +264,7 @@ struct ConstPropagator<'mir, 'tcx> { // Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store // the last known `SourceInfo` here and just keep revisiting it. source_info: Option, + lint_root: Option, } impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> { @@ -344,6 +344,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { local_decls: body.local_decls.clone(), ret: ret.map(Into::into), source_info: None, + lint_root: None, } } @@ -377,10 +378,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { self.ecx.tcx.span = source_info.span; - // FIXME(eddyb) move this to the `Panic(_)` error case, so that - // `f(self)` is always called, and that the only difference when the - // scope's `local_data` is missing, is that the lint isn't emitted. - let lint_root = self.lint_root(source_info)?; let r = match f(self) { Ok(val) => Some(val), Err(error) => { @@ -414,7 +411,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { diagnostic.report_as_lint( self.ecx.tcx, "this expression will panic at runtime", - lint_root, + self.lint_root?, None, ); } @@ -426,17 +423,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { r } - fn eval_constant( - &mut self, - c: &Constant<'tcx>, - source_info: SourceInfo, - ) -> Option> { + fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option> { self.ecx.tcx.span = c.span; + + // FIXME we need to revisit this for #67176 + if c.needs_subst() { + return None; + } + match self.ecx.eval_const_to_op(c.literal, None) { Ok(op) => Some(op), Err(error) => { let err = error_to_const_error(&self.ecx, error); - match self.lint_root(source_info) { + match self.lint_root { Some(lint_root) if c.literal.needs_subst() => { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. @@ -463,7 +462,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { - Operand::Constant(ref c) => self.eval_constant(c, source_info), + Operand::Constant(ref c) => self.eval_constant(c), Operand::Move(ref place) | Operand::Copy(ref place) => { self.eval_place(place, source_info) } @@ -552,6 +551,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } + // FIXME we need to revisit this for #67176 + if rvalue.needs_subst() { + return None; + } + let overflow_check = self.tcx.sess.overflow_checks(); // Perform any special handling for specific Rvalue types. @@ -708,7 +712,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { )) => l.is_bits() && r.is_bits(), interpret::Operand::Indirect(_) if mir_opt_level >= 2 => { let mplace = op.assert_mem_place(&self.ecx); - intern_const_alloc_recursive(&mut self.ecx, None, mplace) + intern_const_alloc_recursive(&mut self.ecx, None, mplace, false) .expect("failed to intern alloc"); true } @@ -797,13 +801,14 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { trace!("visit_constant: {:?}", constant); self.super_constant(constant, location); - self.eval_constant(constant, self.source_info.unwrap()); + self.eval_constant(constant); } fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { trace!("visit_statement: {:?}", statement); let source_info = statement.source_info; self.source_info = Some(source_info); + self.lint_root = self.lint_root(source_info); if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind { let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty; if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { @@ -855,6 +860,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { let source_info = terminator.source_info; self.source_info = Some(source_info); self.super_terminator(terminator, location); + self.lint_root = self.lint_root(source_info); match &mut terminator.kind { TerminatorKind::Assert { expected, ref msg, ref mut cond, .. } => { if let Some(value) = self.eval_operand(&cond, source_info) { diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 00a39905c0232..f8851f7dbdcf0 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -27,7 +27,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_target::spec::abi::Abi; use std::cell::Cell; -use std::{iter, mem, usize}; +use std::{cmp, iter, mem, usize}; use crate::const_eval::{is_const_fn, is_unstable_const_fn}; use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item}; @@ -761,6 +761,7 @@ struct Promoter<'a, 'tcx> { source: &'a mut BodyAndCache<'tcx>, promoted: BodyAndCache<'tcx>, temps: &'a mut IndexVec, + extra_statements: &'a mut Vec<(Location, Statement<'tcx>)>, /// If true, all nested temps are also kept in the /// source MIR, not moved to the promoted MIR. @@ -903,7 +904,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { candidate: Candidate, next_promoted_id: usize, ) -> Option> { - let mut operand = { + let mut rvalue = { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); let tcx = self.tcx; @@ -927,15 +928,70 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { Candidate::Ref(loc) => { let ref mut statement = blocks[loc.block].statements[loc.statement_index]; match statement.kind { - StatementKind::Assign(box (_, Rvalue::Ref(_, _, ref mut place))) => { + StatementKind::Assign(box ( + _, + Rvalue::Ref(ref mut region, borrow_kind, ref mut place), + )) => { // Use the underlying local for this (necessarily interior) borrow. let ty = place.base.ty(local_decls).ty; let span = statement.source_info.span; - Operand::Move(Place { - base: mem::replace(&mut place.base, promoted_place(ty, span).base), - projection: List::empty(), - }) + let ref_ty = tcx.mk_ref( + tcx.lifetimes.re_static, + ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() }, + ); + + promoted.span = span; + promoted.local_decls[RETURN_PLACE] = + LocalDecl::new_return_place(ref_ty, span); + + *region = tcx.lifetimes.re_static; + + let mut projection = vec![PlaceElem::Deref]; + projection.extend(place.projection); + place.projection = tcx.intern_place_elems(&projection); + + // Create a temp to hold the promoted reference. + // This is because `*r` requires `r` to be a local, + // otherwise we would use the `promoted` directly. + let mut promoted_ref = LocalDecl::new_temp(ref_ty, span); + promoted_ref.source_info = statement.source_info; + let promoted_ref = local_decls.push(promoted_ref); + assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref); + + let promoted_ref_rvalue = + Rvalue::Use(Operand::Constant(Box::new(Constant { + span, + user_ty: None, + literal: tcx.mk_const(ty::Const { + ty: ref_ty, + val: ty::ConstKind::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + Some(promoted_id), + ), + }), + }))); + let promoted_ref_statement = Statement { + source_info: statement.source_info, + kind: StatementKind::Assign(Box::new(( + Place::from(promoted_ref), + promoted_ref_rvalue, + ))), + }; + self.extra_statements.push((loc, promoted_ref_statement)); + + Rvalue::Ref( + tcx.lifetimes.re_static, + borrow_kind, + Place { + base: mem::replace( + &mut place.base, + PlaceBase::Local(promoted_ref), + ), + projection: List::empty(), + }, + ) } _ => bug!(), } @@ -946,7 +1002,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { StatementKind::Assign(box (_, Rvalue::Repeat(ref mut operand, _))) => { let ty = operand.ty(local_decls, self.tcx); let span = statement.source_info.span; - mem::replace(operand, Operand::Copy(promoted_place(ty, span))) + Rvalue::Use(mem::replace( + operand, + Operand::Copy(promoted_place(ty, span)), + )) } _ => bug!(), } @@ -958,7 +1017,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let ty = args[index].ty(local_decls, self.tcx); let span = terminator.source_info.span; let operand = Operand::Copy(promoted_place(ty, span)); - mem::replace(&mut args[index], operand) + Rvalue::Use(mem::replace(&mut args[index], operand)) } // We expected a `TerminatorKind::Call` for which we'd like to promote an // argument. `qualify_consts` saw a `TerminatorKind::Call` here, but @@ -975,13 +1034,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { }; assert_eq!(self.new_block(), START_BLOCK); - self.visit_operand( - &mut operand, + self.visit_rvalue( + &mut rvalue, Location { block: BasicBlock::new(0), statement_index: usize::MAX }, ); let span = self.promoted.span; - self.assign(RETURN_PLACE, Rvalue::Use(operand), span); + self.assign(RETURN_PLACE, rvalue, span); Some(self.promoted) } } @@ -1020,6 +1079,7 @@ pub fn promote_candidates<'tcx>( let mut promotions = IndexVec::new(); + let mut extra_statements = vec![]; for candidate in candidates.into_iter().rev() { match candidate { Candidate::Repeat(Location { block, statement_index }) @@ -1043,23 +1103,27 @@ pub fn promote_candidates<'tcx>( let initial_locals = iter::once(LocalDecl::new_return_place(tcx.types.never, body.span)).collect(); + let mut promoted = Body::new( + IndexVec::new(), + // FIXME: maybe try to filter this to avoid blowing up + // memory usage? + body.source_scopes.clone(), + initial_locals, + IndexVec::new(), + 0, + vec![], + body.span, + vec![], + body.generator_kind, + ); + promoted.ignore_interior_mut_in_const_validation = true; + let promoter = Promoter { - promoted: BodyAndCache::new(Body::new( - IndexVec::new(), - // FIXME: maybe try to filter this to avoid blowing up - // memory usage? - body.source_scopes.clone(), - initial_locals, - IndexVec::new(), - 0, - vec![], - body.span, - vec![], - body.generator_kind, - )), + promoted: BodyAndCache::new(promoted), tcx, source: body, temps: &mut temps, + extra_statements: &mut extra_statements, keep_original: false, }; @@ -1069,6 +1133,13 @@ pub fn promote_candidates<'tcx>( } } + // Insert each of `extra_statements` before its indicated location, which + // has to be done in reverse location order, to not invalidate the rest. + extra_statements.sort_by_key(|&(loc, _)| cmp::Reverse(loc)); + for (loc, statement) in extra_statements { + body[loc.block].statements.insert(loc.statement_index, statement); + } + // Eliminate assignments to, and drops of promoted temps. let promoted = |index: Local| temps[index] == TempState::PromotedOut; for block in body.basic_blocks_mut() { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7c7480339a5ee..9c1672f6a7a7d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2697,7 +2697,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let def_id = tcx.hir().local_def_id(ast_const.hir_id); let mut const_ = ty::Const { - val: ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id)), + val: ty::ConstKind::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + None, + ), ty, }; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 874cb9b8a5c9e..089b4bd8445ff 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -460,12 +460,16 @@ pub fn name_from_pat(p: &hir::Pat) -> String { pub fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(def_id, _) => { - if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { + ty::ConstKind::Unevaluated(def_id, _, promoted) => { + let mut s = if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) } else { inline::print_inlined_const(cx, def_id) + }; + if let Some(promoted) = promoted { + s.push_str(&format!("{:?}", promoted)) } + s } _ => { let mut s = n.to_string(); diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index 7d65ad1435e12..a5478a0379111 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -14,7 +14,7 @@ // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}}, align 4 +// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}} getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* @2, i32 0, i32 0, i32 0), {{.*}}, align 8 #[derive(Copy, Clone)] @@ -44,7 +44,7 @@ pub fn inline_enum_const() -> E { #[no_mangle] pub fn low_align_const() -> E { // Check that low_align_const and high_align_const use the same constant -// CHECK: i8* align 2 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), +// CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), align 8 *&E::A(0) } @@ -52,6 +52,6 @@ pub fn low_align_const() -> E { #[no_mangle] pub fn high_align_const() -> E { // Check that low_align_const and high_align_const use the same constant -// CHECK: i8* align 4 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), +// CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), align 8 *&E::A(0) } diff --git a/src/test/run-fail/promoted_div_by_zero.rs b/src/test/compile-fail/promoted_div_by_zero.rs similarity index 57% rename from src/test/run-fail/promoted_div_by_zero.rs rename to src/test/compile-fail/promoted_div_by_zero.rs index 3fe51a19c20bb..de55b5360f31d 100644 --- a/src/test/run-fail/promoted_div_by_zero.rs +++ b/src/test/compile-fail/promoted_div_by_zero.rs @@ -1,6 +1,6 @@ #![allow(const_err)] -// error-pattern: attempt to divide by zero +// error-pattern: referenced constant has errors fn main() { let x = &(1 / (1 - 1)); diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs index d45ffdc877535..6b5101af5fcd8 100644 --- a/src/test/mir-opt/const_prop/ref_deref.rs +++ b/src/test/mir-opt/const_prop/ref_deref.rs @@ -6,7 +6,8 @@ fn main() { // START rustc.main.ConstProp.before.mir // bb0: { // ... -// _2 = &(promoted[0]: i32); +// _4 = const main::promoted[0]; +// _2 = _4; // _1 = (*_2); // ... //} @@ -14,7 +15,8 @@ fn main() { // START rustc.main.ConstProp.after.mir // bb0: { // ... -// _2 = &(promoted[0]: i32); +// _4 = const main::promoted[0]; +// _2 = _4; // _1 = const 4i32; // ... // } diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs index d6ff76b34b9b5..43813e43d3681 100644 --- a/src/test/mir-opt/const_prop/slice_len.rs +++ b/src/test/mir-opt/const_prop/slice_len.rs @@ -6,7 +6,8 @@ fn main() { // START rustc.main.ConstProp.before.mir // bb0: { // ... -// _4 = &(promoted[0]: [u32; 3]); +// _9 = const main::promoted[0]; +// _4 = _9; // _3 = _4; // _2 = move _3 as &[u32] (Pointer(Unsize)); // ... @@ -24,7 +25,8 @@ fn main() { // START rustc.main.ConstProp.after.mir // bb0: { // ... -// _4 = &(promoted[0]: [u32; 3]); +// _9 = const main::promoted[0]; +// _4 = _9; // _3 = _4; // _2 = move _3 as &[u32] (Pointer(Unsize)); // ... diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline-retag.rs index 6cdbcfdb0add7..7b78fc339f2c1 100644 --- a/src/test/mir-opt/inline/inline-retag.rs +++ b/src/test/mir-opt/inline/inline-retag.rs @@ -25,11 +25,11 @@ fn foo(x: &i32, y: &i32) -> bool { // ... // Retag(_3); // Retag(_6); -// StorageLive(_9); -// _9 = (*_3); -// StorageLive(_10); -// _10 = (*_6); -// _0 = Eq(move _9, move _10); +// StorageLive(_11); +// _11 = (*_3); +// StorageLive(_12); +// _12 = (*_6); +// _0 = Eq(move _11, move _12); // ... // return; // } diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 648856b5523d3..2c20c35e4a491 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -65,7 +65,8 @@ fn main() { // } // bb6: { // binding1 and guard // StorageLive(_6); -// _6 = &(((promoted[0]: std::option::Option) as Some).0: i32); +// _11 = const full_tested_match::promoted[0]; +// _6 = &(((*_11) as Some).0: i32); // _4 = &shallow _2; // StorageLive(_7); // _7 = const guard() -> [return: bb7, unwind: bb1]; diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs index 1de6bafd293cf..59b2fdb78216e 100644 --- a/src/test/ui/consts/array-literal-index-oob.rs +++ b/src/test/ui/consts/array-literal-index-oob.rs @@ -4,4 +4,5 @@ fn main() { &{[1, 2, 3][4]}; //~^ ERROR index out of bounds //~| ERROR reaching this expression at runtime will panic or abort + //~| ERROR erroneous constant used [E0080] } diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr index f3ef16659dd3e..261c10d1391ad 100644 --- a/src/test/ui/consts/array-literal-index-oob.stderr +++ b/src/test/ui/consts/array-literal-index-oob.stderr @@ -14,5 +14,12 @@ LL | &{[1, 2, 3][4]}; | | | indexing out of bounds: the len is 3 but the index is 4 -error: aborting due to 2 previous errors +error[E0080]: erroneous constant used + --> $DIR/array-literal-index-oob.rs:4:5 + | +LL | &{[1, 2, 3][4]}; + | ^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.rs b/src/test/ui/consts/const-eval/conditional_array_execution.rs index 96f67c92a5e93..107d0817dafc8 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.rs +++ b/src/test/ui/consts/const-eval/conditional_array_execution.rs @@ -10,4 +10,5 @@ const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; fn main() { println!("{}", FOO); //~^ ERROR + //~| ERROR erroneous constant used [E0080] } diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index ec18f8f011d61..f161ab6f19892 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -18,6 +18,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{}", FOO); | ^^^ referenced constant has errors -error: aborting due to previous error +error[E0080]: erroneous constant used + --> $DIR/conditional_array_execution.rs:11:20 + | +LL | println!("{}", FOO); + | ^^^ referenced constant has errors + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs index a5f04d088b611..21dbe72418a72 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -17,6 +17,8 @@ const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday fn main() { assert_eq!(Y, 4); //~^ ERROR evaluation of constant expression failed + //~| ERROR erroneous constant used [E0080] assert_eq!(Z, 4); //~^ ERROR evaluation of constant expression failed + //~| ERROR erroneous constant used [E0080] } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 19f37fa00795c..ebbd18bbd253b 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -14,8 +14,16 @@ LL | assert_eq!(Y, 4); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) +error[E0080]: erroneous constant used + --> $DIR/const_fn_ptr_fail2.rs:18:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^^ referenced constant has errors + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:20:5 + --> $DIR/const_fn_ptr_fail2.rs:21:5 | LL | assert_eq!(Z, 4); | ^^^^^^^^^^^-^^^^^ @@ -24,6 +32,14 @@ LL | assert_eq!(Z, 4); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to 2 previous errors +error[E0080]: erroneous constant used + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^^ referenced constant has errors + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-43197.rs b/src/test/ui/consts/const-eval/issue-43197.rs index 849c81ad449b5..23890be693431 100644 --- a/src/test/ui/consts/const-eval/issue-43197.rs +++ b/src/test/ui/consts/const-eval/issue-43197.rs @@ -14,4 +14,6 @@ fn main() { println!("{} {}", X, Y); //~^ ERROR evaluation of constant expression failed //~| ERROR evaluation of constant expression failed + //~| ERROR erroneous constant used [E0080] + //~| ERROR erroneous constant used [E0080] } diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index a1b3a05ed4169..50bc07d459c78 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -26,12 +26,24 @@ error[E0080]: evaluation of constant expression failed LL | println!("{} {}", X, Y); | ^ referenced constant has errors +error[E0080]: erroneous constant used + --> $DIR/issue-43197.rs:14:23 + | +LL | println!("{} {}", X, Y); + | ^ referenced constant has errors + error[E0080]: evaluation of constant expression failed --> $DIR/issue-43197.rs:14:26 | LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error: aborting due to 2 previous errors +error[E0080]: erroneous constant used + --> $DIR/issue-43197.rs:14:26 + | +LL | println!("{} {}", X, Y); + | ^ referenced constant has errors + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index 7da9256bb398f..607f78f70b308 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -25,5 +25,6 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR E0080 + //~^ ERROR erroneous constant used [E0080] + //~| ERROR evaluation of constant expression failed [E0080] } diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index f4323713e682b..5c0ac17acebe6 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors -error: aborting due to previous error +error[E0080]: erroneous constant used + --> $DIR/issue-44578.rs:27:20 + | +LL | println!("{}", as Foo>::AMT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-50814.rs b/src/test/ui/consts/const-eval/issue-50814.rs index e589126a9429c..5c3635e4650cd 100644 --- a/src/test/ui/consts/const-eval/issue-50814.rs +++ b/src/test/ui/consts/const-eval/issue-50814.rs @@ -12,11 +12,13 @@ impl Unsigned for U8 { struct Sum(A,B); impl Unsigned for Sum { - const MAX: u8 = A::MAX + B::MAX; //~ ERROR any use of this value will cause an error + const MAX: u8 = A::MAX + B::MAX; + //~^ ERROR any use of this value will cause an error [const_err] } fn foo(_: T) -> &'static u8 { - &Sum::::MAX //~ ERROR E0080 + &Sum::::MAX + //~^ ERROR E0080 } fn main() { diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index f8b017e4b53a1..2e5167a99a2c6 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -9,7 +9,7 @@ LL | const MAX: u8 = A::MAX + B::MAX; = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant expression failed - --> $DIR/issue-50814.rs:19:5 + --> $DIR/issue-50814.rs:20:5 | LL | &Sum::::MAX | ^----------------- diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index 2eed8ca7d322c..6d83839a8d1cd 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -10,11 +10,13 @@ fn main() { println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR const_err + //~| ERROR erroneous constant used [E0080] let _x = 1/(1-1); //~^ ERROR const_err println!("{}", 1/(false as u32)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR const_err + //~| ERROR erroneous constant used [E0080] let _x = 1/(false as u32); //~^ ERROR const_err } diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 8f17ef05f2356..32672ca856641 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -22,29 +22,42 @@ error: reaching this expression at runtime will panic or abort LL | println!("{}", 1/(1-1)); | ^^^^^^^ dividing by zero +error[E0080]: erroneous constant used + --> $DIR/promoted_errors.rs:10:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ referenced constant has errors + error: attempt to divide by zero - --> $DIR/promoted_errors.rs:13:14 + --> $DIR/promoted_errors.rs:14:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: attempt to divide by zero - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ dividing by zero +error[E0080]: erroneous constant used + --> $DIR/promoted_errors.rs:16:20 + | +LL | println!("{}", 1/(false as u32)); + | ^^^^^^^^^^^^^^^^ referenced constant has errors + error: attempt to divide by zero - --> $DIR/promoted_errors.rs:18:14 + --> $DIR/promoted_errors.rs:20:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs index ae680b4f1072e..8ea6cdf6a8f61 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.rs +++ b/src/test/ui/consts/const-eval/promoted_errors2.rs @@ -11,11 +11,13 @@ fn main() { println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR const_err + //~| ERROR erroneous constant used [E0080] let _x = 1/(1-1); //~^ ERROR const_err println!("{}", 1/(false as u32)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR const_err + //~| ERROR erroneous constant used [E0080] let _x = 1/(false as u32); //~^ ERROR const_err } diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr index 60a3cba6e1ff5..e7a73aa8118e3 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr @@ -28,29 +28,42 @@ error: reaching this expression at runtime will panic or abort LL | println!("{}", 1/(1-1)); | ^^^^^^^ dividing by zero +error[E0080]: erroneous constant used + --> $DIR/promoted_errors2.rs:11:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ referenced constant has errors + error: attempt to divide by zero - --> $DIR/promoted_errors2.rs:14:14 + --> $DIR/promoted_errors2.rs:15:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: attempt to divide by zero - --> $DIR/promoted_errors2.rs:16:20 + --> $DIR/promoted_errors2.rs:17:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors2.rs:16:20 + --> $DIR/promoted_errors2.rs:17:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ dividing by zero +error[E0080]: erroneous constant used + --> $DIR/promoted_errors2.rs:17:20 + | +LL | println!("{}", 1/(false as u32)); + | ^^^^^^^^^^^^^^^^ referenced constant has errors + error: attempt to divide by zero - --> $DIR/promoted_errors2.rs:19:14 + --> $DIR/promoted_errors2.rs:21:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index 80d80a986751e..c2446d1404019 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! LL | | let out_of_bounds_ptr = &ptr[255]; - | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 6 which has size 1 + | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1 LL | | mem::transmute(out_of_bounds_ptr) LL | | } }; | |____- diff --git a/src/test/ui/consts/miri_unleashed/non_const_fn.rs b/src/test/ui/consts/miri_unleashed/non_const_fn.rs index 32a713ebaa44e..23b0cfa83211f 100644 --- a/src/test/ui/consts/miri_unleashed/non_const_fn.rs +++ b/src/test/ui/consts/miri_unleashed/non_const_fn.rs @@ -11,5 +11,7 @@ const C: () = foo(); //~ WARN: skipping const checks //~^ WARN any use of this value will cause an error fn main() { - println!("{:?}", C); //~ ERROR: evaluation of constant expression failed + println!("{:?}", C); + //~^ ERROR: evaluation of constant expression failed + //~| ERROR: erroneous constant used [E0080] } diff --git a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr index 75f532a81bdc3..a7364ddf72c87 100644 --- a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr +++ b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr @@ -24,6 +24,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{:?}", C); | ^ referenced constant has errors -error: aborting due to previous error +error[E0080]: erroneous constant used + --> $DIR/non_const_fn.rs:14:22 + | +LL | println!("{:?}", C); + | ^ referenced constant has errors + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/zst_no_llvm_alloc.rs b/src/test/ui/consts/zst_no_llvm_alloc.rs index 5d779355400cc..2a41f708c2b87 100644 --- a/src/test/ui/consts/zst_no_llvm_alloc.rs +++ b/src/test/ui/consts/zst_no_llvm_alloc.rs @@ -7,13 +7,15 @@ static FOO: Foo = Foo; fn main() { let x: &'static () = &(); - assert_eq!(x as *const () as usize, 1); + assert_ne!(x as *const () as usize, 1); let x: &'static Foo = &Foo; - assert_eq!(x as *const Foo as usize, 4); + assert_ne!(x as *const Foo as usize, 4); // statics must have a unique address assert_ne!(&FOO as *const Foo as usize, 4); - assert_eq!(>::new().as_ptr(), <&[i32]>::default().as_ptr()); - assert_eq!(>::default().as_ptr(), (&[]).as_ptr()); + // FIXME this two tests should be assert_eq! + // this stopped working since we are promoting to constants instead of statics + assert_ne!(>::new().as_ptr(), <&[i32]>::default().as_ptr()); + assert_ne!(>::default().as_ptr(), (&[]).as_ptr()); } diff --git a/src/test/ui/invalid_const_promotion.rs b/src/test/ui/invalid_const_promotion.rs deleted file mode 100644 index 5d7664cefb33a..0000000000000 --- a/src/test/ui/invalid_const_promotion.rs +++ /dev/null @@ -1,61 +0,0 @@ -// run-pass - -#![allow(unused_mut)] -// ignore-wasm32 -// ignore-emscripten -// ignore-sgx no processes - -// compile-flags: -C debug_assertions=yes - -#![stable(feature = "rustc", since = "1.0.0")] -#![feature(const_fn, rustc_private, staged_api, rustc_attrs)] -#![allow(const_err)] - -extern crate libc; - -use std::env; -use std::process::{Command, Stdio}; - -// this will panic in debug mode and overflow in release mode -// -// NB we give bar an unused argument because otherwise memoization -// of the const fn kicks in, causing a different code path in the -// compiler to be executed (see PR #66294). -#[stable(feature = "rustc", since = "1.0.0")] -#[rustc_const_stable(feature = "rustc", since = "1.0.0")] -#[rustc_promotable] -const fn bar(_: bool) -> usize { 0 - 1 } - -fn foo() { - let _: &'static _ = &bar(true); -} - -#[cfg(unix)] -fn check_status(status: std::process::ExitStatus) -{ - use std::os::unix::process::ExitStatusExt; - - assert!(status.signal() == Some(libc::SIGILL) - || status.signal() == Some(libc::SIGTRAP) - || status.signal() == Some(libc::SIGABRT)); -} - -#[cfg(not(unix))] -fn check_status(status: std::process::ExitStatus) -{ - assert!(!status.success()); -} - -fn main() { - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "test" { - foo(); - return; - } - - let mut p = Command::new(&args[0]) - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .arg("test").output().unwrap(); - check_status(p.status); -} diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index 53ab2f9878f30..affb5537b1856 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -46,13 +46,13 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h92c563325b7ff21aE) +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17hf07584432cd4d8beE) --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::h92c563325b7ff21a) +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::hf07584432cd4d8be) --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] From 2508f17ac2d8c645ab8127cea87c8e3e77d1053a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 10 Dec 2019 20:40:29 -0300 Subject: [PATCH 0146/1253] Promote `Repeat`s to constants instead of statics --- src/librustc_mir/transform/promote_consts.rs | 23 ++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index f8851f7dbdcf0..e160e922f4c44 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -1002,10 +1002,25 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { StatementKind::Assign(box (_, Rvalue::Repeat(ref mut operand, _))) => { let ty = operand.ty(local_decls, self.tcx); let span = statement.source_info.span; - Rvalue::Use(mem::replace( - operand, - Operand::Copy(promoted_place(ty, span)), - )) + + promoted.span = span; + promoted.local_decls[RETURN_PLACE] = + LocalDecl::new_return_place(ty, span); + + let promoted_operand = Operand::Constant(Box::new(Constant { + span, + user_ty: None, + literal: tcx.mk_const(ty::Const { + ty, + val: ty::ConstKind::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + Some(promoted_id), + ), + }), + })); + + Rvalue::Use(mem::replace(operand, promoted_operand)) } _ => bug!(), } From 32fe47779b169cd8d637cfae3b130e004008e6f3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 00:09:49 -0300 Subject: [PATCH 0147/1253] Promote `Argument`s to constants instead of statics --- src/librustc_mir/transform/promote_consts.rs | 36 +++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index e160e922f4c44..a607383f77789 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -908,21 +908,6 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); let tcx = self.tcx; - let mut promoted_place = |ty, span| { - promoted.span = span; - promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); - Place { - base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted( - promoted_id, - InternalSubsts::identity_for_item(tcx, def_id), - ), - ty, - def_id, - }), - projection: List::empty(), - } - }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { Candidate::Ref(loc) => { @@ -1031,8 +1016,25 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { TerminatorKind::Call { ref mut args, .. } => { let ty = args[index].ty(local_decls, self.tcx); let span = terminator.source_info.span; - let operand = Operand::Copy(promoted_place(ty, span)); - Rvalue::Use(mem::replace(&mut args[index], operand)) + + promoted.span = span; + promoted.local_decls[RETURN_PLACE] = + LocalDecl::new_return_place(ty, span); + + let promoted_operand = Operand::Constant(Box::new(Constant { + span, + user_ty: None, + literal: tcx.mk_const(ty::Const { + ty, + val: ty::ConstKind::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + Some(promoted_id), + ), + }), + })); + + Rvalue::Use(mem::replace(&mut args[index], promoted_operand)) } // We expected a `TerminatorKind::Call` for which we'd like to promote an // argument. `qualify_consts` saw a `TerminatorKind::Call` here, but From 6aa4b5a7603efc7a6f323e1be9be67ecf8f5f227 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 00:11:12 -0300 Subject: [PATCH 0148/1253] Add promoted_operand closure to reuse code across different --- src/librustc_mir/transform/promote_consts.rs | 74 ++++++-------------- 1 file changed, 20 insertions(+), 54 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index a607383f77789..1052d037326b4 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -908,6 +908,23 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); let tcx = self.tcx; + let mut promoted_operand = |ty, span| { + promoted.span = span; + promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); + + Operand::Constant(Box::new(Constant { + span, + user_ty: None, + literal: tcx.mk_const(ty::Const { + ty, + val: ty::ConstKind::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + Some(promoted_id), + ), + }), + })) + }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { Candidate::Ref(loc) => { @@ -926,10 +943,6 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() }, ); - promoted.span = span; - promoted.local_decls[RETURN_PLACE] = - LocalDecl::new_return_place(ref_ty, span); - *region = tcx.lifetimes.re_static; let mut projection = vec![PlaceElem::Deref]; @@ -944,24 +957,11 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let promoted_ref = local_decls.push(promoted_ref); assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref); - let promoted_ref_rvalue = - Rvalue::Use(Operand::Constant(Box::new(Constant { - span, - user_ty: None, - literal: tcx.mk_const(ty::Const { - ty: ref_ty, - val: ty::ConstKind::Unevaluated( - def_id, - InternalSubsts::identity_for_item(tcx, def_id), - Some(promoted_id), - ), - }), - }))); let promoted_ref_statement = Statement { source_info: statement.source_info, kind: StatementKind::Assign(Box::new(( Place::from(promoted_ref), - promoted_ref_rvalue, + Rvalue::Use(promoted_operand(ref_ty, span)), ))), }; self.extra_statements.push((loc, promoted_ref_statement)); @@ -988,24 +988,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let ty = operand.ty(local_decls, self.tcx); let span = statement.source_info.span; - promoted.span = span; - promoted.local_decls[RETURN_PLACE] = - LocalDecl::new_return_place(ty, span); - - let promoted_operand = Operand::Constant(Box::new(Constant { - span, - user_ty: None, - literal: tcx.mk_const(ty::Const { - ty, - val: ty::ConstKind::Unevaluated( - def_id, - InternalSubsts::identity_for_item(tcx, def_id), - Some(promoted_id), - ), - }), - })); - - Rvalue::Use(mem::replace(operand, promoted_operand)) + Rvalue::Use(mem::replace(operand, promoted_operand(ty, span))) } _ => bug!(), } @@ -1017,24 +1000,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let ty = args[index].ty(local_decls, self.tcx); let span = terminator.source_info.span; - promoted.span = span; - promoted.local_decls[RETURN_PLACE] = - LocalDecl::new_return_place(ty, span); - - let promoted_operand = Operand::Constant(Box::new(Constant { - span, - user_ty: None, - literal: tcx.mk_const(ty::Const { - ty, - val: ty::ConstKind::Unevaluated( - def_id, - InternalSubsts::identity_for_item(tcx, def_id), - Some(promoted_id), - ), - }), - })); - - Rvalue::Use(mem::replace(&mut args[index], promoted_operand)) + Rvalue::Use(mem::replace(&mut args[index], promoted_operand(ty, span))) } // We expected a `TerminatorKind::Call` for which we'd like to promote an // argument. `qualify_consts` saw a `TerminatorKind::Call` here, but From 6f2c7025b8192d68a082b153b9574d5df452ca8a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 01:27:33 -0300 Subject: [PATCH 0149/1253] Remove StaticKind::Promoted --- src/librustc/mir/mod.rs | 25 ++------ src/librustc_codegen_ssa/mir/block.rs | 32 +--------- src/librustc_codegen_ssa/mir/place.rs | 35 +---------- .../borrow_check/diagnostics/mod.rs | 6 -- src/librustc_mir/borrow_check/mod.rs | 10 ---- .../borrow_check/places_conflict.rs | 24 +------- .../borrow_check/type_check/mod.rs | 59 +++++++------------ src/librustc_mir/interpret/place.rs | 19 +----- src/librustc_mir/monomorphize/collector.rs | 17 +----- src/librustc_mir/transform/check_unsafety.rs | 3 - 10 files changed, 33 insertions(+), 197 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0f909dc148fcb..2a33e91a69f08 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1687,7 +1687,7 @@ pub enum PlaceBase<'tcx> { )] pub struct Static<'tcx> { pub ty: Ty<'tcx>, - pub kind: StaticKind<'tcx>, + pub kind: StaticKind, /// The `DefId` of the item this static was declared in. For promoted values, usually, this is /// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in. /// However, after inlining, that might no longer be the case as inlined `Place`s are copied @@ -1707,11 +1707,7 @@ pub struct Static<'tcx> { RustcEncodable, RustcDecodable )] -pub enum StaticKind<'tcx> { - /// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize - /// it. Usually, these substs are just the identity substs for the item. However, the inliner - /// will adjust these substs when it inlines a function based on the substs at the callsite. - Promoted(Promoted, SubstsRef<'tcx>), +pub enum StaticKind { Static, } @@ -1949,11 +1945,6 @@ impl Debug for PlaceBase<'_> { PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static, def_id }) => { write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) } - PlaceBase::Static(box self::Static { - ty, - kind: StaticKind::Promoted(promoted, _), - def_id: _, - }) => write!(fmt, "({:?}: {:?})", promoted, ty), } } } @@ -3069,21 +3060,15 @@ impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for StaticKind<'tcx> { - fn super_fold_with>(&self, folder: &mut F) -> Self { +impl<'tcx> TypeFoldable<'tcx> for StaticKind { + fn super_fold_with>(&self, _folder: &mut F) -> Self { match self { - StaticKind::Promoted(promoted, substs) => { - StaticKind::Promoted(promoted.fold_with(folder), substs.fold_with(folder)) - } StaticKind::Static => StaticKind::Static, } } - fn super_visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, _visitor: &mut V) -> bool { match self { - StaticKind::Promoted(promoted, substs) => { - promoted.visit_with(visitor) || substs.visit_with(visitor) - } StaticKind::Static => false, } } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index a1d4c0c820bc6..ecb3eb05f1163 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -10,8 +10,8 @@ use crate::traits::*; use crate::MemFlags; use rustc::middle::lang_items; +use rustc::mir; use rustc::mir::interpret::PanicInfo; -use rustc::mir::{self, PlaceBase, Static, StaticKind}; use rustc::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf}; use rustc::ty::{self, Instance, Ty, TypeFoldable}; use rustc_index::vec::Idx; @@ -613,35 +613,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // The shuffle array argument is usually not an explicit constant, // but specified directly in the code. This means it gets promoted // and we can then extract the value by evaluating the promoted. - mir::Operand::Copy(place) | mir::Operand::Move(place) => { - if let mir::PlaceRef { - base: - &PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted, substs), - ty, - def_id, - }), - projection: &[], - } = place.as_ref() - { - let c = bx.tcx().const_eval_promoted( - Instance::new(def_id, self.monomorphize(&substs)), - promoted, - ); - let (llval, ty) = self.simd_shuffle_indices( - &bx, - terminator.source_info.span, - ty, - c, - ); - return OperandRef { - val: Immediate(llval), - layout: bx.layout_of(ty), - }; - } else { - span_bug!(span, "shuffle indices must be constant"); - } - } + mir::Operand::Copy(_place) | mir::Operand::Move(_place) => {} mir::Operand::Constant(constant) => { let c = self.eval_mir_constant(constant); diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 7399db1f2b950..639a98107cd56 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -9,7 +9,7 @@ use crate::MemFlags; use rustc::mir; use rustc::mir::tcx::PlaceTy; use rustc::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyLayout, VariantIdx}; -use rustc::ty::{self, Instance, Ty}; +use rustc::ty::{self, Ty}; #[derive(Copy, Clone, Debug)] pub struct PlaceRef<'tcx, V> { @@ -437,39 +437,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - mir::PlaceRef { - base: - mir::PlaceBase::Static(box mir::Static { - ty, - kind: mir::StaticKind::Promoted(promoted, substs), - def_id, - }), - projection: [], - } => { - let instance = Instance::new(*def_id, self.monomorphize(substs)); - let layout = cx.layout_of(self.monomorphize(&ty)); - match bx.tcx().const_eval_promoted(instance, *promoted) { - Ok(val) => match val.val { - ty::ConstKind::Value(mir::interpret::ConstValue::ByRef { - alloc, - offset, - }) => bx.cx().from_const_alloc(layout, alloc, offset), - _ => bug!("promoteds should have an allocation: {:?}", val), - }, - Err(_) => { - // This is unreachable as long as runtime - // and compile-time agree perfectly. - // With floats that won't always be true, - // so we generate a (safe) abort. - bx.abort(); - // We still have to return a place but it doesn't matter, - // this code is unreachable. - let llval = - bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))); - PlaceRef::new_sized(llval, layout) - } - } - } mir::PlaceRef { base: mir::PlaceBase::Static(box mir::Static { diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index c8a59331f31af..d1c6ee8af5830 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -172,12 +172,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { PlaceRef { base: PlaceBase::Local(local), projection: [] } => { self.append_local_to_string(*local, buf)?; } - PlaceRef { - base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }), - projection: [], - } => { - buf.push_str("promoted"); - } PlaceRef { base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), projection: [], diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index fff6f036da082..238a59490906c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -2196,16 +2196,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }), } } - // The rules for promotion are made by `qualify_consts`, there wouldn't even be a - // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this - PlaceRef { - base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }), - projection: [], - } => Ok(RootPlace { - place_base: place.base, - place_projection: place.projection, - is_local_mutation_allowed, - }), PlaceRef { base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), projection: [], diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 64103719fe925..422bcd2b75c25 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -310,7 +310,7 @@ fn place_components_conflict<'tcx>( // between `elem1` and `elem2`. fn place_base_conflict<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + _param_env: ty::ParamEnv<'tcx>, elem1: &PlaceBase<'tcx>, elem2: &PlaceBase<'tcx>, ) -> Overlap { @@ -341,28 +341,6 @@ fn place_base_conflict<'tcx>( Overlap::EqualOrDisjoint } } - (StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => { - if promoted_1 == promoted_2 { - if let ty::Array(_, len) = s1.ty.kind { - if let Some(0) = len.try_eval_usize(tcx, param_env) { - // Ignore conflicts with promoted [T; 0]. - debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); - return Overlap::Disjoint; - } - } - // the same promoted - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); - Overlap::EqualOrDisjoint - } else { - // different promoteds - base case, disjoint - debug!("place_element_conflict: DISJOINT-PROMOTED"); - Overlap::Disjoint - } - } - (_, _) => { - debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); - Overlap::Disjoint - } } } (PlaceBase::Local(_), PlaceBase::Static(_)) diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index fa6ce3aa4a1f7..f66af1f04a360 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -488,15 +488,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }; }; match kind { - StaticKind::Promoted(promoted, _) => { - if !self.errors_reported { - let promoted_body_cache = self.promoted[*promoted]; - self.sanitize_promoted(promoted_body_cache, location); - - let promoted_ty = promoted_body_cache.return_ty(); - check_err(self, place, promoted_ty, san_ty); - } - } StaticKind::Static => { let ty = self.tcx().type_of(*def_id); let ty = self.cx.normalize(ty, location); @@ -510,38 +501,28 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if place.projection.is_empty() { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { - let is_promoted = match place.as_ref() { - PlaceRef { - base: &PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }), - projection: &[], - } => true, - _ => false, + let tcx = self.tcx(); + let trait_ref = ty::TraitRef { + def_id: tcx.lang_items().copy_trait().unwrap(), + substs: tcx.mk_substs_trait(place_ty.ty, &[]), }; - if !is_promoted { - let tcx = self.tcx(); - let trait_ref = ty::TraitRef { - def_id: tcx.lang_items().copy_trait().unwrap(), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), - }; - - // To have a `Copy` operand, the type `T` of the - // value must be `Copy`. Note that we prove that `T: Copy`, - // rather than using the `is_copy_modulo_regions` - // test. This is important because - // `is_copy_modulo_regions` ignores the resulting region - // obligations and assumes they pass. This can result in - // bounds from `Copy` impls being unsoundly ignored (e.g., - // #29149). Note that we decide to use `Copy` before knowing - // whether the bounds fully apply: in effect, the rule is - // that if a value of some type could implement `Copy`, then - // it must. - self.cx.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::CopyBound, - ); - } + // To have a `Copy` operand, the type `T` of the + // value must be `Copy`. Note that we prove that `T: Copy`, + // rather than using the `is_copy_modulo_regions` + // test. This is important because + // `is_copy_modulo_regions` ignores the resulting region + // obligations and assumes they pass. This can result in + // bounds from `Copy` impls being unsoundly ignored (e.g., + // #29149). Note that we decide to use `Copy` before knowing + // whether the bounds fully apply: in effect, the rule is + // that if a value of some type could implement `Copy`, then + // it must. + self.cx.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::CopyBound, + ); } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 890627a54543a..79411d872a959 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -15,9 +15,9 @@ use rustc::ty::{self, Ty}; use rustc_macros::HashStable; use super::{ - AllocId, AllocMap, Allocation, AllocationExtra, GlobalId, ImmTy, Immediate, InterpCx, - InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, - RawConst, Scalar, ScalarMaybeUndef, + AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, Immediate, InterpCx, InterpResult, + LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, RawConst, Scalar, + ScalarMaybeUndef, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -628,19 +628,6 @@ where use rustc::mir::StaticKind; Ok(match place_static.kind { - StaticKind::Promoted(promoted, promoted_substs) => { - let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs); - let instance = ty::Instance::new(place_static.def_id, substs); - - // Even after getting `substs` from the frame, this instance may still be - // polymorphic because `ConstProp` will try to promote polymorphic MIR. - if instance.needs_subst() { - throw_inval!(TooGeneric); - } - - self.const_eval_raw(GlobalId { instance, promoted: Some(promoted) })? - } - StaticKind::Static => { let ty = place_static.ty; assert!(!ty.needs_subst()); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 99df9456a6f4b..84b641a763a02 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -186,7 +186,7 @@ use rustc::mir::{self, Location, PlaceBase, Static, StaticKind}; use rustc::session::config::EntryFnType; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::print::obsolete::DefPathBasedNames; -use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; +use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; @@ -656,21 +656,6 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.output.push(MonoItem::Static(*def_id)); } } - PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted, substs), - def_id, - .. - }) => { - let instance = Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)); - match self.tcx.const_eval_promoted(instance, *promoted) { - Ok(val) => collect_const(self.tcx, val, substs, self.output), - Err(ErrorHandled::Reported) => {} - Err(ErrorHandled::TooGeneric) => { - let span = self.tcx.promoted_mir(*def_id)[*promoted].span; - span_bug!(span, "collection encountered polymorphic constant") - } - } - } PlaceBase::Local(_) => { // Locals have no relevance for collector. } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 02c54803842f0..88fce075d7c02 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -194,9 +194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { PlaceBase::Local(..) => { // Locals are safe. } - PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => { - bug!("unsafety checking should happen before promotion"); - } PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => { bug!("StaticKind::Static should not exist"); } From b63597dedba1c94a1fa9f2521ce50723cc019e78 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 01:53:46 -0300 Subject: [PATCH 0150/1253] Remove StaticKind --- src/librustc/mir/mod.rs | 43 ++--------------- src/librustc/mir/visit.rs | 2 +- src/librustc_codegen_ssa/mir/place.rs | 7 +-- .../borrow_check/diagnostics/mod.rs | 9 ++-- src/librustc_mir/borrow_check/mod.rs | 7 +-- .../borrow_check/places_conflict.rs | 28 +++++------ .../borrow_check/type_check/mod.rs | 12 ++--- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/place.rs | 48 ++++++++----------- src/librustc_mir/monomorphize/collector.rs | 4 +- src/librustc_mir/transform/check_unsafety.rs | 4 +- src/librustc_mir/transform/promote_consts.rs | 2 +- 12 files changed, 53 insertions(+), 115 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 2a33e91a69f08..42d24d9f332b4 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1687,7 +1687,6 @@ pub enum PlaceBase<'tcx> { )] pub struct Static<'tcx> { pub ty: Ty<'tcx>, - pub kind: StaticKind, /// The `DefId` of the item this static was declared in. For promoted values, usually, this is /// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in. /// However, after inlining, that might no longer be the case as inlined `Place`s are copied @@ -1695,22 +1694,6 @@ pub struct Static<'tcx> { pub def_id: DefId, } -#[derive( - Clone, - Debug, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - HashStable, - RustcEncodable, - RustcDecodable -)] -pub enum StaticKind { - Static, -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(RustcEncodable, RustcDecodable, HashStable)] pub enum ProjectionElem { @@ -1942,7 +1925,7 @@ impl Debug for PlaceBase<'_> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { match *self { PlaceBase::Local(id) => write!(fmt, "{:?}", id), - PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static, def_id }) => { + PlaceBase::Static(box self::Static { ty, def_id }) => { write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) } } @@ -3046,31 +3029,13 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - Static { - ty: self.ty.fold_with(folder), - kind: self.kind.fold_with(folder), - def_id: self.def_id, - } + Static { ty: self.ty.fold_with(folder), def_id: self.def_id } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - let Static { ty, kind, def_id: _ } = self; - - ty.visit_with(visitor) || kind.visit_with(visitor) - } -} + let Static { ty, def_id: _ } = self; -impl<'tcx> TypeFoldable<'tcx> for StaticKind { - fn super_fold_with>(&self, _folder: &mut F) -> Self { - match self { - StaticKind::Static => StaticKind::Static, - } - } - - fn super_visit_with>(&self, _visitor: &mut V) -> bool { - match self { - StaticKind::Static => false, - } + ty.visit_with(visitor) } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 9173c32800641..3924a1aa47eda 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -712,7 +712,7 @@ macro_rules! make_mir_visitor { PlaceBase::Local(local) => { self.visit_local(local, context, location); } - PlaceBase::Static(box Static { kind: _, ty, def_id: _ }) => { + PlaceBase::Static(box Static { ty, def_id: _ }) => { self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); } } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 639a98107cd56..49c3edbb2b3df 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -438,12 +438,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::PlaceRef { - base: - mir::PlaceBase::Static(box mir::Static { - ty, - kind: mir::StaticKind::Static, - def_id, - }), + base: mir::PlaceBase::Static(box mir::Static { ty, def_id }), projection: [], } => { // NB: The layout of a static may be unsized as is the case when working diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index d1c6ee8af5830..8ef4273a2f6a5 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -2,8 +2,8 @@ use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Static, StaticKind, - Terminator, TerminatorKind, + PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Static, Terminator, + TerminatorKind, }; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; @@ -172,10 +172,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { PlaceRef { base: PlaceBase::Local(local), projection: [] } => { self.append_local_to_string(*local, buf)?; } - PlaceRef { - base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), - projection: [], - } => { + PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => { buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string()); } PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 238a59490906c..6c9b811ebd0a8 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -5,7 +5,7 @@ use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, - PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static, StaticKind, + PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static, }; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -2196,10 +2196,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }), } } - PlaceRef { - base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), - projection: [], - } => { + PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => { if !self.infcx.tcx.is_mutable_static(*def_id) { Err(place) } else { diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 422bcd2b75c25..815ace55a3721 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -1,9 +1,7 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; use crate::borrow_check::{AccessDepth, Deep, Shallow}; -use rustc::mir::{ - Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem, StaticKind, -}; +use rustc::mir::{Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; use std::cmp::max; @@ -327,20 +325,16 @@ fn place_base_conflict<'tcx>( } } (PlaceBase::Static(s1), PlaceBase::Static(s2)) => { - match (&s1.kind, &s2.kind) { - (StaticKind::Static, StaticKind::Static) => { - if s1.def_id != s2.def_id { - debug!("place_element_conflict: DISJOINT-STATIC"); - Overlap::Disjoint - } else if tcx.is_mutable_static(s1.def_id) { - // We ignore mutable statics - they can only be unsafe code. - debug!("place_element_conflict: IGNORE-STATIC-MUT"); - Overlap::Disjoint - } else { - debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); - Overlap::EqualOrDisjoint - } - } + if s1.def_id != s2.def_id { + debug!("place_element_conflict: DISJOINT-STATIC"); + Overlap::Disjoint + } else if tcx.is_mutable_static(s1.def_id) { + // We ignore mutable statics - they can only be unsafe code. + debug!("place_element_conflict: IGNORE-STATIC-MUT"); + Overlap::Disjoint + } else { + debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); + Overlap::EqualOrDisjoint } } (PlaceBase::Local(_), PlaceBase::Static(_)) diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index f66af1f04a360..f771330e2d711 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -467,7 +467,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let mut place_ty = match &place.base { PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), - PlaceBase::Static(box Static { kind, ty, def_id }) => { + PlaceBase::Static(box Static { ty, def_id }) => { let san_ty = self.sanitize_type(place, ty); let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, place: &Place<'tcx>, ty, san_ty| { @@ -487,14 +487,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { ); }; }; - match kind { - StaticKind::Static => { - let ty = self.tcx().type_of(*def_id); - let ty = self.cx.normalize(ty, location); + let ty = self.tcx().type_of(*def_id); + let ty = self.cx.normalize(ty, location); - check_err(self, place, ty, san_ty); - } - } + check_err(self, place, ty, san_ty); PlaceTy::from_ty(san_ty) } }; diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 6d15827536c55..3309e9b9b622a 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -212,7 +212,7 @@ pub trait Machine<'mir, 'tcx>: Sized { frame.locals[local].access() } - /// Called before a `StaticKind::Static` value is accessed. + /// Called before a `Static` value is accessed. fn before_access_static( _memory_extra: &Self::MemoryExtra, _allocation: &Allocation, diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 79411d872a959..aa15f3d1f173e 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -625,33 +625,27 @@ where &self, place_static: &mir::Static<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { - use rustc::mir::StaticKind; - - Ok(match place_static.kind { - StaticKind::Static => { - let ty = place_static.ty; - assert!(!ty.needs_subst()); - let layout = self.layout_of(ty)?; - // Just create a lazy reference, so we can support recursive statics. - // tcx takes care of assigning every static one and only one unique AllocId. - // When the data here is ever actually used, memory will notice, - // and it knows how to deal with alloc_id that are present in the - // global table but not in its local memory: It calls back into tcx through - // a query, triggering the CTFE machinery to actually turn this lazy reference - // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this InterpCx uses another Machine (e.g., in miri). This is what we - // want! This way, computing statics works consistently between codegen - // and miri: They use the same query to eventually obtain a `ty::Const` - // and use that for further computation. - // - // Notice that statics have *two* AllocIds: the lazy one, and the resolved - // one. Here we make sure that the interpreted program never sees the - // resolved ID. Also see the doc comment of `Memory::get_static_alloc`. - let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(place_static.def_id); - let ptr = self.tag_static_base_pointer(Pointer::from(alloc_id)); - MPlaceTy::from_aligned_ptr(ptr, layout) - } - }) + let ty = place_static.ty; + assert!(!ty.needs_subst()); + let layout = self.layout_of(ty)?; + // Just create a lazy reference, so we can support recursive statics. + // tcx takes care of assigning every static one and only one unique AllocId. + // When the data here is ever actually used, memory will notice, + // and it knows how to deal with alloc_id that are present in the + // global table but not in its local memory: It calls back into tcx through + // a query, triggering the CTFE machinery to actually turn this lazy reference + // into a bunch of bytes. IOW, statics are evaluated with CTFE even when + // this InterpCx uses another Machine (e.g., in miri). This is what we + // want! This way, computing statics works consistently between codegen + // and miri: They use the same query to eventually obtain a `ty::Const` + // and use that for further computation. + // + // Notice that statics have *two* AllocIds: the lazy one, and the resolved + // one. Here we make sure that the interpreted program never sees the + // resolved ID. Also see the doc comment of `Memory::get_static_alloc`. + let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(place_static.def_id); + let ptr = self.tag_static_base_pointer(Pointer::from(alloc_id)); + Ok(MPlaceTy::from_aligned_ptr(ptr, layout)) } /// Computes a place. You should only use this if you intend to write into this diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 84b641a763a02..2ecae7c6b0cd8 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,7 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::{self, Location, PlaceBase, Static, StaticKind}; +use rustc::mir::{self, Location, PlaceBase, Static}; use rustc::session::config::EntryFnType; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::print::obsolete::DefPathBasedNames; @@ -647,7 +647,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { location: Location, ) { match place_base { - PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => { + PlaceBase::Static(box Static { def_id, .. }) => { debug!("visiting static {:?} @ {:?}", def_id, location); let tcx = self.tcx; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 88fce075d7c02..be9c2b741a269 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -194,8 +194,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { PlaceBase::Local(..) => { // Locals are safe. } - PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => { - bug!("StaticKind::Static should not exist"); + PlaceBase::Static(box Static { .. }) => { + bug!("Static should not exist"); } } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 1052d037326b4..76f1e2d186e61 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -39,7 +39,7 @@ use crate::transform::{MirPass, MirSource}; /// errors when promotion of `#[rustc_args_required_const]` arguments fails. /// /// After this pass is run, `promoted_fragments` will hold the MIR body corresponding to each -/// newly created `StaticKind::Promoted`. +/// newly created `Constant`. #[derive(Default)] pub struct PromoteTemps<'tcx> { pub promoted_fragments: Cell>>, From fb2f0ec416167d9d7a454c6eff6601fb7a009e9e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 01:57:01 -0300 Subject: [PATCH 0151/1253] Use if let instead of match with one meaningful arm --- src/librustc_codegen_ssa/mir/block.rs | 28 +++++++++------------------ 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index ecb3eb05f1163..a1ff62fde0af0 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -609,25 +609,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked by const-qualification, which also // promotes any complex rvalues to constants. if i == 2 && intrinsic.unwrap().starts_with("simd_shuffle") { - match arg { - // The shuffle array argument is usually not an explicit constant, - // but specified directly in the code. This means it gets promoted - // and we can then extract the value by evaluating the promoted. - mir::Operand::Copy(_place) | mir::Operand::Move(_place) => {} - - mir::Operand::Constant(constant) => { - let c = self.eval_mir_constant(constant); - let (llval, ty) = self.simd_shuffle_indices( - &bx, - constant.span, - constant.literal.ty, - c, - ); - return OperandRef { - val: Immediate(llval), - layout: bx.layout_of(ty), - }; - } + if let mir::Operand::Constant(constant) = arg { + let c = self.eval_mir_constant(constant); + let (llval, ty) = self.simd_shuffle_indices( + &bx, + constant.span, + constant.literal.ty, + c, + ); + return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) }; } } From 9e70c4778371130ecc9ac5f1aff24000411eabd8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 02:07:04 -0300 Subject: [PATCH 0152/1253] Remove unused param_env parameter --- .../borrow_check/constraint_generation.rs | 4 ---- src/librustc_mir/borrow_check/invalidation.rs | 7 +------ src/librustc_mir/borrow_check/mod.rs | 7 +------ src/librustc_mir/borrow_check/nll.rs | 10 +--------- src/librustc_mir/borrow_check/path_utils.rs | 4 +--- .../borrow_check/places_conflict.rs | 18 ++---------------- src/librustc_mir/dataflow/impls/borrows.rs | 6 +----- 7 files changed, 7 insertions(+), 49 deletions(-) diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index 97de201faba01..67cd9c40db655 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -16,7 +16,6 @@ use crate::borrow_check::{ pub(super) fn generate_constraints<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, liveness_constraints: &mut LivenessValues, all_facts: &mut Option, location_table: &LocationTable, @@ -30,7 +29,6 @@ pub(super) fn generate_constraints<'cx, 'tcx>( location_table, all_facts, body, - param_env, }; for (bb, data) in body.basic_blocks().iter_enumerated() { @@ -41,7 +39,6 @@ pub(super) fn generate_constraints<'cx, 'tcx>( /// 'cg = the duration of the constraint generation process itself. struct ConstraintGeneration<'cg, 'cx, 'tcx> { infcx: &'cg InferCtxt<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, all_facts: &'cg mut Option, location_table: &'cg LocationTable, liveness_constraints: &'cg mut LivenessValues, @@ -226,7 +223,6 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { for &borrow_index in borrow_indices { let places_conflict = places_conflict::places_conflict( self.infcx.tcx, - self.param_env, self.body, &self.borrow_set.borrows[borrow_index].borrowed_place, place, diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index f9ffa2138ba40..bb56c11872a29 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -3,7 +3,7 @@ use rustc::mir::TerminatorKind; use rustc::mir::{BasicBlock, Body, Location, Place, ReadOnlyBodyAndCache, Rvalue}; use rustc::mir::{BorrowKind, Mutability, Operand}; use rustc::mir::{Statement, StatementKind}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::TyCtxt; use rustc_data_structures::graph::dominators::Dominators; use crate::dataflow::indexes::BorrowIndex; @@ -16,7 +16,6 @@ use crate::borrow_check::{ pub(super) fn generate_invalidates<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, all_facts: &mut Option, location_table: &LocationTable, body: ReadOnlyBodyAndCache<'_, 'tcx>, @@ -33,7 +32,6 @@ pub(super) fn generate_invalidates<'tcx>( let mut ig = InvalidationGenerator { all_facts, borrow_set, - param_env, tcx, location_table, body: &body, @@ -45,7 +43,6 @@ pub(super) fn generate_invalidates<'tcx>( struct InvalidationGenerator<'cx, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, all_facts: &'cx mut AllFacts, location_table: &'cx LocationTable, body: &'cx Body<'tcx>, @@ -337,13 +334,11 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { ); let tcx = self.tcx; let body = self.body; - let param_env = self.param_env; let borrow_set = self.borrow_set.clone(); let indices = self.borrow_set.borrows.indices(); each_borrow_involving_path( self, tcx, - param_env, body, location, (sd, place), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 6c9b811ebd0a8..5174f17ab8839 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -239,7 +239,7 @@ fn do_mir_borrowck<'a, 'tcx>( def_id, &attributes, &dead_unwinds, - Borrows::new(tcx, &body, param_env, regioncx.clone(), &borrow_set), + Borrows::new(tcx, &body, regioncx.clone(), &borrow_set), |rs, i| DebugFormatted::new(&rs.location(i)), )); let flow_uninits = FlowAtLocation::new(do_dataflow( @@ -275,7 +275,6 @@ fn do_mir_borrowck<'a, 'tcx>( infcx, body, mir_def_id: def_id, - param_env, move_data: &mdpe.move_data, location_table, movable_generator, @@ -418,7 +417,6 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { crate infcx: &'cx InferCtxt<'cx, 'tcx>, body: ReadOnlyBodyAndCache<'cx, 'tcx>, mir_def_id: DefId, - param_env: ty::ParamEnv<'tcx>, move_data: &'cx MoveData<'tcx>, /// Map from MIR `Location` to `LocationIndex`; created @@ -926,13 +924,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let body = self.body; let body: &Body<'_> = &body; - let param_env = self.param_env; let location_table = self.location_table.start_index(location); let borrow_set = self.borrow_set.clone(); each_borrow_involving_path( self, tcx, - param_env, body, location, (sd, place_span.0), @@ -1412,7 +1408,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if places_conflict::borrow_conflicts_with_place( self.infcx.tcx, - self.param_env, &self.body, place, borrow.kind, diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index a4c2299b3eaac..151a2c4c19a7d 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -231,7 +231,6 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( constraint_generation::generate_constraints( infcx, - param_env, &mut liveness_constraints, &mut all_facts, location_table, @@ -253,14 +252,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( ); // Generate various additional constraints. - invalidation::generate_invalidates( - infcx.tcx, - param_env, - &mut all_facts, - location_table, - body, - borrow_set, - ); + invalidation::generate_invalidates(infcx.tcx, &mut all_facts, location_table, body, borrow_set); // Dump facts if requested. let polonius_output = all_facts.and_then(|all_facts| { diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 23b4799643a6c..6fb0bbceb1b51 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -4,7 +4,7 @@ use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; use rustc::mir::BorrowKind; use rustc::mir::{BasicBlock, Body, Location, Place, PlaceBase}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::TyCtxt; use rustc_data_structures::graph::dominators::Dominators; /// Returns `true` if the borrow represented by `kind` is @@ -25,7 +25,6 @@ pub(super) enum Control { pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( s: &mut S, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, _location: Location, access_place: (AccessDepth, &Place<'tcx>), @@ -48,7 +47,6 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( if places_conflict::borrow_conflicts_with_place( tcx, - param_env, body, &borrowed.borrowed_place, borrowed.kind, diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 815ace55a3721..3988221e06383 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -23,7 +23,6 @@ crate enum PlaceConflictBias { /// dataflow). crate fn places_conflict<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_place: &Place<'tcx>, access_place: &Place<'tcx>, @@ -31,7 +30,6 @@ crate fn places_conflict<'tcx>( ) -> bool { borrow_conflicts_with_place( tcx, - param_env, body, borrow_place, BorrowKind::Mut { allow_two_phase_borrow: true }, @@ -47,7 +45,6 @@ crate fn places_conflict<'tcx>( /// order to make the conservative choice and preserve soundness. pub(super) fn borrow_conflicts_with_place<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, @@ -68,21 +65,11 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( } } - place_components_conflict( - tcx, - param_env, - body, - borrow_place, - borrow_kind, - access_place, - access, - bias, - ) + place_components_conflict(tcx, body, borrow_place, borrow_kind, access_place, access, bias) } fn place_components_conflict<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, @@ -135,7 +122,7 @@ fn place_components_conflict<'tcx>( let borrow_base = &borrow_place.base; let access_base = access_place.base; - match place_base_conflict(tcx, param_env, borrow_base, access_base) { + match place_base_conflict(tcx, borrow_base, access_base) { Overlap::Arbitrary => { bug!("Two base can't return Arbitrary"); } @@ -308,7 +295,6 @@ fn place_components_conflict<'tcx>( // between `elem1` and `elem2`. fn place_base_conflict<'tcx>( tcx: TyCtxt<'tcx>, - _param_env: ty::ParamEnv<'tcx>, elem1: &PlaceBase<'tcx>, elem2: &PlaceBase<'tcx>, ) -> Overlap { diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 8d51cb2391234..583075980ec97 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -1,6 +1,6 @@ use rustc::mir::{self, Body, Location, Place, PlaceBase}; use rustc::ty::RegionVid; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; @@ -30,7 +30,6 @@ rustc_index::newtype_index! { pub struct Borrows<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, - param_env: ty::ParamEnv<'tcx>, borrow_set: Rc>, borrows_out_of_scope_at_location: FxHashMap>, @@ -134,7 +133,6 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { crate fn new( tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, - param_env: ty::ParamEnv<'tcx>, nonlexical_regioncx: Rc>, borrow_set: &Rc>, ) -> Self { @@ -156,7 +154,6 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { Borrows { tcx, body, - param_env, borrow_set: borrow_set.clone(), borrows_out_of_scope_at_location, _nonlexical_regioncx: nonlexical_regioncx, @@ -219,7 +216,6 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { places_conflict( self.tcx, - self.param_env, self.body, &self.borrow_set.borrows[i].borrowed_place, place, From fd5aa32c352d9aa7e652a64320f89b7f3859858b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 10:39:24 -0300 Subject: [PATCH 0153/1253] Remove Static from PlaceBase --- src/librustc/mir/mod.rs | 54 ++---------- src/librustc/mir/tcx.rs | 5 +- src/librustc/mir/visit.rs | 15 ++-- src/librustc/ty/codec.rs | 2 +- src/librustc_codegen_ssa/mir/analyze.rs | 13 ++- src/librustc_codegen_ssa/mir/debuginfo.rs | 4 +- src/librustc_codegen_ssa/mir/operand.rs | 64 +++++++------- src/librustc_codegen_ssa/mir/place.rs | 19 ---- src/librustc_mir/borrow_check/borrow_set.rs | 6 +- .../borrow_check/constraint_generation.rs | 4 - .../diagnostics/conflict_errors.rs | 17 ++-- .../borrow_check/diagnostics/mod.rs | 8 +- .../borrow_check/diagnostics/move_errors.rs | 3 - .../diagnostics/mutability_errors.rs | 3 +- src/librustc_mir/borrow_check/mod.rs | 86 +++++++------------ src/librustc_mir/borrow_check/path_utils.rs | 2 - src/librustc_mir/borrow_check/place_ext.rs | 1 - .../borrow_check/places_conflict.rs | 28 +----- src/librustc_mir/borrow_check/prefixes.rs | 61 +++---------- .../borrow_check/type_check/mod.rs | 26 ------ src/librustc_mir/borrow_check/used_muts.rs | 14 +-- src/librustc_mir/build/expr/as_place.rs | 6 +- src/librustc_mir/dataflow/impls/borrows.rs | 56 ++++++------ .../dataflow/impls/storage_liveness.rs | 18 ++-- .../dataflow/move_paths/builder.rs | 3 - src/librustc_mir/dataflow/move_paths/mod.rs | 4 - src/librustc_mir/interpret/operand.rs | 1 - src/librustc_mir/interpret/place.rs | 31 ------- src/librustc_mir/monomorphize/collector.rs | 15 +--- .../transform/check_consts/qualifs.rs | 3 - .../transform/check_consts/validation.rs | 24 ++---- src/librustc_mir/transform/check_unsafety.rs | 3 - src/librustc_mir/transform/const_prop.rs | 4 +- src/librustc_mir/transform/generator.rs | 22 ++--- src/librustc_mir/transform/inline.rs | 5 -- src/librustc_mir/transform/promote_consts.rs | 5 -- src/librustc_mir/transform/simplify.rs | 10 +-- 37 files changed, 193 insertions(+), 452 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 42d24d9f332b4..05bb1d9698016 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1655,7 +1655,7 @@ impl Debug for Statement<'_> { /// changing or disturbing program state. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] pub struct Place<'tcx> { - pub base: PlaceBase<'tcx>, + pub base: PlaceBase, /// projection out of a place (access a field, deref a pointer, etc) pub projection: &'tcx List>, @@ -1664,34 +1664,9 @@ pub struct Place<'tcx> { impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] -pub enum PlaceBase<'tcx> { +pub enum PlaceBase { /// local variable Local(Local), - - /// static or static mut variable - Static(Box>), -} - -/// We store the normalized type to avoid requiring normalization when reading MIR -#[derive( - Clone, - Debug, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - RustcEncodable, - RustcDecodable, - HashStable -)] -pub struct Static<'tcx> { - pub ty: Ty<'tcx>, - /// The `DefId` of the item this static was declared in. For promoted values, usually, this is - /// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in. - /// However, after inlining, that might no longer be the case as inlined `Place`s are copied - /// into the calling frame. - pub def_id: DefId, } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -1781,7 +1756,7 @@ rustc_index::newtype_index! { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct PlaceRef<'a, 'tcx> { - pub base: &'a PlaceBase<'tcx>, + pub base: &'a PlaceBase, pub projection: &'a [PlaceElem<'tcx>], } @@ -1830,7 +1805,7 @@ impl From for Place<'_> { } } -impl From for PlaceBase<'_> { +impl From for PlaceBase { fn from(local: Local) -> Self { PlaceBase::Local(local) } @@ -1921,13 +1896,10 @@ impl Debug for Place<'_> { } } -impl Debug for PlaceBase<'_> { +impl Debug for PlaceBase { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { match *self { PlaceBase::Local(id) => write!(fmt, "{:?}", id), - PlaceBase::Static(box self::Static { ty, def_id }) => { - write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) - } } } } @@ -3000,18 +2972,16 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> { +impl<'tcx> TypeFoldable<'tcx> for PlaceBase { fn super_fold_with>(&self, folder: &mut F) -> Self { match self { PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)), - PlaceBase::Static(static_) => PlaceBase::Static(static_.fold_with(folder)), } } fn super_visit_with>(&self, visitor: &mut V) -> bool { match self { PlaceBase::Local(local) => local.visit_with(visitor), - PlaceBase::Static(static_) => (**static_).visit_with(visitor), } } } @@ -3027,18 +2997,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> { - fn super_fold_with>(&self, folder: &mut F) -> Self { - Static { ty: self.ty.fold_with(folder), def_id: self.def_id } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - let Static { ty, def_id: _ } = self; - - ty.visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { use crate::mir::Rvalue::*; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 77f3ff47ff247..5adf6447d3981 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -114,7 +114,7 @@ impl<'tcx> PlaceTy<'tcx> { impl<'tcx> Place<'tcx> { pub fn ty_from( - base: &PlaceBase<'tcx>, + base: &PlaceBase, projection: &[PlaceElem<'tcx>], local_decls: &D, tcx: TyCtxt<'tcx>, @@ -135,14 +135,13 @@ impl<'tcx> Place<'tcx> { } } -impl<'tcx> PlaceBase<'tcx> { +impl<'tcx> PlaceBase { pub fn ty(&self, local_decls: &D) -> PlaceTy<'tcx> where D: HasLocalDecls<'tcx>, { match self { PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty), - PlaceBase::Static(data) => PlaceTy::from_ty(data.ty), } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 3924a1aa47eda..a31931c8a99bc 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -164,7 +164,7 @@ macro_rules! make_mir_visitor { } fn visit_place_base(&mut self, - base: & $($mutability)? PlaceBase<'tcx>, + base: & $($mutability)? PlaceBase, context: PlaceContext, location: Location) { self.super_place_base(base, context, location); @@ -705,16 +705,13 @@ macro_rules! make_mir_visitor { } fn super_place_base(&mut self, - place_base: & $($mutability)? PlaceBase<'tcx>, + place_base: & $($mutability)? PlaceBase, context: PlaceContext, location: Location) { match place_base { PlaceBase::Local(local) => { self.visit_local(local, context, location); } - PlaceBase::Static(box Static { ty, def_id: _ }) => { - self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); - } } } @@ -889,7 +886,7 @@ macro_rules! visit_place_fns { () => ( fn visit_projection( &mut self, - base: &PlaceBase<'tcx>, + base: &PlaceBase, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, @@ -899,7 +896,7 @@ macro_rules! visit_place_fns { fn visit_projection_elem( &mut self, - base: &PlaceBase<'tcx>, + base: &PlaceBase, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, @@ -934,7 +931,7 @@ macro_rules! visit_place_fns { fn super_projection( &mut self, - base: &PlaceBase<'tcx>, + base: &PlaceBase, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, @@ -948,7 +945,7 @@ macro_rules! visit_place_fns { fn super_projection_elem( &mut self, - _base: &PlaceBase<'tcx>, + _base: &PlaceBase, _proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, _context: PlaceContext, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 9b2714082f1e1..c691cb44f0118 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -226,7 +226,7 @@ pub fn decode_place(decoder: &mut D) -> Result, D::Error> where D: TyDecoder<'tcx>, { - let base: mir::PlaceBase<'tcx> = Decodable::decode(decoder)?; + let base: mir::PlaceBase = Decodable::decode(decoder)?; let len = decoder.read_usize()?; let projection: &'tcx List> = decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 0ceb44d019b64..7b9bc923cd6fd 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -14,7 +14,6 @@ use rustc::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; -use rustc_span::DUMMY_SP; pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, @@ -135,10 +134,10 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { // ZSTs don't require any actual memory access. let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty; let elem_ty = self.fx.monomorphize(&elem_ty); - let span = if let mir::PlaceBase::Local(index) = place_ref.base { - self.fx.mir.local_decls[*index].source_info.span - } else { - DUMMY_SP + let span = match place_ref.base { + mir::PlaceBase::Local(index) => { + self.fx.mir.local_decls[*index].source_info.span + } }; if cx.spanned_layout_of(elem_ty, span).is_zst() { return; @@ -179,8 +178,8 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { // We use `NonUseContext::VarDebugInfo` for the base, // which might not force the base local to memory, // so we have to do it manually. - if let mir::PlaceBase::Local(local) = place_ref.base { - self.visit_local(&local, context, location); + match place_ref.base { + mir::PlaceBase::Local(local) => self.visit_local(&local, context, location), } } } diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index 6c17a01eb9133..88e43c7f53528 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -258,8 +258,8 @@ pub fn per_local_var_debug_info( if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() { let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); for var in &body.var_debug_info { - if let mir::PlaceBase::Local(local) = var.place.base { - per_local[local].push(var); + match var.place.base { + mir::PlaceBase::Local(local) => per_local[local].push(var), } } Some(per_local) diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index d530696543720..be6e05b948c7c 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -373,44 +373,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); - if let mir::PlaceBase::Local(index) = place_ref.base { - match self.locals[*index] { - LocalRef::Operand(Some(mut o)) => { - // Moves out of scalar and scalar pair fields are trivial. - for elem in place_ref.projection.iter() { - match elem { - mir::ProjectionElem::Field(ref f, _) => { - o = o.extract_field(bx, f.index()); - } - mir::ProjectionElem::Index(_) - | mir::ProjectionElem::ConstantIndex { .. } => { - // ZSTs don't require any actual memory access. - // FIXME(eddyb) deduplicate this with the identical - // checks in `codegen_consume` and `extract_field`. - let elem = o.layout.field(bx.cx(), 0); - if elem.is_zst() { - o = OperandRef::new_zst(bx, elem); - } else { - return None; + match place_ref.base { + mir::PlaceBase::Local(index) => { + match self.locals[*index] { + LocalRef::Operand(Some(mut o)) => { + // Moves out of scalar and scalar pair fields are trivial. + for elem in place_ref.projection.iter() { + match elem { + mir::ProjectionElem::Field(ref f, _) => { + o = o.extract_field(bx, f.index()); + } + mir::ProjectionElem::Index(_) + | mir::ProjectionElem::ConstantIndex { .. } => { + // ZSTs don't require any actual memory access. + // FIXME(eddyb) deduplicate this with the identical + // checks in `codegen_consume` and `extract_field`. + let elem = o.layout.field(bx.cx(), 0); + if elem.is_zst() { + o = OperandRef::new_zst(bx, elem); + } else { + return None; + } } + _ => return None, } - _ => return None, } - } - Some(o) - } - LocalRef::Operand(None) => { - bug!("use of {:?} before def", place_ref); - } - LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { - // watch out for locals that do not have an - // alloca; they are handled somewhat differently - None + Some(o) + } + LocalRef::Operand(None) => { + bug!("use of {:?} before def", place_ref); + } + LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { + // watch out for locals that do not have an + // alloca; they are handled somewhat differently + None + } } } - } else { - None } } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 49c3edbb2b3df..3d94cf9aa2c46 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -37,15 +37,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { PlaceRef { llval, llextra: None, layout, align } } - fn new_thin_place>( - bx: &mut Bx, - llval: V, - layout: TyLayout<'tcx>, - ) -> PlaceRef<'tcx, V> { - assert!(!bx.cx().type_has_metadata(layout.ty)); - PlaceRef { llval, llextra: None, layout, align: layout.align.abi } - } - // FIXME(eddyb) pass something else for the name so no work is done // unless LLVM IR names are turned on (e.g. for `--emit=llvm-ir`). pub fn alloca>( @@ -437,16 +428,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - mir::PlaceRef { - base: mir::PlaceBase::Static(box mir::Static { ty, def_id }), - projection: [], - } => { - // NB: The layout of a static may be unsized as is the case when working - // with a static that is an extern_type. - let layout = cx.layout_of(self.monomorphize(&ty)); - let static_ = bx.get_static(*def_id); - PlaceRef::new_thin_place(bx, static_, layout) - } mir::PlaceRef { base, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => { // Load the pointer from its location. self.codegen_consume(bx, &mir::PlaceRef { base, projection: proj_base }) diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index b66b2e4b1f7f5..4c6b9bc02a4ba 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -208,8 +208,10 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - if let mir::PlaceBase::Local(local) = borrowed_place.base { - self.local_map.entry(local).or_default().insert(idx); + match borrowed_place.base { + mir::PlaceBase::Local(local) => { + self.local_map.entry(local).or_default().insert(idx); + } } } diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index 67cd9c40db655..2a9ad6a1505da 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -207,10 +207,6 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { ); } - PlaceRef { base: &PlaceBase::Static(_), .. } => { - // Ignore kills of static or static mut variables. - } - PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => { // Kill conflicting borrows of the innermost local. debug!( diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 7e251560a6c51..dc3157f6b4d9c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -688,7 +688,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { assert!(root_place.projection.is_empty()); let proper_span = match root_place.base { PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span, - _ => drop_span, }; let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); @@ -709,12 +708,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, )); - if let PlaceBase::Local(local) = borrow.borrowed_place.base { - if self.body.local_decls[local].is_ref_to_thread_local() { - let err = self - .report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span); - err.buffer(&mut self.errors_buffer); - return; + match borrow.borrowed_place.base { + PlaceBase::Local(local) => { + if self.body.local_decls[local].is_ref_to_thread_local() { + let err = self.report_thread_local_value_does_not_live_long_enough( + drop_span, + borrow_span, + ); + err.buffer(&mut self.errors_buffer); + return; + } } }; diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 8ef4273a2f6a5..38c479c72c1e7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -2,7 +2,7 @@ use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Static, Terminator, + PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc::ty::layout::VariantIdx; @@ -172,9 +172,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { PlaceRef { base: PlaceBase::Local(local), projection: [] } => { self.append_local_to_string(*local, buf)?; } - PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => { - buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string()); - } PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } if self.body.local_decls[local].is_ref_for_guard() => { @@ -318,9 +315,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let local = &self.body.local_decls[*local]; self.describe_field_from_ty(&local.ty, field, None) } - PlaceRef { base: PlaceBase::Static(static_), projection: [] } => { - self.describe_field_from_ty(&static_.ty, field, None) - } PlaceRef { base, projection: [proj_base @ .., elem] } => match elem { ProjectionElem::Deref => { self.describe_field(PlaceRef { base, projection: proj_base }, field) diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index 3f4204bc12f6a..ceb97a98f1f7e 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -243,9 +243,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); ( match kind { - IllegalMoveOriginKind::Static => { - unreachable!(); - } IllegalMoveOriginKind::BorrowedContent { target_place } => self .report_cannot_move_from_borrowed_content( original_path, diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 595acec2f74d7..e81a012cef59a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -136,8 +136,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - PlaceRef { base: PlaceBase::Static(_), .. } - | PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] } + PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] } | PlaceRef { base: _, projection: [.., ProjectionElem::ConstantIndex { .. }] } | PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] } | PlaceRef { base: _, projection: [.., ProjectionElem::Downcast(..)] } => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 5174f17ab8839..d0b0a159e8664 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -5,7 +5,7 @@ use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, - PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static, + PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, }; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -815,7 +815,7 @@ enum InitializationRequiringAction { } struct RootPlace<'d, 'tcx> { - place_base: &'d PlaceBase<'tcx>, + place_base: &'d PlaceBase, place_projection: &'d [PlaceElem<'tcx>], is_local_mutation_allowed: LocalMutationIsAllowed, } @@ -1251,8 +1251,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(field) = this.is_upvar_field_projection(place.as_ref()) { this.used_mut_upvars.push(field); } - } else if let PlaceBase::Local(local) = place.base { - this.used_mut.insert(local); + } else { + match place.base { + PlaceBase::Local(local) => { + this.used_mut.insert(local); + } + } } }; @@ -1385,7 +1389,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // FIXME: allow thread-locals to borrow other thread locals? let (might_be_alive, will_be_dropped) = match root_place.base { - PlaceBase::Static(_) => (true, false), PlaceBase::Local(local) => { if self.body.local_decls[*local].is_ref_to_thread_local() { // Thread-locals might be dropped after the function exits @@ -1649,26 +1652,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // This code covers scenarios 1, 2, and 3. debug!("check_if_full_path_is_moved place: {:?}", place_span.0); - match self.move_path_closest_to(place_span.0) { - Ok((prefix, mpi)) => { - if maybe_uninits.contains(mpi) { - self.report_use_of_moved_or_uninitialized( - location, - desired_action, - (prefix, place_span.0, place_span.1), - mpi, - ); - } - } - Err(NoMovePathFound::ReachedStatic) => { - // Okay: we do not build MoveData for static variables - } // Only query longest prefix with a MovePath, not further - // ancestors; dataflow recurs on children when parents - // move (to support partial (re)inits). - // - // (I.e., querying parents breaks scenario 7; but may want - // to do such a query based on partial-init feature-gate.) - } + let (prefix, mpi) = self.move_path_closest_to(place_span.0); + if maybe_uninits.contains(mpi) { + self.report_use_of_moved_or_uninitialized( + location, + desired_action, + (prefix, place_span.0, place_span.1), + mpi, + ); + } // Only query longest prefix with a MovePath, not further + // ancestors; dataflow recurs on children when parents + // move (to support partial (re)inits). + // + // (I.e., querying parents breaks scenario 7; but may want + // to do such a query based on partial-init feature-gate.) } /// Subslices correspond to multiple move paths, so we iterate through the @@ -1792,12 +1789,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn move_path_closest_to( &mut self, place: PlaceRef<'_, 'tcx>, - ) -> Result<(PlaceRef<'cx, 'tcx>, MovePathIndex), NoMovePathFound> { + ) -> (PlaceRef<'cx, 'tcx>, MovePathIndex) { match self.move_data.rev_lookup.find(place) { LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { - Ok((self.move_data.move_paths[mpi].place.as_ref(), mpi)) + (self.move_data.move_paths[mpi].place.as_ref(), mpi) } - LookupResult::Parent(None) => Err(NoMovePathFound::ReachedStatic), + LookupResult::Parent(None) => panic!("should have move path for every Local"), } } @@ -1881,7 +1878,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { projection: proj_base, }, span, flow_state); - if let PlaceBase::Local(local) = place.base { + match place.base { // rust-lang/rust#21232, // #54499, #54986: during // period where we reject @@ -1890,7 +1887,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // unnecessary `mut` on an // attempt to do a partial // initialization. - self.used_mut.insert(local); + PlaceBase::Local(local) => { + self.used_mut.insert(local); + } } } @@ -2088,10 +2087,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = if let PlaceBase::Local(local) = place.base { - self.is_local_ever_initialized(local, flow_state).is_some() - } else { - true + let previously_initialized = match place.base { + PlaceBase::Local(local) => self.is_local_ever_initialized(local, flow_state).is_some(), }; // at this point, we have set up the error reporting state. @@ -2152,11 +2149,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.used_mut_upvars.push(field); } } - RootPlace { - place_base: PlaceBase::Static(..), - place_projection: [], - is_local_mutation_allowed: _, - } => {} } } @@ -2191,17 +2183,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }), } } - PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => { - if !self.infcx.tcx.is_mutable_static(*def_id) { - Err(place) - } else { - Ok(RootPlace { - place_base: place.base, - place_projection: place.projection, - is_local_mutation_allowed, - }) - } - } PlaceRef { base: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { @@ -2356,11 +2337,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum NoMovePathFound { - ReachedStatic, -} - /// The degree of overlap between 2 places for borrow-checking. enum Overlap { /// The places might partially overlap - in this case, we give diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 6fb0bbceb1b51..41bf1aa47d415 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -132,8 +132,6 @@ pub(super) fn is_active<'tcx>( /// This is called for all Yield expressions on movable generators pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { match place.base { - PlaceBase::Static(_) => false, - // Reborrow of already borrowed data is ignored // Any errors will be caught on the initial borrow PlaceBase::Local(_) => !place.is_indirect(), diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 91ab314e2b910..445ba057c1b51 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -47,7 +47,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { } } }, - PlaceBase::Static(_) => return true, }; for (i, elem) in self.projection.iter().enumerate() { diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 3988221e06383..a09779a766ffb 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -122,7 +122,7 @@ fn place_components_conflict<'tcx>( let borrow_base = &borrow_place.base; let access_base = access_place.base; - match place_base_conflict(tcx, borrow_base, access_base) { + match place_base_conflict(borrow_base, access_base) { Overlap::Arbitrary => { bug!("Two base can't return Arbitrary"); } @@ -293,11 +293,7 @@ fn place_components_conflict<'tcx>( // Given that the bases of `elem1` and `elem2` are always either equal // or disjoint (and have the same type!), return the overlap situation // between `elem1` and `elem2`. -fn place_base_conflict<'tcx>( - tcx: TyCtxt<'tcx>, - elem1: &PlaceBase<'tcx>, - elem2: &PlaceBase<'tcx>, -) -> Overlap { +fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap { match (elem1, elem2) { (PlaceBase::Local(l1), PlaceBase::Local(l2)) => { if l1 == l2 { @@ -310,24 +306,6 @@ fn place_base_conflict<'tcx>( Overlap::Disjoint } } - (PlaceBase::Static(s1), PlaceBase::Static(s2)) => { - if s1.def_id != s2.def_id { - debug!("place_element_conflict: DISJOINT-STATIC"); - Overlap::Disjoint - } else if tcx.is_mutable_static(s1.def_id) { - // We ignore mutable statics - they can only be unsafe code. - debug!("place_element_conflict: IGNORE-STATIC-MUT"); - Overlap::Disjoint - } else { - debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); - Overlap::EqualOrDisjoint - } - } - (PlaceBase::Local(_), PlaceBase::Static(_)) - | (PlaceBase::Static(_), PlaceBase::Local(_)) => { - debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); - Overlap::Disjoint - } } } @@ -337,7 +315,7 @@ fn place_base_conflict<'tcx>( fn place_projection_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - pi1_base: &PlaceBase<'tcx>, + pi1_base: &PlaceBase, pi1_proj_base: &[PlaceElem<'tcx>], pi1_elem: &PlaceElem<'tcx>, pi2_elem: &PlaceElem<'tcx>, diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 1e88f696f2315..c41f2f45012e2 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -69,39 +69,22 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { 'cursor: loop { match &cursor { - PlaceRef { - base: PlaceBase::Local(_), - projection: [], - } - | // search yielded this leaf - PlaceRef { - base: PlaceBase::Static(_), - projection: [], - } => { + PlaceRef { base: PlaceBase::Local(_), projection: [] } => { self.next = None; return Some(cursor); } - PlaceRef { - base: _, - projection: [proj_base @ .., elem], - } => { + PlaceRef { base: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Field(_ /*field*/, _ /*ty*/) => { // FIXME: add union handling - self.next = Some(PlaceRef { - base: cursor.base, - projection: proj_base, - }); + self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); return Some(cursor); } - ProjectionElem::Downcast(..) | - ProjectionElem::Subslice { .. } | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Index(_) => { - cursor = PlaceRef { - base: cursor.base, - projection: proj_base, - }; + ProjectionElem::Downcast(..) + | ProjectionElem::Subslice { .. } + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Index(_) => { + cursor = PlaceRef { base: cursor.base, projection: proj_base }; continue 'cursor; } ProjectionElem::Deref => { @@ -122,10 +105,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { PrefixSet::All => { // All prefixes: just blindly enqueue the base // of the projection. - self.next = Some(PlaceRef { - base: cursor.base, - projection: proj_base, - }); + self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); return Some(cursor); } PrefixSet::Supporting => { @@ -140,35 +120,20 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { let ty = Place::ty_from(cursor.base, proj_base, *self.body, self.tcx).ty; match ty.kind { - ty::RawPtr(_) | - ty::Ref( - _, /*rgn*/ - _, /*ty*/ - hir::Mutability::Not - ) => { + ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => { // don't continue traversing over derefs of raw pointers or shared // borrows. self.next = None; return Some(cursor); } - ty::Ref( - _, /*rgn*/ - _, /*ty*/ - hir::Mutability::Mut, - ) => { - self.next = Some(PlaceRef { - base: cursor.base, - projection: proj_base, - }); + ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => { + self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); return Some(cursor); } ty::Adt(..) if ty.is_box() => { - self.next = Some(PlaceRef { - base: cursor.base, - projection: proj_base, - }); + self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); return Some(cursor); } diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index f771330e2d711..001f2fc3b2287 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -467,32 +467,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let mut place_ty = match &place.base { PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), - PlaceBase::Static(box Static { ty, def_id }) => { - let san_ty = self.sanitize_type(place, ty); - let check_err = - |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, place: &Place<'tcx>, ty, san_ty| { - if let Err(terr) = verifier.cx.eq_types( - san_ty, - ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!( - verifier, - place, - "bad promoted type ({:?}: {:?}): {:?}", - ty, - san_ty, - terr - ); - }; - }; - let ty = self.tcx().type_of(*def_id); - let ty = self.cx.normalize(ty, location); - - check_err(self, place, ty, san_ty); - PlaceTy::from_ty(san_ty) - } }; if place.projection.is_empty() { diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 608a2436bf3d3..ea530042913e8 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -57,8 +57,10 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - if let PlaceBase::Local(local) = into.base { - let _ = self.never_initialized_mut_locals.remove(&local); + match into.base { + PlaceBase::Local(local) => { + self.never_initialized_mut_locals.remove(&local); + } } } } @@ -80,12 +82,12 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) { match &statement.kind { StatementKind::Assign(box (into, _)) => { - if let PlaceBase::Local(local) = into.base { - debug!( + match into.base { + PlaceBase::Local(local) => debug!( "visit_statement: statement={:?} local={:?} \ - never_initialized_mut_locals={:?}", + never_initialized_mut_locals={:?}", statement, local, self.never_initialized_mut_locals - ); + ), } self.remove_never_initialized_mut_locals(into); } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 29eac5e4b3f54..661111ed9484c 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -20,7 +20,7 @@ use rustc_index::vec::Idx; /// and `c` can be progressively pushed onto the place builder that is created when converting `a`. #[derive(Clone)] struct PlaceBuilder<'tcx> { - base: PlaceBase<'tcx>, + base: PlaceBase, projection: Vec>, } @@ -53,8 +53,8 @@ impl From for PlaceBuilder<'tcx> { } } -impl From> for PlaceBuilder<'tcx> { - fn from(base: PlaceBase<'tcx>) -> Self { +impl From for PlaceBuilder<'tcx> { + fn from(base: PlaceBase) -> Self { Self { base, projection: Vec::new() } } } diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 583075980ec97..d6ada9162272d 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -195,35 +195,37 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { fn kill_borrows_on_place(&self, trans: &mut GenKillSet, place: &Place<'tcx>) { debug!("kill_borrows_on_place: place={:?}", place); - if let PlaceBase::Local(local) = place.base { - let other_borrows_of_local = - self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); - - // If the borrowed place is a local with no projections, all other borrows of this - // local must conflict. This is purely an optimization so we don't have to call - // `places_conflict` for every borrow. - if place.projection.is_empty() { - if !self.body.local_decls[local].is_ref_to_static() { - trans.kill_all(other_borrows_of_local); + match place.base { + PlaceBase::Local(local) => { + let other_borrows_of_local = + self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); + + // If the borrowed place is a local with no projections, all other borrows of this + // local must conflict. This is purely an optimization so we don't have to call + // `places_conflict` for every borrow. + if place.projection.is_empty() { + if !self.body.local_decls[local].is_ref_to_static() { + trans.kill_all(other_borrows_of_local); + } + return; } - return; - } - // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given - // pair of array indices are unequal, so that when `places_conflict` returns true, we - // will be assured that two places being compared definitely denotes the same sets of - // locations. - let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { - places_conflict( - self.tcx, - self.body, - &self.borrow_set.borrows[i].borrowed_place, - place, - PlaceConflictBias::NoOverlap, - ) - }); - - trans.kill_all(definitely_conflicting_borrows); + // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given + // pair of array indices are unequal, so that when `places_conflict` returns true, we + // will be assured that two places being compared definitely denotes the same sets of + // locations. + let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { + places_conflict( + self.tcx, + self.body, + &self.borrow_set.borrows[i].borrowed_place, + place, + PlaceConflictBias::NoOverlap, + ) + }); + + trans.kill_all(definitely_conflicting_borrows); + } } } } diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 17f71e83cfd21..e4d5d6adfc17c 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -115,15 +115,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { match stmt.kind { StatementKind::StorageDead(l) => sets.kill(l), StatementKind::Assign(box (ref place, _)) - | StatementKind::SetDiscriminant { box ref place, .. } => { - if let PlaceBase::Local(local) = place.base { - sets.gen(local); - } - } + | StatementKind::SetDiscriminant { box ref place, .. } => match place.base { + PlaceBase::Local(local) => sets.gen(local), + }, StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { for p in &**outputs { - if let PlaceBase::Local(local) = p.base { - sets.gen(local); + match p.base { + PlaceBase::Local(local) => sets.gen(local), } } } @@ -171,8 +169,10 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { _dest_bb: mir::BasicBlock, dest_place: &mir::Place<'tcx>, ) { - if let PlaceBase::Local(local) = dest_place.base { - in_out.insert(local); + match dest_place.base { + PlaceBase::Local(local) => { + in_out.insert(local); + } } } } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index c05f7f8959dbf..b0be49689f953 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -98,9 +98,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { debug!("lookup({:?})", place); let mut base = match place.base { PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local], - PlaceBase::Static(..) => { - return Err(MoveError::cannot_move_out_of(self.loc, Static)); - } }; // The move path index of the first union that we find. Once this is diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index e5cddaf6c66f2..7133c46d6c70f 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -248,7 +248,6 @@ impl MovePathLookup { pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult { let mut result = match place.base { PlaceBase::Local(local) => self.locals[*local], - PlaceBase::Static(..) => return LookupResult::Parent(None), }; for elem in place.projection.iter() { @@ -281,9 +280,6 @@ pub struct IllegalMoveOrigin<'tcx> { #[derive(Debug)] pub(crate) enum IllegalMoveOriginKind<'tcx> { - /// Illegal move due to attempt to move from `static` variable. - Static, - /// Illegal move due to attempt to move from behind a reference. BorrowedContent { /// The place the reference refers to: if erroneous code was trying to diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index ebe600f25dad1..30725d781dc7f 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -474,7 +474,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.access_local(self.frame(), *local, layout)? } - PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(), }; let op = place diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index aa15f3d1f173e..bd3059951e86b 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -10,7 +10,6 @@ use rustc::mir::interpret::truncate; use rustc::ty::layout::{ self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, }; -use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty}; use rustc_macros::HashStable; @@ -619,35 +618,6 @@ where }) } - /// Evaluate statics and promoteds to an `MPlace`. Used to share some code between - /// `eval_place` and `eval_place_to_op`. - pub(super) fn eval_static_to_mplace( - &self, - place_static: &mir::Static<'tcx>, - ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { - let ty = place_static.ty; - assert!(!ty.needs_subst()); - let layout = self.layout_of(ty)?; - // Just create a lazy reference, so we can support recursive statics. - // tcx takes care of assigning every static one and only one unique AllocId. - // When the data here is ever actually used, memory will notice, - // and it knows how to deal with alloc_id that are present in the - // global table but not in its local memory: It calls back into tcx through - // a query, triggering the CTFE machinery to actually turn this lazy reference - // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this InterpCx uses another Machine (e.g., in miri). This is what we - // want! This way, computing statics works consistently between codegen - // and miri: They use the same query to eventually obtain a `ty::Const` - // and use that for further computation. - // - // Notice that statics have *two* AllocIds: the lazy one, and the resolved - // one. Here we make sure that the interpreted program never sees the - // resolved ID. Also see the doc comment of `Memory::get_static_alloc`. - let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(place_static.def_id); - let ptr = self.tag_static_base_pointer(Pointer::from(alloc_id)); - Ok(MPlaceTy::from_aligned_ptr(ptr, layout)) - } - /// Computes a place. You should only use this if you intend to write into this /// place; for reading, a more efficient alternative is `eval_place_for_read`. pub fn eval_place( @@ -683,7 +653,6 @@ where place: Place::Local { frame: self.cur_frame(), local: *local }, layout: self.layout_of_local(self.frame(), *local, None)?, }, - PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(), }; for elem in place.projection.iter() { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 2ecae7c6b0cd8..5da5695a4d4eb 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,7 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::{self, Location, PlaceBase, Static}; +use rustc::mir::{self, Location, PlaceBase}; use rustc::session::config::EntryFnType; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::print::obsolete::DefPathBasedNames; @@ -642,20 +642,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn visit_place_base( &mut self, - place_base: &mir::PlaceBase<'tcx>, + place_base: &mir::PlaceBase, _context: mir::visit::PlaceContext, - location: Location, + _location: Location, ) { match place_base { - PlaceBase::Static(box Static { def_id, .. }) => { - debug!("visiting static {:?} @ {:?}", def_id, location); - - let tcx = self.tcx; - let instance = Instance::mono(tcx, *def_id); - if should_monomorphize_locally(tcx, &instance) { - self.output.push(MonoItem::Static(*def_id)); - } - } PlaceBase::Local(_) => { // Locals have no relevance for collector. } diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 253a5899768b2..8c52a4e7a29dd 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -76,9 +76,6 @@ pub trait Qualif { ) -> bool { match place { PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local), - PlaceRef { base: PlaceBase::Static(_), projection: [] } => { - bug!("qualifying already promoted MIR") - } PlaceRef { base: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), } } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index b818397247624..c864abdae66a5 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -369,15 +369,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf), - // At the moment, `PlaceBase::Static` is only used for promoted MIR. - Rvalue::Ref(_, BorrowKind::Shared, ref place) - | Rvalue::Ref(_, BorrowKind::Shallow, ref place) - | Rvalue::AddressOf(Mutability::Not, ref place) - if matches!(place.base, PlaceBase::Static(_)) => - { - bug!("Saw a promoted during const-checking, which must run before promotion") - } - Rvalue::Ref(_, BorrowKind::Shared, ref place) | Rvalue::Ref(_, BorrowKind::Shallow, ref place) => { self.check_immutable_borrow_like(location, place) @@ -423,7 +414,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { fn visit_place_base( &mut self, - place_base: &PlaceBase<'tcx>, + place_base: &PlaceBase, context: PlaceContext, location: Location, ) { @@ -437,9 +428,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { match place_base { PlaceBase::Local(_) => {} - PlaceBase::Static(_) => { - bug!("Promotion must be run after const validation"); - } } } @@ -453,7 +441,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } fn visit_projection_elem( &mut self, - place_base: &PlaceBase<'tcx>, + place_base: &PlaceBase, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, @@ -681,9 +669,11 @@ fn place_as_reborrow( // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` // that points to the allocation for the static. Don't treat these as reborrows. - if let PlaceBase::Local(local) = place.base { - if body.local_decls[local].is_ref_to_static() { - return None; + match place.base { + PlaceBase::Local(local) => { + if body.local_decls[local].is_ref_to_static() { + return None; + } } } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index be9c2b741a269..017d0f3467410 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -194,9 +194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { PlaceBase::Local(..) => { // Locals are safe. } - PlaceBase::Static(box Static { .. }) => { - bug!("Static should not exist"); - } } for (i, elem) in place.projection.iter().enumerate() { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 9614137b7e7bf..f9b24b00e8719 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -872,8 +872,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // doesn't use the invalid value match cond { Operand::Move(ref place) | Operand::Copy(ref place) => { - if let PlaceBase::Local(local) = place.base { - self.remove_const(local); + match place.base { + PlaceBase::Local(local) => self.remove_const(local), } } Operand::Constant(_) => {} diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 96fb992e53b23..b075a39951613 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -275,18 +275,18 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { assert_eq!(self.remap.get(local), None); } - fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if let PlaceBase::Local(l) = place.base { + fn visit_place( + &mut self, + place: &mut Place<'tcx>, + _context: PlaceContext, + _location: Location, + ) { + match place.base { + PlaceBase::Local(l) => // Replace an Local in the remap with a generator struct access - if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { - replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); - } - } else { - self.visit_place_base(&mut place.base, context, location); - - for elem in place.projection.iter() { - if let PlaceElem::Index(local) = elem { - assert_ne!(*local, self_arg()); + { + if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { + replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 3c5d2c9f310bb..52992f7d7a8cc 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -431,9 +431,6 @@ impl Inliner<'tcx> { } match place.base { - // Static variables need a borrow because the callee - // might modify the same static. - PlaceBase::Static(_) => true, _ => false, } } @@ -649,7 +646,6 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { if *local == RETURN_PLACE { match self.destination.base { PlaceBase::Local(l) => return l, - PlaceBase::Static(ref s) => bug!("Return place is {:?}, not local", s), } } @@ -673,7 +669,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { match &mut place.base { - PlaceBase::Static(_) => {} PlaceBase::Local(l) => { // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. let dest_proj_len = self.destination.projection.len(); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 76f1e2d186e61..494b61c5d1ee7 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -310,7 +310,6 @@ impl<'tcx> Validator<'_, 'tcx> { // don't get promoted anyway). let base = match place.base { PlaceBase::Local(local) => local, - _ => return Err(Unpromotable), }; self.validate_local(base)?; @@ -482,9 +481,6 @@ impl<'tcx> Validator<'_, 'tcx> { PlaceRef { base: PlaceBase::Local(local), projection: [] } => { self.validate_local(*local) } - PlaceRef { base: PlaceBase::Static(_), projection: [] } => { - bug!("qualifying already promoted MIR") - } PlaceRef { base: _, projection: [proj_base @ .., elem] } => { match *elem { ProjectionElem::Deref | ProjectionElem::Downcast(..) => { @@ -648,7 +644,6 @@ impl<'tcx> Validator<'_, 'tcx> { // `check_consts::qualifs` but without recursion. let mut has_mut_interior = match place.base { PlaceBase::Local(local) => self.qualif_local::(*local), - PlaceBase::Static(_) => false, }; if has_mut_interior { let mut place_projection = place.projection; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index fb7f4fac4dca4..e96baefc8229b 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -388,13 +388,9 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { // Remove unnecessary StorageLive and StorageDead annotations. data.statements.retain(|stmt| match &stmt.kind { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), - StatementKind::Assign(box (place, _)) => { - if let PlaceBase::Local(local) = place.base { - self.map[local].is_some() - } else { - true - } - } + StatementKind::Assign(box (place, _)) => match place.base { + PlaceBase::Local(local) => self.map[local].is_some(), + }, _ => true, }); self.super_basic_block_data(block, data); From 5d9b39904436f6f20e34e85a4e06384116080f56 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2019 16:50:03 -0300 Subject: [PATCH 0154/1253] Remove PlaceBase enum and make Place base field be local: Local --- src/librustc/mir/mod.rs | 64 ++-------- src/librustc/mir/tcx.rs | 19 +-- src/librustc/mir/visit.rs | 32 +++-- src/librustc/ty/codec.rs | 4 +- src/librustc/ty/context.rs | 2 +- .../debuginfo/metadata.rs | 4 +- src/librustc_codegen_ssa/mir/analyze.rs | 18 +-- src/librustc_codegen_ssa/mir/block.rs | 2 +- src/librustc_codegen_ssa/mir/debuginfo.rs | 4 +- src/librustc_codegen_ssa/mir/operand.rs | 62 +++++----- src/librustc_codegen_ssa/mir/place.rs | 32 +++-- src/librustc_mir/borrow_check/borrow_set.rs | 6 +- .../borrow_check/constraint_generation.rs | 17 ++- .../diagnostics/conflict_errors.rs | 62 ++++------ .../borrow_check/diagnostics/mod.rs | 62 +++++----- .../borrow_check/diagnostics/move_errors.rs | 7 +- .../diagnostics/mutability_errors.rs | 58 ++++----- src/librustc_mir/borrow_check/mod.rs | 111 +++++++----------- src/librustc_mir/borrow_check/path_utils.rs | 10 +- src/librustc_mir/borrow_check/place_ext.rs | 47 ++++---- .../borrow_check/places_conflict.rs | 38 +++--- src/librustc_mir/borrow_check/prefixes.rs | 24 ++-- .../borrow_check/type_check/mod.rs | 6 +- src/librustc_mir/borrow_check/used_muts.rs | 20 ++-- src/librustc_mir/build/expr/as_place.rs | 20 ++-- src/librustc_mir/build/expr/as_rvalue.rs | 16 ++- src/librustc_mir/build/matches/mod.rs | 6 +- src/librustc_mir/build/mod.rs | 2 +- .../dataflow/impls/borrowed_locals.rs | 5 +- src/librustc_mir/dataflow/impls/borrows.rs | 56 ++++----- .../dataflow/impls/indirect_mutation.rs | 8 +- .../dataflow/impls/storage_liveness.rs | 24 ++-- .../dataflow/move_paths/builder.rs | 16 ++- src/librustc_mir/dataflow/move_paths/mod.rs | 4 +- src/librustc_mir/interpret/operand.rs | 10 +- src/librustc_mir/interpret/place.rs | 12 +- src/librustc_mir/monomorphize/collector.rs | 9 +- .../transform/check_consts/qualifs.rs | 17 +-- .../transform/check_consts/resolver.rs | 6 +- .../transform/check_consts/validation.rs | 49 +++----- src/librustc_mir/transform/check_unsafety.rs | 15 +-- src/librustc_mir/transform/const_prop.rs | 6 +- src/librustc_mir/transform/generator.rs | 27 ++--- src/librustc_mir/transform/inline.rs | 28 ++--- src/librustc_mir/transform/instcombine.rs | 8 +- src/librustc_mir/transform/promote_consts.rs | 47 ++++---- .../transform/qualify_min_const_fn.rs | 2 +- src/librustc_mir/transform/simplify.rs | 4 +- src/librustc_mir/transform/simplify_try.rs | 4 +- src/librustc_mir/util/alignment.rs | 2 +- 50 files changed, 457 insertions(+), 657 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 05bb1d9698016..32d85314c7ab7 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1655,7 +1655,7 @@ impl Debug for Statement<'_> { /// changing or disturbing program state. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] pub struct Place<'tcx> { - pub base: PlaceBase, + pub local: Local, /// projection out of a place (access a field, deref a pointer, etc) pub projection: &'tcx List>, @@ -1663,12 +1663,6 @@ pub struct Place<'tcx> { impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] -pub enum PlaceBase { - /// local variable - Local(Local), -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(RustcEncodable, RustcDecodable, HashStable)] pub enum ProjectionElem { @@ -1756,14 +1750,14 @@ rustc_index::newtype_index! { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct PlaceRef<'a, 'tcx> { - pub base: &'a PlaceBase, + pub local: &'a Local, pub projection: &'a [PlaceElem<'tcx>], } impl<'tcx> Place<'tcx> { // FIXME change this to a const fn by also making List::empty a const fn. pub fn return_place() -> Place<'tcx> { - Place { base: PlaceBase::Local(RETURN_PLACE), projection: List::empty() } + Place { local: RETURN_PLACE, projection: List::empty() } } /// Returns `true` if this `Place` contains a `Deref` projection. @@ -1780,10 +1774,8 @@ impl<'tcx> Place<'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } - | PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref] } => { - Some(local) - } + PlaceRef { local, projection: &[] } + | PlaceRef { local, projection: &[ProjectionElem::Deref] } => Some(*local), _ => None, } } @@ -1795,19 +1787,13 @@ impl<'tcx> Place<'tcx> { } pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> { - PlaceRef { base: &self.base, projection: &self.projection } + PlaceRef { local: &self.local, projection: &self.projection } } } impl From for Place<'_> { fn from(local: Local) -> Self { - Place { base: local.into(), projection: List::empty() } - } -} - -impl From for PlaceBase { - fn from(local: Local) -> Self { - PlaceBase::Local(local) + Place { local: local.into(), projection: List::empty() } } } @@ -1818,10 +1804,8 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self { - PlaceRef { base: PlaceBase::Local(local), projection: [] } - | PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } => { - Some(*local) - } + PlaceRef { local, projection: [] } + | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(**local), _ => None, } } @@ -1830,7 +1814,7 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> { /// projections, return `Some(_X)`. pub fn as_local(&self) -> Option { match self { - PlaceRef { base: PlaceBase::Local(l), projection: [] } => Some(*l), + PlaceRef { local, projection: [] } => Some(**local), _ => None, } } @@ -1852,7 +1836,7 @@ impl Debug for Place<'_> { } } - write!(fmt, "{:?}", self.base)?; + write!(fmt, "{:?}", self.local)?; for elem in self.projection.iter() { match elem { @@ -1896,14 +1880,6 @@ impl Debug for Place<'_> { } } -impl Debug for PlaceBase { - fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { - match *self { - PlaceBase::Local(id) => write!(fmt, "{:?}", id), - } - } -} - /////////////////////////////////////////////////////////////////////////// // Scopes @@ -2964,25 +2940,11 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - Place { base: self.base.fold_with(folder), projection: self.projection.fold_with(folder) } + Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.base.visit_with(visitor) || self.projection.visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for PlaceBase { - fn super_fold_with>(&self, folder: &mut F) -> Self { - match self { - PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match self { - PlaceBase::Local(local) => local.visit_with(visitor), - } + self.local.visit_with(visitor) || self.projection.visit_with(visitor) } } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 5adf6447d3981..e2aac562cc4cc 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -114,7 +114,7 @@ impl<'tcx> PlaceTy<'tcx> { impl<'tcx> Place<'tcx> { pub fn ty_from( - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], local_decls: &D, tcx: TyCtxt<'tcx>, @@ -124,25 +124,16 @@ impl<'tcx> Place<'tcx> { { projection .iter() - .fold(base.ty(local_decls), |place_ty, elem| place_ty.projection_ty(tcx, elem)) + .fold(PlaceTy::from_ty(local_decls.local_decls()[*local].ty), |place_ty, elem| { + place_ty.projection_ty(tcx, elem) + }) } pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> where D: HasLocalDecls<'tcx>, { - Place::ty_from(&self.base, &self.projection, local_decls, tcx) - } -} - -impl<'tcx> PlaceBase { - pub fn ty(&self, local_decls: &D) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, - { - match self { - PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty), - } + Place::ty_from(&self.local, &self.projection, local_decls, tcx) } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index a31931c8a99bc..4c5db1b07d225 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -164,10 +164,10 @@ macro_rules! make_mir_visitor { } fn visit_place_base(&mut self, - base: & $($mutability)? PlaceBase, + local: & $($mutability)? Local, context: PlaceContext, location: Location) { - self.super_place_base(base, context, location); + self.super_place_base(local, context, location); } visit_place_fns!($($mutability)?); @@ -705,14 +705,10 @@ macro_rules! make_mir_visitor { } fn super_place_base(&mut self, - place_base: & $($mutability)? PlaceBase, + local: & $($mutability)? Local, context: PlaceContext, location: Location) { - match place_base { - PlaceBase::Local(local) => { - self.visit_local(local, context, location); - } - } + self.visit_local(local, context, location); } fn super_local_decl(&mut self, @@ -845,7 +841,7 @@ macro_rules! visit_place_fns { context: PlaceContext, location: Location, ) { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); if let Some(new_projection) = self.process_projection(&place.projection) { place.projection = self.tcx().intern_place_elems(&new_projection); @@ -886,23 +882,23 @@ macro_rules! visit_place_fns { () => ( fn visit_projection( &mut self, - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, ) { - self.super_projection(base, projection, context, location); + self.super_projection(local, projection, context, location); } fn visit_projection_elem( &mut self, - base: &PlaceBase, + local: &Local, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { - self.super_projection_elem(base, proj_base, elem, context, location); + self.super_projection_elem(local, proj_base, elem, context, location); } fn super_place( @@ -921,9 +917,9 @@ macro_rules! visit_place_fns { }; } - self.visit_place_base(&place.base, context, location); + self.visit_place_base(&place.local, context, location); - self.visit_projection(&place.base, + self.visit_projection(&place.local, &place.projection, context, location); @@ -931,7 +927,7 @@ macro_rules! visit_place_fns { fn super_projection( &mut self, - base: &PlaceBase, + local: &Local, projection: &[PlaceElem<'tcx>], context: PlaceContext, location: Location, @@ -939,13 +935,13 @@ macro_rules! visit_place_fns { let mut cursor = projection; while let [proj_base @ .., elem] = cursor { cursor = proj_base; - self.visit_projection_elem(base, cursor, elem, context, location); + self.visit_projection_elem(local, cursor, elem, context, location); } } fn super_projection_elem( &mut self, - _base: &PlaceBase, + _local: &Local, _proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, _context: PlaceContext, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index c691cb44f0118..df1602b2ac46d 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -226,11 +226,11 @@ pub fn decode_place(decoder: &mut D) -> Result, D::Error> where D: TyDecoder<'tcx>, { - let base: mir::PlaceBase = Decodable::decode(decoder)?; + let local: mir::Local = Decodable::decode(decoder)?; let len = decoder.read_usize()?; let projection: &'tcx List> = decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; - Ok(mir::Place { base, projection }) + Ok(mir::Place { local, projection }) } #[inline] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 17f5b98ab208b..52a151439dcb7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2434,7 +2434,7 @@ impl<'tcx> TyCtxt<'tcx> { let mut projection = place.projection.to_vec(); projection.push(elem); - Place { base: place.base, projection: self.intern_place_elems(&projection) } + Place { local: place.local, projection: self.intern_place_elems(&projection) } } pub fn intern_existential_predicates( diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 8d8e86de4d464..d1f70ad43bd28 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1286,9 +1286,9 @@ fn generator_layout_and_saved_local_names( let generator_layout = body.generator_layout.as_ref().unwrap(); let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys); - let state_arg = mir::PlaceBase::Local(mir::Local::new(1)); + let state_arg = mir::Local::new(1); for var in &body.var_debug_info { - if var.place.base != state_arg { + if var.place.local != state_arg { continue; } match var.place.projection[..] { diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 7b9bc923cd6fd..c3affd233f8e3 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -128,17 +128,13 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { }; if is_consume { let base_ty = - mir::Place::ty_from(place_ref.base, proj_base, *self.fx.mir, cx.tcx()); + mir::Place::ty_from(place_ref.local, proj_base, *self.fx.mir, cx.tcx()); let base_ty = self.fx.monomorphize(&base_ty); // ZSTs don't require any actual memory access. let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty; let elem_ty = self.fx.monomorphize(&elem_ty); - let span = match place_ref.base { - mir::PlaceBase::Local(index) => { - self.fx.mir.local_decls[*index].source_info.span - } - }; + let span = self.fx.mir.local_decls[*place_ref.local].source_info.span; if cx.spanned_layout_of(elem_ty, span).is_zst() { return; } @@ -178,9 +174,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { // We use `NonUseContext::VarDebugInfo` for the base, // which might not force the base local to memory, // so we have to do it manually. - match place_ref.base { - mir::PlaceBase::Local(local) => self.visit_local(&local, context, location), - } + self.visit_local(place_ref.local, context, location); } } @@ -191,7 +185,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { } self.process_place( - &mir::PlaceRef { base: place_ref.base, projection: proj_base }, + &mir::PlaceRef { local: place_ref.local, projection: proj_base }, base_context, location, ); @@ -218,8 +212,8 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { }; } - self.visit_place_base(place_ref.base, context, location); - self.visit_projection(place_ref.base, place_ref.projection, context, location); + self.visit_place_base(place_ref.local, context, location); + self.visit_projection(place_ref.local, place_ref.projection, context, location); } } } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index a1ff62fde0af0..fa79541701e41 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1109,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { self.codegen_place( bx, - &mir::PlaceRef { base: &dest.base, projection: &dest.projection }, + &mir::PlaceRef { local: &dest.local, projection: &dest.projection }, ) }; if fn_ret.is_indirect() { diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index 88e43c7f53528..e0aec5d6dd512 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -258,9 +258,7 @@ pub fn per_local_var_debug_info( if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() { let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); for var in &body.var_debug_info { - match var.place.base { - mir::PlaceBase::Local(local) => per_local[local].push(var), - } + per_local[var.place.local].push(var); } Some(per_local) } else { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index be6e05b948c7c..a155a6e78f7c3 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -373,43 +373,39 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); - match place_ref.base { - mir::PlaceBase::Local(index) => { - match self.locals[*index] { - LocalRef::Operand(Some(mut o)) => { - // Moves out of scalar and scalar pair fields are trivial. - for elem in place_ref.projection.iter() { - match elem { - mir::ProjectionElem::Field(ref f, _) => { - o = o.extract_field(bx, f.index()); - } - mir::ProjectionElem::Index(_) - | mir::ProjectionElem::ConstantIndex { .. } => { - // ZSTs don't require any actual memory access. - // FIXME(eddyb) deduplicate this with the identical - // checks in `codegen_consume` and `extract_field`. - let elem = o.layout.field(bx.cx(), 0); - if elem.is_zst() { - o = OperandRef::new_zst(bx, elem); - } else { - return None; - } - } - _ => return None, + match self.locals[*place_ref.local] { + LocalRef::Operand(Some(mut o)) => { + // Moves out of scalar and scalar pair fields are trivial. + for elem in place_ref.projection.iter() { + match elem { + mir::ProjectionElem::Field(ref f, _) => { + o = o.extract_field(bx, f.index()); + } + mir::ProjectionElem::Index(_) + | mir::ProjectionElem::ConstantIndex { .. } => { + // ZSTs don't require any actual memory access. + // FIXME(eddyb) deduplicate this with the identical + // checks in `codegen_consume` and `extract_field`. + let elem = o.layout.field(bx.cx(), 0); + if elem.is_zst() { + o = OperandRef::new_zst(bx, elem); + } else { + return None; } } - - Some(o) - } - LocalRef::Operand(None) => { - bug!("use of {:?} before def", place_ref); - } - LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { - // watch out for locals that do not have an - // alloca; they are handled somewhat differently - None + _ => return None, } } + + Some(o) + } + LocalRef::Operand(None) => { + bug!("use of {:?} before def", place_ref); + } + LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { + // watch out for locals that do not have an + // alloca; they are handled somewhat differently + None } } } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 3d94cf9aa2c46..5e03a35b8a6fd 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -415,28 +415,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let tcx = self.cx.tcx(); let result = match place_ref { - mir::PlaceRef { base: mir::PlaceBase::Local(index), projection: [] } => { - match self.locals[*index] { - LocalRef::Place(place) => { - return place; - } - LocalRef::UnsizedPlace(place) => { - return bx.load_operand(place).deref(cx); - } - LocalRef::Operand(..) => { - bug!("using operand local {:?} as place", place_ref); - } + mir::PlaceRef { local, projection: [] } => match self.locals[**local] { + LocalRef::Place(place) => { + return place; } - } - mir::PlaceRef { base, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => { + LocalRef::UnsizedPlace(place) => { + return bx.load_operand(place).deref(cx); + } + LocalRef::Operand(..) => { + bug!("using operand local {:?} as place", place_ref); + } + }, + mir::PlaceRef { local, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => { // Load the pointer from its location. - self.codegen_consume(bx, &mir::PlaceRef { base, projection: proj_base }) + self.codegen_consume(bx, &mir::PlaceRef { local, projection: proj_base }) .deref(bx.cx()) } - mir::PlaceRef { base, projection: [proj_base @ .., elem] } => { + mir::PlaceRef { local, projection: [proj_base @ .., elem] } => { // FIXME turn this recursion into iteration let cg_base = - self.codegen_place(bx, &mir::PlaceRef { base, projection: proj_base }); + self.codegen_place(bx, &mir::PlaceRef { local, projection: proj_base }); match elem { mir::ProjectionElem::Deref => bug!(), @@ -501,7 +499,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphized_place_ty(&self, place_ref: &mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); - let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, *self.mir, tcx); + let place_ty = mir::Place::ty_from(place_ref.local, place_ref.projection, *self.mir, tcx); self.monomorphize(&place_ty.ty) } } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 4c6b9bc02a4ba..f2a44986cc4d4 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -208,11 +208,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - match borrowed_place.base { - mir::PlaceBase::Local(local) => { - self.local_map.entry(local).or_default().insert(idx); - } - } + self.local_map.entry(borrowed_place.local).or_default().insert(idx); } self.super_assign(assigned_place, rvalue, location) diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index 2a9ad6a1505da..0f6a360c7933b 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -2,8 +2,8 @@ use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; use rustc::mir::{ - BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, PlaceRef, ProjectionElem, - Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection, + BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, + SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection, }; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::SubstsRef; @@ -188,11 +188,8 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { // of the borrows are killed: the ones whose `borrowed_place` // conflicts with the `place`. match place.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } - | PlaceRef { - base: &PlaceBase::Local(local), - projection: &[ProjectionElem::Deref], - } => { + PlaceRef { local, projection: &[] } + | PlaceRef { local, projection: &[ProjectionElem::Deref] } => { debug!( "Recording `killed` facts for borrows of local={:?} at location={:?}", local, location @@ -202,12 +199,12 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { all_facts, self.borrow_set, self.location_table, - &local, + local, location, ); } - PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => { + PlaceRef { local, projection: &[.., _] } => { // Kill conflicting borrows of the innermost local. debug!( "Recording `killed` facts for borrows of \ @@ -215,7 +212,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { local, location ); - if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { + if let Some(borrow_indices) = self.borrow_set.local_map.get(local) { for &borrow_index in borrow_indices { let places_conflict = places_conflict::places_conflict( self.infcx.tcx, diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index dc3157f6b4d9c..08333ae423da7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1,7 +1,7 @@ use rustc::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, - FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceBase, - PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, + FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, + ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; use rustc::traits::error_reporting::suggest_constraining_type_param; use rustc::ty::{self, Ty}; @@ -186,7 +186,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let ty = - Place::ty_from(used_place.base, used_place.projection, *self.body, self.infcx.tcx) + Place::ty_from(used_place.local, used_place.projection, *self.body, self.infcx.tcx) .ty; let needs_note = match ty.kind { ty::Closure(id, _) => { @@ -597,15 +597,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // field access to a union. If we find that, then we will keep the place of the // union being accessed and the field that was being accessed so we can check the // second borrowed place for the same union and a access to a different field. - let Place { base, projection } = first_borrowed_place; + let Place { local, projection } = first_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { cursor = proj_base; match elem { - ProjectionElem::Field(field, _) if union_ty(base, proj_base).is_some() => { - return Some((PlaceRef { base: base, projection: proj_base }, field)); + ProjectionElem::Field(field, _) if union_ty(local, proj_base).is_some() => { + return Some((PlaceRef { local, projection: proj_base }, field)); } _ => {} } @@ -615,21 +615,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|(target_base, target_field)| { // With the place of a union and a field access into it, we traverse the second // borrowed place and look for a access to a different field of the same union. - let Place { base, projection } = second_borrowed_place; + let Place { local, projection } = second_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { cursor = proj_base; if let ProjectionElem::Field(field, _) = elem { - if let Some(union_ty) = union_ty(base, proj_base) { + if let Some(union_ty) = union_ty(local, proj_base) { if field != target_field - && base == target_base.base + && local == target_base.local && proj_base == target_base.projection { // FIXME when we avoid clone reuse describe_place closure let describe_base_place = self - .describe_place(PlaceRef { base: base, projection: proj_base }) + .describe_place(PlaceRef { local, projection: proj_base }) .unwrap_or_else(|| "_".to_owned()); return Some(( @@ -686,14 +686,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_span = borrow_spans.var_or_use(); assert!(root_place.projection.is_empty()); - let proper_span = match root_place.base { - PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span, - }; + let proper_span = self.body.local_decls[*root_place.local].source_info.span; let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); if self.access_place_error_reported.contains(&( - Place { base: root_place.base.clone(), projection: root_place_projection }, + Place { local: root_place.local.clone(), projection: root_place_projection }, borrow_span, )) { debug!( @@ -704,22 +702,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } self.access_place_error_reported.insert(( - Place { base: root_place.base.clone(), projection: root_place_projection }, + Place { local: root_place.local.clone(), projection: root_place_projection }, borrow_span, )); - match borrow.borrowed_place.base { - PlaceBase::Local(local) => { - if self.body.local_decls[local].is_ref_to_thread_local() { - let err = self.report_thread_local_value_does_not_live_long_enough( - drop_span, - borrow_span, - ); - err.buffer(&mut self.errors_buffer); - return; - } - } - }; + let borrowed_local = borrow.borrowed_place.local; + if self.body.local_decls[borrowed_local].is_ref_to_thread_local() { + let err = + self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span); + err.buffer(&mut self.errors_buffer); + return; + } if let StorageDeadOrDrop::Destructor(dropped_ty) = self.classify_drop_access_kind(borrow.borrowed_place.as_ref()) @@ -1145,12 +1138,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); - let local = - if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = root_place { - local - } else { - bug!("try_report_cannot_return_reference_to_local: not a local") - }; + let local = root_place.local; match self.body.local_kind(*local) { LocalKind::ReturnPointer | LocalKind::Temp => { ("temporary value".to_string(), "temporary value created here".to_string()) @@ -1517,7 +1505,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { [proj_base @ .., elem] => { // FIXME(spastorino) make this iterate let base_access = self.classify_drop_access_kind(PlaceRef { - base: place.base, + local: place.local, projection: proj_base, }); match elem { @@ -1525,7 +1513,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { StorageDeadOrDrop::LocalStorageDead | StorageDeadOrDrop::BoxedStorageDead => { assert!( - Place::ty_from(&place.base, proj_base, *self.body, tcx).ty.is_box(), + Place::ty_from(&place.local, proj_base, *self.body, tcx) + .ty + .is_box(), "Drop of value behind a reference or raw pointer" ); StorageDeadOrDrop::BoxedStorageDead @@ -1533,7 +1523,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { StorageDeadOrDrop::Destructor(_) => base_access, }, ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, tcx).ty; match base_ty.kind { ty::Adt(def, _) if def.has_dtor(tcx) => { // Report the outermost adt with a destructor diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 38c479c72c1e7..3f3bdb9d36c76 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -2,8 +2,7 @@ use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, + PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; @@ -169,30 +168,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { including_downcast: &IncludingDowncast, ) -> Result<(), ()> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { self.append_local_to_string(*local, buf)?; } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_for_guard() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_for_guard() => { self.append_place_to_string( - PlaceRef { base: &PlaceBase::Local(local), projection: &[] }, + PlaceRef { local: local, projection: &[] }, buf, autoderef, &including_downcast, )?; } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_to_static() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_to_static() => { - let local_info = &self.body.local_decls[local].local_info; + let local_info = &self.body.local_decls[*local].local_info; if let LocalInfo::StaticRef { def_id, .. } = *local_info { buf.push_str(&self.infcx.tcx.item_name(def_id).as_str()); } else { unreachable!(); } } - PlaceRef { base, projection: [proj_base @ .., elem] } => { + PlaceRef { local, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { let upvar_field_projection = self.is_upvar_field_projection(place); @@ -208,29 +207,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if autoderef { // FIXME turn this recursion into iteration self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, )?; } else { - match (proj_base, base) { - _ => { - buf.push_str(&"*"); - self.append_place_to_string( - PlaceRef { base, projection: proj_base }, - buf, - autoderef, - &including_downcast, - )?; - } - } + buf.push_str(&"*"); + self.append_place_to_string( + PlaceRef { local, projection: proj_base }, + buf, + autoderef, + &including_downcast, + )?; } } } ProjectionElem::Downcast(..) => { self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -249,9 +244,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { buf.push_str(&name); } else { let field_name = self - .describe_field(PlaceRef { base, projection: proj_base }, *field); + .describe_field(PlaceRef { local, projection: proj_base }, *field); self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -263,7 +258,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { autoderef = true; self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -280,7 +275,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // then use another while the borrow is held, don't output indices details // to avoid confusing the end-user self.append_place_to_string( - PlaceRef { base, projection: proj_base }, + PlaceRef { local, projection: proj_base }, buf, autoderef, &including_downcast, @@ -311,17 +306,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { // FIXME Place2 Make this work iteratively match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[*local]; self.describe_field_from_ty(&local.ty, field, None) } - PlaceRef { base, projection: [proj_base @ .., elem] } => match elem { + PlaceRef { local, projection: [proj_base @ .., elem] } => match elem { ProjectionElem::Deref => { - self.describe_field(PlaceRef { base, projection: proj_base }, field) + self.describe_field(PlaceRef { local, projection: proj_base }, field) } ProjectionElem::Downcast(_, variant_index) => { let base_ty = - Place::ty_from(place.base, place.projection, *self.body, self.infcx.tcx).ty; + Place::ty_from(place.local, place.projection, *self.body, self.infcx.tcx) + .ty; self.describe_field_from_ty(&base_ty, field, Some(*variant_index)) } ProjectionElem::Field(_, field_type) => { @@ -330,7 +326,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { - self.describe_field(PlaceRef { base, projection: proj_base }, field) + self.describe_field(PlaceRef { local, projection: proj_base }, field) } }, } @@ -451,7 +447,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If we didn't find an overloaded deref or index, then assume it's a // built in deref and check the type of the base. - let base_ty = Place::ty_from(deref_base.base, deref_base.projection, *self.body, tcx).ty; + let base_ty = Place::ty_from(deref_base.local, deref_base.projection, *self.body, tcx).ty; if base_ty.is_unsafe_ptr() { BorrowedContentSource::DerefRawPointer } else if base_ty.is_mutable_ptr() { diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index ceb97a98f1f7e..eb6db7c145c3c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -273,7 +273,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let description = if place.projection.len() == 1 { format!("static item `{}`", self.describe_place(place.as_ref()).unwrap()) } else { - let base_static = PlaceRef { base: &place.base, projection: &[ProjectionElem::Deref] }; + let base_static = + PlaceRef { local: &place.local, projection: &[ProjectionElem::Deref] }; format!( "`{:?}` as `{:?}` is a static item", @@ -302,12 +303,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let deref_base = match deref_target_place.projection.as_ref() { &[ref proj_base @ .., ProjectionElem::Deref] => { - PlaceRef { base: &deref_target_place.base, projection: &proj_base } + PlaceRef { local: &deref_target_place.local, projection: &proj_base } } _ => bug!("deref_target_place is not a deref projection"), }; - if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = deref_base { + if let PlaceRef { local, projection: [] } = deref_base { let decl = &self.body.local_decls[*local]; if decl.is_ref_for_guard() { let mut err = self.cannot_move_out_of( diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index e81a012cef59a..ae468e83ae253 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -1,5 +1,5 @@ use rustc::mir::{self, ClearCrossCrate, Local, LocalInfo, Location, ReadOnlyBodyAndCache}; -use rustc::mir::{Mutability, Place, PlaceBase, PlaceRef, ProjectionElem}; +use rustc::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; use rustc_hir::Node; @@ -42,7 +42,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); match the_place_err { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { item_msg = format!("`{}`", access_place_desc.unwrap()); if access_place.as_local().is_some() { reason = ", as it is not declared as mutable".to_string(); @@ -53,11 +53,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } PlaceRef { - base: _, + local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { debug_assert!(is_closure_or_generator( - Place::ty_from(&the_place_err.base, proj_base, *self.body, self.infcx.tcx).ty + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty )); item_msg = format!("`{}`", access_place_desc.unwrap()); @@ -69,21 +69,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_for_guard() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_for_guard() => { item_msg = format!("`{}`", access_place_desc.unwrap()); reason = ", as it is immutable for the pattern guard".to_string(); } - PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } - if self.body.local_decls[local].is_ref_to_static() => + PlaceRef { local, projection: [ProjectionElem::Deref] } + if self.body.local_decls[*local].is_ref_to_static() => { if access_place.projection.len() == 1 { item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); reason = String::new(); } else { item_msg = format!("`{}`", access_place_desc.unwrap()); - let local_info = &self.body.local_decls[local].local_info; + let local_info = &self.body.local_decls[*local].local_info; if let LocalInfo::StaticRef { def_id, .. } = *local_info { let static_name = &self.infcx.tcx.item_name(def_id); reason = format!(", as `{}` is an immutable static item", static_name); @@ -92,8 +92,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } } - PlaceRef { base: _, projection: [proj_base @ .., ProjectionElem::Deref] } => { - if the_place_err.base == &PlaceBase::Local(Local::new(1)) + PlaceRef { local: _, projection: [proj_base @ .., ProjectionElem::Deref] } => { + if *the_place_err.local == Local::new(1) && proj_base.is_empty() && !self.upvars.is_empty() { @@ -101,7 +101,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr()); debug_assert!(is_closure_or_generator( Place::ty_from( - the_place_err.base, + the_place_err.local, the_place_err.projection, *self.body, self.infcx.tcx @@ -116,7 +116,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } else { let source = self.borrowed_content_source(PlaceRef { - base: the_place_err.base, + local: the_place_err.local, projection: proj_base, }); let pointer_type = source.describe_for_immutable_place(); @@ -136,10 +136,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] } - | PlaceRef { base: _, projection: [.., ProjectionElem::ConstantIndex { .. }] } - | PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] } - | PlaceRef { base: _, projection: [.., ProjectionElem::Downcast(..)] } => { + PlaceRef { local: _, projection: [.., ProjectionElem::Index(_)] } + | PlaceRef { local: _, projection: [.., ProjectionElem::ConstantIndex { .. }] } + | PlaceRef { local: _, projection: [.., ProjectionElem::Subslice { .. }] } + | PlaceRef { local: _, projection: [.., ProjectionElem::Downcast(..)] } => { bug!("Unexpected immutable place.") } } @@ -187,7 +187,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // struct we've got a field access of (it must be a reference since there's a deref // after the field access). PlaceRef { - base, + local, projection: [proj_base @ .., ProjectionElem::Deref, ProjectionElem::Field(field, _), ProjectionElem::Deref], } => { @@ -195,7 +195,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some((span, message)) = annotate_struct_field( self.infcx.tcx, - Place::ty_from(base, proj_base, *self.body, self.infcx.tcx).ty, + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty, field, ) { err.span_suggestion( @@ -208,7 +208,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // Suggest removing a `&mut` from the use of a mutable reference. - PlaceRef { base: PlaceBase::Local(local), projection: [] } + PlaceRef { local, projection: [] } if { self.body .local_decls @@ -246,7 +246,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // We want to suggest users use `let mut` for local (user // variable) mutations... - PlaceRef { base: PlaceBase::Local(local), projection: [] } + PlaceRef { local, projection: [] } if self.body.local_decls[*local].can_be_made_mutable() => { // ... but it doesn't make sense to suggest it on @@ -267,11 +267,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Also suggest adding mut for upvars PlaceRef { - base, + local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { debug_assert!(is_closure_or_generator( - Place::ty_from(base, proj_base, *self.body, self.infcx.tcx).ty + Place::ty_from(local, proj_base, *self.body, self.infcx.tcx).ty )); err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -298,7 +298,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // complete hack to approximate old AST-borrowck // diagnostic: if the span starts with a mutable borrow of // a local variable, then just suggest the user remove it. - PlaceRef { base: PlaceBase::Local(_), projection: [] } + PlaceRef { local: _, projection: [] } if { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { snippet.starts_with("&mut ") @@ -311,7 +311,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_label(span, "try removing `&mut` here"); } - PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + PlaceRef { local, projection: [ProjectionElem::Deref] } if self.body.local_decls[*local].is_ref_for_guard() => { err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -325,7 +325,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // // FIXME: can this case be generalized to work for an // arbitrary base for the projection? - PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + PlaceRef { local, projection: [ProjectionElem::Deref] } if self.body.local_decls[*local].is_user_variable() => { let local_decl = &self.body.local_decls[*local]; @@ -408,10 +408,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } PlaceRef { - base, + local, projection: [ProjectionElem::Deref], // FIXME document what is this 1 magic number about - } if *base == PlaceBase::Local(Local::new(1)) && !self.upvars.is_empty() => { + } if *local == Local::new(1) && !self.upvars.is_empty() => { err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_help( self.body.span, @@ -419,7 +419,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } - PlaceRef { base: _, projection: [.., ProjectionElem::Deref] } => { + PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => { err.span_label(span, format!("cannot {ACT}", ACT = act)); match opt_source { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index d0b0a159e8664..7b0a103fd0038 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -5,7 +5,7 @@ use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, - PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, + PlaceElem, PlaceRef, ReadOnlyBodyAndCache, }; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -815,7 +815,7 @@ enum InitializationRequiringAction { } struct RootPlace<'d, 'tcx> { - place_base: &'d PlaceBase, + place_local: &'d Local, place_projection: &'d [PlaceElem<'tcx>], is_local_mutation_allowed: LocalMutationIsAllowed, } @@ -1252,11 +1252,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { this.used_mut_upvars.push(field); } } else { - match place.base { - PlaceBase::Local(local) => { - this.used_mut.insert(local); - } - } + this.used_mut.insert(place.local); } }; @@ -1380,7 +1376,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("check_for_invalidation_at_exit({:?})", borrow); let place = &borrow.borrowed_place; let deref = [ProjectionElem::Deref]; - let mut root_place = PlaceRef { base: &place.base, projection: &[] }; + let mut root_place = PlaceRef { local: &place.local, projection: &[] }; // FIXME(nll-rfc#40): do more precise destructor tracking here. For now // we just know that all locals are dropped at function exit (otherwise @@ -1388,19 +1384,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // // FIXME: allow thread-locals to borrow other thread locals? - let (might_be_alive, will_be_dropped) = match root_place.base { - PlaceBase::Local(local) => { - if self.body.local_decls[*local].is_ref_to_thread_local() { - // Thread-locals might be dropped after the function exits - // We have to dereference the outer reference because - // borrows don't conflict behind shared references. - root_place.projection = &deref; - (true, true) - } else { - (false, self.locals_are_invalidated_at_exit) - } - } - }; + let (might_be_alive, will_be_dropped) = + if self.body.local_decls[*root_place.local].is_ref_to_thread_local() { + // Thread-locals might be dropped after the function exits + // We have to dereference the outer reference because + // borrows don't conflict behind shared references. + root_place.projection = &deref; + (true, true) + } else { + (false, self.locals_are_invalidated_at_exit) + }; if !will_be_dropped { debug!("place_is_invalidated_at_exit({:?}) - won't be dropped", place); @@ -1738,9 +1731,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place_span.0.projection { let place_ty = - Place::ty_from(place_span.0.base, base_proj, self.body(), self.infcx.tcx); + Place::ty_from(place_span.0.local, base_proj, self.body(), self.infcx.tcx); if let ty::Array(..) = place_ty.ty.kind { - let array_place = PlaceRef { base: place_span.0.base, projection: base_proj }; + let array_place = PlaceRef { local: place_span.0.local, projection: base_proj }; self.check_if_subslice_element_is_moved( location, desired_action, @@ -1837,7 +1830,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_full_path_is_moved( location, InitializationRequiringAction::Use, (PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span), flow_state); // (base initialized; no need to @@ -1855,13 +1848,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // assigning to `P.f` requires `P` itself // be already initialized let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(&place.base, proj_base, self.body(), tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, self.body(), tcx).ty; match base_ty.kind { ty::Adt(def, _) if def.has_dtor(tcx) => { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Assignment, (PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span), flow_state); @@ -1874,23 +1867,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // is allowed, remove this match arm. ty::Adt(..) | ty::Tuple(..) => { check_parent_of_field(self, location, PlaceRef { - base: &place.base, + local: &place.local, projection: proj_base, }, span, flow_state); - match place.base { - // rust-lang/rust#21232, - // #54499, #54986: during - // period where we reject - // partial initialization, do - // not complain about - // unnecessary `mut` on an - // attempt to do a partial - // initialization. - PlaceBase::Local(local) => { - self.used_mut.insert(local); - } - } + // rust-lang/rust#21232, #54499, #54986: during period where we reject + // partial initialization, do not complain about unnecessary `mut` on + // an attempt to do a partial initialization. + self.used_mut.insert(place.local); } _ => {} @@ -1968,7 +1952,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // of the union - we should error in that case. let tcx = this.infcx.tcx; if let ty::Adt(def, _) = - Place::ty_from(base.base, base.projection, this.body(), tcx).ty.kind + Place::ty_from(base.local, base.projection, this.body(), tcx).ty.kind { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { @@ -2087,9 +2071,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = match place.base { - PlaceBase::Local(local) => self.is_local_ever_initialized(local, flow_state).is_some(), - }; + let previously_initialized = + self.is_local_ever_initialized(place.local, flow_state).is_some(); // at this point, we have set up the error reporting state. if previously_initialized { @@ -2118,11 +2101,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Adds the place into the used mutable variables set fn add_used_mut<'d>(&mut self, root_place: RootPlace<'d, 'tcx>, flow_state: &Flows<'cx, 'tcx>) { match root_place { - RootPlace { - place_base: PlaceBase::Local(local), - place_projection: [], - is_local_mutation_allowed, - } => { + RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being // mutated, then it is justified to be annotated with the `mut` // keyword, since the mutation may be a possible reassignment. @@ -2133,18 +2112,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } RootPlace { - place_base: _, + place_local: _, place_projection: _, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, } => {} RootPlace { - place_base, + place_local, place_projection: place_projection @ [.., _], is_local_mutation_allowed: _, } => { if let Some(field) = self.is_upvar_field_projection(PlaceRef { - base: &place_base, - projection: &place_projection, + local: place_local, + projection: place_projection, }) { self.used_mut_upvars.push(field); } @@ -2160,34 +2139,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { is_local_mutation_allowed: LocalMutationIsAllowed, ) -> Result, PlaceRef<'d, 'tcx>> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[*local]; match local.mutability { Mutability::Not => match is_local_mutation_allowed { LocalMutationIsAllowed::Yes => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, }), LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars, }), LocalMutationIsAllowed::No => Err(place), }, Mutability::Mut => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }), } } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { let base_ty = - Place::ty_from(place.base, proj_base, self.body(), self.infcx.tcx).ty; + Place::ty_from(place.local, proj_base, self.body(), self.infcx.tcx).ty; // Check the kind of deref to decide match base_ty.kind { @@ -2206,7 +2185,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, mode, ) } @@ -2219,7 +2198,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // `*mut` raw pointers are always mutable, regardless of // context. The users have to check by themselves. hir::Mutability::Mut => Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }), @@ -2227,7 +2206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // `Box` owns its content, so mutable if its location is mutable _ if base_ty.is_box() => self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, ), // Deref should only be for reference, pointers or boxes @@ -2283,11 +2262,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // } // ``` let _ = self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, )?; Ok(RootPlace { - place_base: place.base, + place_local: place.local, place_projection: place.projection, is_local_mutation_allowed, }) @@ -2295,7 +2274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { self.is_mutable( - PlaceRef { base: place.base, projection: proj_base }, + PlaceRef { local: place.local, projection: proj_base }, is_local_mutation_allowed, ) } @@ -2321,7 +2300,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match place_projection { [base @ .., ProjectionElem::Field(field, _ty)] => { let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(place_ref.base, base, self.body(), tcx).ty; + let base_ty = Place::ty_from(place_ref.local, base, self.body(), tcx).ty; if (base_ty.is_closure() || base_ty.is_generator()) && (!by_ref || self.upvars[field.index()].by_ref) diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 41bf1aa47d415..deec6f386ffb3 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict; use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; use rustc::mir::BorrowKind; -use rustc::mir::{BasicBlock, Body, Location, Place, PlaceBase}; +use rustc::mir::{BasicBlock, Body, Location, Place}; use rustc::ty::TyCtxt; use rustc_data_structures::graph::dominators::Dominators; @@ -131,9 +131,7 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield expressions on movable generators pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { - match place.base { - // Reborrow of already borrowed data is ignored - // Any errors will be caught on the initial borrow - PlaceBase::Local(_) => !place.is_indirect(), - } + // Reborrow of already borrowed data is ignored + // Any errors will be caught on the initial borrow + !place.is_indirect() } diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 445ba057c1b51..ac02da2661586 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -1,6 +1,6 @@ use crate::borrow_check::borrow_set::LocalsStateAtExit; use rustc::mir::ProjectionElem; -use rustc::mir::{Body, Mutability, Place, PlaceBase}; +use rustc::mir::{Body, Mutability, Place}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; @@ -25,40 +25,35 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { body: &Body<'tcx>, locals_state_at_exit: &LocalsStateAtExit, ) -> bool { - let local = match self.base { - // If a local variable is immutable, then we only need to track borrows to guard - // against two kinds of errors: - // * The variable being dropped while still borrowed (e.g., because the fn returns - // a reference to a local variable) - // * The variable being moved while still borrowed - // - // In particular, the variable cannot be mutated -- the "access checks" will fail -- - // so we don't have to worry about mutation while borrowed. - PlaceBase::Local(local) => match locals_state_at_exit { - LocalsStateAtExit::AllAreInvalidated => local, - LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => { - let ignore = !has_storage_dead_or_moved.contains(local) - && body.local_decls[local].mutability == Mutability::Not; - debug!("ignore_borrow: local {:?} => {:?}", local, ignore); - if ignore { - return true; - } else { - local - } - } - }, - }; + // If a local variable is immutable, then we only need to track borrows to guard + // against two kinds of errors: + // * The variable being dropped while still borrowed (e.g., because the fn returns + // a reference to a local variable) + // * The variable being moved while still borrowed + // + // In particular, the variable cannot be mutated -- the "access checks" will fail -- + // so we don't have to worry about mutation while borrowed. + if let LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } = + locals_state_at_exit + { + let ignore = !has_storage_dead_or_moved.contains(self.local) + && body.local_decls[self.local].mutability == Mutability::Not; + debug!("ignore_borrow: local {:?} => {:?}", self.local, ignore); + if ignore { + return true; + } + } for (i, elem) in self.projection.iter().enumerate() { let proj_base = &self.projection[..i]; if *elem == ProjectionElem::Deref { - let ty = Place::ty_from(&self.base, proj_base, body, tcx).ty; + let ty = Place::ty_from(&self.local, proj_base, body, tcx).ty; match ty.kind { ty::Ref(_, _, hir::Mutability::Not) if i == 0 => { // For references to thread-local statics, we do need // to track the borrow. - if body.local_decls[local].is_ref_to_thread_local() { + if body.local_decls[self.local].is_ref_to_thread_local() { continue; } return true; diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index a09779a766ffb..b95d1af11ad1d 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -1,7 +1,7 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; use crate::borrow_check::{AccessDepth, Deep, Shallow}; -use rustc::mir::{Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem}; +use rustc::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; use std::cmp::max; @@ -119,10 +119,10 @@ fn place_components_conflict<'tcx>( // and either equal or disjoint. // - If we did run out of access, the borrow can access a part of it. - let borrow_base = &borrow_place.base; - let access_base = access_place.base; + let borrow_local = &borrow_place.local; + let access_local = access_place.local; - match place_base_conflict(borrow_base, access_base) { + match place_base_conflict(borrow_local, access_local) { Overlap::Arbitrary => { bug!("Two base can't return Arbitrary"); } @@ -161,7 +161,7 @@ fn place_components_conflict<'tcx>( match place_projection_conflict( tcx, body, - borrow_base, + borrow_local, borrow_proj_base, borrow_c, access_c, @@ -208,7 +208,7 @@ fn place_components_conflict<'tcx>( // access cares about. let proj_base = &borrow_place.projection[..access_place.projection.len() + i]; - let base_ty = Place::ty_from(borrow_base, proj_base, body, tcx).ty; + let base_ty = Place::ty_from(borrow_local, proj_base, body, tcx).ty; match (elem, &base_ty.kind, access) { (_, _, Shallow(Some(ArtificialField::ArrayLength))) @@ -293,19 +293,15 @@ fn place_components_conflict<'tcx>( // Given that the bases of `elem1` and `elem2` are always either equal // or disjoint (and have the same type!), return the overlap situation // between `elem1` and `elem2`. -fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap { - match (elem1, elem2) { - (PlaceBase::Local(l1), PlaceBase::Local(l2)) => { - if l1 == l2 { - // the same local - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL"); - Overlap::EqualOrDisjoint - } else { - // different locals - base case, disjoint - debug!("place_element_conflict: DISJOINT-LOCAL"); - Overlap::Disjoint - } - } +fn place_base_conflict(l1: &Local, l2: &Local) -> Overlap { + if l1 == l2 { + // the same local - base case, equal + debug!("place_element_conflict: DISJOINT-OR-EQ-LOCAL"); + Overlap::EqualOrDisjoint + } else { + // different locals - base case, disjoint + debug!("place_element_conflict: DISJOINT-LOCAL"); + Overlap::Disjoint } } @@ -315,7 +311,7 @@ fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap { fn place_projection_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - pi1_base: &PlaceBase, + pi1_local: &Local, pi1_proj_base: &[PlaceElem<'tcx>], pi1_elem: &PlaceElem<'tcx>, pi2_elem: &PlaceElem<'tcx>, @@ -333,7 +329,7 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD"); Overlap::EqualOrDisjoint } else { - let ty = Place::ty_from(pi1_base, pi1_proj_base, body, tcx).ty; + let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty; match ty.kind { ty::Adt(def, _) if def.is_union() => { // Different fields of a union, we are basically stuck. diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index c41f2f45012e2..31bee460fa011 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -9,7 +9,7 @@ use super::MirBorrowckCtxt; -use rustc::mir::{Place, PlaceBase, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; +use rustc::mir::{Place, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; @@ -19,7 +19,7 @@ pub trait IsPrefixOf<'cx, 'tcx> { impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> { fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool { - self.base == other.base + self.local == other.local && self.projection.len() <= other.projection.len() && self.projection == &other.projection[..self.projection.len()] } @@ -69,22 +69,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { 'cursor: loop { match &cursor { - PlaceRef { base: PlaceBase::Local(_), projection: [] } => { + PlaceRef { local: _, projection: [] } => { self.next = None; return Some(cursor); } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Field(_ /*field*/, _ /*ty*/) => { // FIXME: add union handling - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => { - cursor = PlaceRef { base: cursor.base, projection: proj_base }; + cursor = PlaceRef { local: cursor.local, projection: proj_base }; continue 'cursor; } ProjectionElem::Deref => { @@ -105,7 +106,8 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { PrefixSet::All => { // All prefixes: just blindly enqueue the base // of the projection. - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } PrefixSet::Supporting => { @@ -118,7 +120,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { // derefs, except we stop at the deref of a shared // reference. - let ty = Place::ty_from(cursor.base, proj_base, *self.body, self.tcx).ty; + let ty = Place::ty_from(cursor.local, proj_base, *self.body, self.tcx).ty; match ty.kind { ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => { // don't continue traversing over derefs of raw pointers or shared @@ -128,12 +130,14 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { } ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => { - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } ty::Adt(..) if ty.is_box() => { - self.next = Some(PlaceRef { base: cursor.base, projection: proj_base }); + self.next = + Some(PlaceRef { local: cursor.local, projection: proj_base }); return Some(cursor); } diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 001f2fc3b2287..947bbef4379f5 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -465,9 +465,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { ) -> PlaceTy<'tcx> { debug!("sanitize_place: {:?}", place); - let mut place_ty = match &place.base { - PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), - }; + let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty); if place.projection.is_empty() { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { @@ -2389,7 +2387,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match elem { ProjectionElem::Deref => { let tcx = self.infcx.tcx; - let base_ty = Place::ty_from(&borrowed_place.base, proj_base, body, tcx).ty; + let base_ty = Place::ty_from(&borrowed_place.local, proj_base, body, tcx).ty; debug!("add_reborrow_constraint - base_ty = {:?}", base_ty); match base_ty.kind { diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index ea530042913e8..5e4eebb771f21 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -1,5 +1,5 @@ use rustc::mir::visit::{PlaceContext, Visitor}; -use rustc::mir::{Local, Location, Place, PlaceBase, Statement, StatementKind, TerminatorKind}; +use rustc::mir::{Local, Location, Place, Statement, StatementKind, TerminatorKind}; use rustc_data_structures::fx::FxHashSet; @@ -57,11 +57,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - match into.base { - PlaceBase::Local(local) => { - self.never_initialized_mut_locals.remove(&local); - } - } + self.never_initialized_mut_locals.remove(&into.local); } } @@ -82,13 +78,11 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) { match &statement.kind { StatementKind::Assign(box (into, _)) => { - match into.base { - PlaceBase::Local(local) => debug!( - "visit_statement: statement={:?} local={:?} \ - never_initialized_mut_locals={:?}", - statement, local, self.never_initialized_mut_locals - ), - } + debug!( + "visit_statement: statement={:?} local={:?} \ + never_initialized_mut_locals={:?}", + statement, into.local, self.never_initialized_mut_locals + ); self.remove_never_initialized_mut_locals(into); } _ => {} diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 661111ed9484c..eb2e87f4a2d41 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -20,13 +20,13 @@ use rustc_index::vec::Idx; /// and `c` can be progressively pushed onto the place builder that is created when converting `a`. #[derive(Clone)] struct PlaceBuilder<'tcx> { - base: PlaceBase, + local: Local, projection: Vec>, } impl PlaceBuilder<'tcx> { fn into_place(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - Place { base: self.base, projection: tcx.intern_place_elems(&self.projection) } + Place { local: self.local, projection: tcx.intern_place_elems(&self.projection) } } fn field(self, f: Field, ty: Ty<'tcx>) -> Self { @@ -49,13 +49,7 @@ impl PlaceBuilder<'tcx> { impl From for PlaceBuilder<'tcx> { fn from(local: Local) -> Self { - Self { base: local.into(), projection: Vec::new() } - } -} - -impl From for PlaceBuilder<'tcx> { - fn from(base: PlaceBase) -> Self { - Self { base, projection: Vec::new() } + Self { local, projection: Vec::new() } } } @@ -370,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let tcx = self.hir.tcx(); let place_ty = - Place::ty_from(&base_place.base, &base_place.projection, &self.local_decls, tcx); + Place::ty_from(&base_place.local, &base_place.projection, &self.local_decls, tcx); if let ty::Slice(_) = place_ty.ty.kind { // We need to create fake borrows to ensure that the bounds // check that we just did stays valid. Since we can't assign to @@ -380,7 +374,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match elem { ProjectionElem::Deref => { let fake_borrow_deref_ty = Place::ty_from( - &base_place.base, + &base_place.local, &base_place.projection[..idx], &self.local_decls, tcx, @@ -398,14 +392,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Shallow, - Place { base: base_place.base.clone(), projection }, + Place { local: base_place.local.clone(), projection }, ), ); fake_borrow_temps.push(fake_borrow_temp); } ProjectionElem::Index(_) => { let index_ty = Place::ty_from( - &base_place.base, + &base_place.local, &base_place.projection[..idx], &self.local_decls, tcx, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 34b0cbf3b25cd..6f7b7258b5a1a 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -393,26 +393,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arg_place = unpack!(block = this.as_place(block, arg)); let mutability = match arg_place.as_ref() { - PlaceRef { base: &PlaceBase::Local(local), projection: &[] } => { - this.local_decls[local].mutability - } - PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref] } => { + PlaceRef { local, projection: &[] } => this.local_decls[*local].mutability, + PlaceRef { local, projection: &[ProjectionElem::Deref] } => { debug_assert!( - this.local_decls[local].is_ref_for_guard(), + this.local_decls[*local].is_ref_for_guard(), "Unexpected capture place", ); - this.local_decls[local].mutability + this.local_decls[*local].mutability } PlaceRef { - ref base, + ref local, projection: &[ref proj_base @ .., ProjectionElem::Field(upvar_index, _)], } | PlaceRef { - ref base, + ref local, projection: &[ref proj_base @ .., ProjectionElem::Field(upvar_index, _), ProjectionElem::Deref], } => { - let place = PlaceRef { base, projection: proj_base }; + let place = PlaceRef { local, projection: proj_base }; // Not projected from the implicit `self` in a closure. debug_assert!( diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 7eea90befb008..1dcd29d923244 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -890,7 +890,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let proj_base = &source.projection[..i]; fake_borrows.insert(Place { - base: source.base.clone(), + local: source.local.clone(), projection: self.hir.tcx().intern_place_elems(proj_base), }); } @@ -1241,7 +1241,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Insert a shallow borrow after a deref. For other // projections the borrow of prefix_cursor will // conflict with any mutation of base. - all_fake_borrows.push(PlaceRef { base: &place.base, projection: proj_base }); + all_fake_borrows.push(PlaceRef { local: &place.local, projection: proj_base }); } } @@ -1258,7 +1258,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .into_iter() .map(|matched_place_ref| { let matched_place = Place { - base: matched_place_ref.base.clone(), + local: matched_place_ref.local.clone(), projection: tcx.intern_place_elems(matched_place_ref.projection), }; let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d6d22db9ff24b..d4813d8ab68ca 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -834,7 +834,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: tcx_hir.span(var_id), }, place: Place { - base: closure_env_arg.into(), + local: closure_env_arg.into(), projection: tcx.intern_place_elems(&projs), }, }); diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 65976908f597e..63834d0ecda00 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -86,10 +86,7 @@ struct BorrowedLocalsVisitor<'gk> { } fn find_local(place: &Place<'_>) -> Option { - match place.base { - PlaceBase::Local(local) if !place.is_indirect() => Some(local), - _ => None, - } + if !place.is_indirect() { Some(place.local) } else { None } } impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> { diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index d6ada9162272d..f94ee67f2bea7 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -1,4 +1,4 @@ -use rustc::mir::{self, Body, Location, Place, PlaceBase}; +use rustc::mir::{self, Body, Location, Place}; use rustc::ty::RegionVid; use rustc::ty::TyCtxt; @@ -195,38 +195,34 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { fn kill_borrows_on_place(&self, trans: &mut GenKillSet, place: &Place<'tcx>) { debug!("kill_borrows_on_place: place={:?}", place); - match place.base { - PlaceBase::Local(local) => { - let other_borrows_of_local = - self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); - - // If the borrowed place is a local with no projections, all other borrows of this - // local must conflict. This is purely an optimization so we don't have to call - // `places_conflict` for every borrow. - if place.projection.is_empty() { - if !self.body.local_decls[local].is_ref_to_static() { - trans.kill_all(other_borrows_of_local); - } - return; - } - - // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given - // pair of array indices are unequal, so that when `places_conflict` returns true, we - // will be assured that two places being compared definitely denotes the same sets of - // locations. - let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { - places_conflict( - self.tcx, - self.body, - &self.borrow_set.borrows[i].borrowed_place, - place, - PlaceConflictBias::NoOverlap, - ) - }); + let other_borrows_of_local = + self.borrow_set.local_map.get(&place.local).into_iter().flat_map(|bs| bs.into_iter()); - trans.kill_all(definitely_conflicting_borrows); + // If the borrowed place is a local with no projections, all other borrows of this + // local must conflict. This is purely an optimization so we don't have to call + // `places_conflict` for every borrow. + if place.projection.is_empty() { + if !self.body.local_decls[place.local].is_ref_to_static() { + trans.kill_all(other_borrows_of_local); } + return; } + + // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given + // pair of array indices are unequal, so that when `places_conflict` returns true, we + // will be assured that two places being compared definitely denotes the same sets of + // locations. + let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { + places_conflict( + self.tcx, + self.body, + &self.borrow_set.borrows[i].borrowed_place, + place, + PlaceConflictBias::NoOverlap, + ) + }); + + trans.kill_all(definitely_conflicting_borrows); } } diff --git a/src/librustc_mir/dataflow/impls/indirect_mutation.rs b/src/librustc_mir/dataflow/impls/indirect_mutation.rs index 38401b42b48a8..85bf342c8a39a 100644 --- a/src/librustc_mir/dataflow/impls/indirect_mutation.rs +++ b/src/librustc_mir/dataflow/impls/indirect_mutation.rs @@ -111,12 +111,8 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { if let mir::Rvalue::Ref(_, kind, ref borrowed_place) = *rvalue { if self.borrow_allows_mutation(kind, borrowed_place) { - match borrowed_place.base { - mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect() => { - self.trans.gen(borrowed_local) - } - - _ => (), + if !borrowed_place.is_indirect() { + self.trans.gen(borrowed_place.local); } } } diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index e4d5d6adfc17c..6a48d1e98032c 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -115,14 +115,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { match stmt.kind { StatementKind::StorageDead(l) => sets.kill(l), StatementKind::Assign(box (ref place, _)) - | StatementKind::SetDiscriminant { box ref place, .. } => match place.base { - PlaceBase::Local(local) => sets.gen(local), - }, + | StatementKind::SetDiscriminant { box ref place, .. } => { + sets.gen(place.local); + } StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { - for p in &**outputs { - match p.base { - PlaceBase::Local(local) => sets.gen(local), - } + for place in &**outputs { + sets.gen(place.local); } } _ => (), @@ -138,10 +136,8 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { fn before_terminator_effect(&self, sets: &mut GenKillSet, loc: Location) { self.check_for_borrow(sets, loc); - if let TerminatorKind::Call { - destination: Some((Place { base: PlaceBase::Local(local), .. }, _)), - .. - } = self.body[loc.block].terminator().kind + if let TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } = + self.body[loc.block].terminator().kind { sets.gen(local); } @@ -169,11 +165,7 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { _dest_bb: mir::BasicBlock, dest_place: &mir::Place<'tcx>, ) { - match dest_place.base { - PlaceBase::Local(local) => { - in_out.insert(local); - } - } + in_out.insert(dest_place.local); } } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index b0be49689f953..271bcce6ca53c 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -96,9 +96,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { /// Maybe we should have separate "borrowck" and "moveck" modes. fn move_path_for(&mut self, place: &Place<'tcx>) -> Result> { debug!("lookup({:?})", place); - let mut base = match place.base { - PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local], - }; + let mut base = self.builder.data.rev_lookup.locals[place.local]; // The move path index of the first union that we find. Once this is // some we stop creating child move paths, since moves from unions @@ -111,7 +109,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let proj_base = &place.projection[..i]; let body = self.builder.body; let tcx = self.builder.tcx; - let place_ty = Place::ty_from(&place.base, proj_base, body, tcx).ty; + let place_ty = Place::ty_from(&place.local, proj_base, body, tcx).ty; match place_ty.kind { ty::Ref(..) | ty::RawPtr(..) => { let proj = &place.projection[..i + 1]; @@ -119,7 +117,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.loc, BorrowedContent { target_place: Place { - base: place.base.clone(), + local: place.local, projection: tcx.intern_place_elems(proj), }, }, @@ -160,7 +158,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { if union_path.is_none() { base = self.add_move_path(base, elem, |tcx| Place { - base: place.base.clone(), + local: place.local.clone(), projection: tcx.intern_place_elems(&place.projection[..i + 1]), }); } @@ -433,7 +431,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // `ConstIndex` patterns. This is done to ensure that all move paths // are disjoint, which is expected by drop elaboration. let base_place = Place { - base: place.base.clone(), + local: place.local.clone(), projection: self.builder.tcx.intern_place_elems(base), }; let base_path = match self.move_path_for(&base_place) { @@ -494,10 +492,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // of the union so it is marked as initialized again. if let [proj_base @ .., ProjectionElem::Field(_, _)] = place.projection { if let ty::Adt(def, _) = - Place::ty_from(place.base, proj_base, self.builder.body, self.builder.tcx).ty.kind + Place::ty_from(place.local, proj_base, self.builder.body, self.builder.tcx).ty.kind { if def.is_union() { - place = PlaceRef { base: place.base, projection: proj_base } + place = PlaceRef { local: place.local, projection: proj_base } } } } diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7133c46d6c70f..a46465ab49376 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -246,9 +246,7 @@ impl MovePathLookup { // unknown place, but will rather return the nearest available // parent. pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult { - let mut result = match place.base { - PlaceBase::Local(local) => self.locals[*local], - }; + let mut result = self.locals[*place.local]; for elem in place.projection.iter() { if let Some(&subpath) = self.projections.get(&(result, elem.lift())) { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 30725d781dc7f..6df3e6fc5962e 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -462,17 +462,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { place: &mir::Place<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - use rustc::mir::PlaceBase; - - let base_op = match &place.base { - PlaceBase::Local(mir::RETURN_PLACE) => throw_unsup!(ReadFromReturnPointer), - PlaceBase::Local(local) => { + let base_op = match place.local { + mir::RETURN_PLACE => throw_unsup!(ReadFromReturnPointer), + local => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. // FIXME use place_projection.is_empty() when is available let layout = if place.projection.is_empty() { layout } else { None }; - self.access_local(self.frame(), *local, layout)? + self.access_local(self.frame(), local, layout)? } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index bd3059951e86b..8888e3fd4632a 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,10 +624,8 @@ where &mut self, place: &mir::Place<'tcx>, ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> { - use rustc::mir::PlaceBase; - - let mut place_ty = match &place.base { - PlaceBase::Local(mir::RETURN_PLACE) => { + let mut place_ty = match place.local { + mir::RETURN_PLACE => { // `return_place` has the *caller* layout, but we want to use our // `layout to verify our assumption. The caller will validate // their layout on return. @@ -648,10 +646,10 @@ where ))?, } } - PlaceBase::Local(local) => PlaceTy { + local => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing - place: Place::Local { frame: self.cur_frame(), local: *local }, - layout: self.layout_of_local(self.frame(), *local, None)?, + place: Place::Local { frame: self.cur_frame(), local: local }, + layout: self.layout_of_local(self.frame(), local, None)?, }, }; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 5da5695a4d4eb..5ccdb4be62461 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,7 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::mir::visit::Visitor as MirVisitor; -use rustc::mir::{self, Location, PlaceBase}; +use rustc::mir::{self, Local, Location}; use rustc::session::config::EntryFnType; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::print::obsolete::DefPathBasedNames; @@ -642,15 +642,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn visit_place_base( &mut self, - place_base: &mir::PlaceBase, + _place_local: &Local, _context: mir::visit::PlaceContext, _location: Location, ) { - match place_base { - PlaceBase::Local(_) => { - // Locals have no relevance for collector. - } - } } } diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 8c52a4e7a29dd..577736f9bd11d 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -38,12 +38,15 @@ pub trait Qualif { place: PlaceRef<'_, 'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { - let base_qualif = - Self::in_place(cx, per_local, PlaceRef { base: place.base, projection: proj_base }); + let base_qualif = Self::in_place( + cx, + per_local, + PlaceRef { local: place.local, projection: proj_base }, + ); let qualif = base_qualif && Self::in_any_value_of_ty( cx, - Place::ty_from(place.base, proj_base, *cx.body, cx.tcx) + Place::ty_from(place.local, proj_base, *cx.body, cx.tcx) .projection_ty(cx.tcx, elem) .ty, ); @@ -75,8 +78,8 @@ pub trait Qualif { place: PlaceRef<'_, 'tcx>, ) -> bool { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local), - PlaceRef { base: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), + PlaceRef { local, projection: [] } => per_local(*local), + PlaceRef { local: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), } } @@ -146,12 +149,12 @@ pub trait Qualif { Rvalue::Ref(_, _, ref place) | Rvalue::AddressOf(_, ref place) => { // Special-case reborrows to be more like a copy of the reference. if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { - let base_ty = Place::ty_from(&place.base, proj_base, *cx.body, cx.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *cx.body, cx.tcx).ty; if let ty::Ref(..) = base_ty.kind { return Self::in_place( cx, per_local, - PlaceRef { base: &place.base, projection: proj_base }, + PlaceRef { local: &place.local, projection: proj_base }, ); } } diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index 207683054f925..c445568dd2a9b 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -47,15 +47,15 @@ where debug_assert!(!place.is_indirect()); match (value, place.as_ref()) { - (true, mir::PlaceRef { base: &mir::PlaceBase::Local(local), .. }) => { - self.qualifs_per_local.insert(local); + (true, mir::PlaceRef { local, .. }) => { + self.qualifs_per_local.insert(*local); } // For now, we do not clear the qualif if a local is overwritten in full by // an unqualified rvalue (e.g. `y = 5`). This is to be consistent // with aggregates where we overwrite all fields with assignments, which would not // get this feature. - (false, mir::PlaceRef { base: &mir::PlaceBase::Local(_local), projection: &[] }) => { + (false, mir::PlaceRef { local: _, projection: &[] }) => { // self.qualifs_per_local.remove(*local); } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index c864abdae66a5..10a4b7d92b764 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -304,8 +304,8 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { PlaceContext::MutatingUse(MutatingUseContext::Borrow) } }; - self.visit_place_base(&place.base, ctx, location); - self.visit_projection(&place.base, reborrowed_proj, ctx, location); + self.visit_place_base(&place.local, ctx, location); + self.visit_projection(&place.local, reborrowed_proj, ctx, location); return; } } @@ -317,8 +317,8 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf), }; - self.visit_place_base(&place.base, ctx, location); - self.visit_projection(&place.base, reborrowed_proj, ctx, location); + self.visit_place_base(&place.local, ctx, location); + self.visit_projection(&place.local, reborrowed_proj, ctx, location); return; } } @@ -412,23 +412,14 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - fn visit_place_base( - &mut self, - place_base: &PlaceBase, - context: PlaceContext, - location: Location, - ) { + fn visit_place_base(&mut self, place_local: &Local, context: PlaceContext, location: Location) { trace!( - "visit_place_base: place_base={:?} context={:?} location={:?}", - place_base, + "visit_place_base: place_local={:?} context={:?} location={:?}", + place_local, context, location, ); - self.super_place_base(place_base, context, location); - - match place_base { - PlaceBase::Local(_) => {} - } + self.super_place_base(place_local, context, location); } fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { @@ -441,30 +432,30 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } fn visit_projection_elem( &mut self, - place_base: &PlaceBase, + place_local: &Local, proj_base: &[PlaceElem<'tcx>], elem: &PlaceElem<'tcx>, context: PlaceContext, location: Location, ) { trace!( - "visit_projection_elem: place_base={:?} proj_base={:?} elem={:?} \ + "visit_projection_elem: place_local={:?} proj_base={:?} elem={:?} \ context={:?} location={:?}", - place_base, + place_local, proj_base, elem, context, location, ); - self.super_projection_elem(place_base, proj_base, elem, context, location); + self.super_projection_elem(place_local, proj_base, elem, context, location); match elem { ProjectionElem::Deref => { - let base_ty = Place::ty_from(place_base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_local, proj_base, *self.body, self.tcx).ty; if let ty::RawPtr(_) = base_ty.kind { if proj_base.is_empty() { - if let (PlaceBase::Local(local), []) = (place_base, proj_base) { + if let (local, []) = (place_local, proj_base) { let decl = &self.body.local_decls[*local]; if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { let span = decl.source_info.span; @@ -485,7 +476,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { | ProjectionElem::Subslice { .. } | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { - let base_ty = Place::ty_from(place_base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_local, proj_base, *self.body, self.tcx).ty; match base_ty.ty_adt_def() { Some(def) if def.is_union() => { self.check_op(ops::UnionAccess); @@ -669,19 +660,15 @@ fn place_as_reborrow( // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` // that points to the allocation for the static. Don't treat these as reborrows. - match place.base { - PlaceBase::Local(local) => { - if body.local_decls[local].is_ref_to_static() { - return None; - } - } + if body.local_decls[place.local].is_ref_to_static() { + return None; } // Ensure the type being derefed is a reference and not a raw pointer. // // This is sufficient to prevent an access to a `static mut` from being marked as a // reborrow, even if the check above were to disappear. - let inner_ty = Place::ty_from(&place.base, inner, body, tcx).ty; + let inner_ty = Place::ty_from(&place.local, inner, body, tcx).ty; match inner_ty.kind { ty::Ref(..) => Some(inner), _ => None, diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 017d0f3467410..934b262c2f9cb 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -190,12 +190,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - match place.base { - PlaceBase::Local(..) => { - // Locals are safe. - } - } - for (i, elem) in place.projection.iter().enumerate() { let proj_base = &place.projection[..i]; @@ -223,7 +217,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } } let is_borrow_of_interior_mut = context.is_borrow() - && !Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty.is_freeze( + && !Place::ty_from(&place.local, proj_base, self.body, self.tcx).ty.is_freeze( self.tcx, self.param_env, self.source_info.span, @@ -238,7 +232,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use()); } let old_source_info = self.source_info; - if let (PlaceBase::Local(local), []) = (&place.base, proj_base) { + if let (local, []) = (&place.local, proj_base) { let decl = &self.body.local_decls[*local]; if decl.internal { // Internal locals are used in the `move_val_init` desugaring. @@ -266,7 +260,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } } } - let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, self.body, self.tcx).ty; match base_ty.kind { ty::RawPtr(..) => self.require_unsafe( "dereference of raw pointer", @@ -420,7 +414,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { match elem { ProjectionElem::Field(..) => { let ty = - Place::ty_from(&place.base, proj_base, &self.body.local_decls, self.tcx).ty; + Place::ty_from(&place.local, proj_base, &self.body.local_decls, self.tcx) + .ty; match ty.kind { ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) { (Bound::Unbounded, Bound::Unbounded) => {} diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index f9b24b00e8719..79506f3f22a67 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -10,7 +10,7 @@ use rustc::mir::visit::{ }; use rustc::mir::{ read_only, AggregateKind, BasicBlock, BinOp, Body, BodyAndCache, ClearCrossCrate, Constant, - Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, ReadOnlyBodyAndCache, Rvalue, + Local, LocalDecl, LocalKind, Location, Operand, Place, ReadOnlyBodyAndCache, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; @@ -872,9 +872,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // doesn't use the invalid value match cond { Operand::Move(ref place) | Operand::Copy(ref place) => { - match place.base { - PlaceBase::Local(local) => self.remove_const(local), - } + self.remove_const(place.local); } Operand::Constant(_) => {} } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index b075a39951613..825ac4a28d869 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -112,17 +112,17 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base == PlaceBase::Local(self_arg()) { + if place.local == self_arg() { replace_base( place, Place { - base: PlaceBase::Local(self_arg()), + local: self_arg(), projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), }, self.tcx, ); } else { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { @@ -148,11 +148,11 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base == PlaceBase::Local(self_arg()) { + if place.local == self_arg() { replace_base( place, Place { - base: PlaceBase::Local(self_arg()), + local: self_arg(), projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field( Field::new(0), self.ref_gen_ty, @@ -161,7 +161,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { self.tcx, ); } else { - self.visit_place_base(&mut place.base, context, location); + self.visit_place_base(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { @@ -173,7 +173,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { } fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtxt<'tcx>) { - place.base = new_base.base; + place.local = new_base.local; let mut new_projection = new_base.projection.to_vec(); new_projection.append(&mut place.projection.to_vec()); @@ -236,7 +236,7 @@ impl TransformVisitor<'tcx> { let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); - Place { base: base.base, projection: self.tcx.intern_place_elems(&projection) } + Place { local: base.local, projection: self.tcx.intern_place_elems(&projection) } } // Create a statement which changes the discriminant @@ -281,14 +281,9 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { _context: PlaceContext, _location: Location, ) { - match place.base { - PlaceBase::Local(l) => - // Replace an Local in the remap with a generator struct access - { - if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { - replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); - } - } + // Replace an Local in the remap with a generator struct access + if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) { + replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 52992f7d7a8cc..2dd00fe2fee19 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -430,9 +430,7 @@ impl Inliner<'tcx> { } } - match place.base { - _ => false, - } + false } let dest = if dest_needs_borrow(&destination.0) { @@ -644,9 +642,7 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { fn make_integrate_local(&self, local: &Local) -> Local { if *local == RETURN_PLACE { - match self.destination.base { - PlaceBase::Local(l) => return l, - } + return self.destination.local; } let idx = local.index() - 1; @@ -668,18 +664,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { } fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - match &mut place.base { - PlaceBase::Local(l) => { - // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. - let dest_proj_len = self.destination.projection.len(); - if *l == RETURN_PLACE && dest_proj_len > 0 { - let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len()); - projs.extend(self.destination.projection); - projs.extend(place.projection); - - place.projection = self.tcx.intern_place_elems(&*projs); - } - } + // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. + let dest_proj_len = self.destination.projection.len(); + if place.local == RETURN_PLACE && dest_proj_len > 0 { + let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len()); + projs.extend(self.destination.projection); + projs.extend(place.projection); + + place.projection = self.tcx.intern_place_elems(&*projs); } // Handles integrating any locals that occur in the base // or projections diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index a2f3fcea7569a..69eedb1ae1876 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -3,7 +3,7 @@ use crate::transform::{MirPass, MirSource}; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::mir::{ - read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceBase, PlaceRef, + read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, }; use rustc::ty::{self, TyCtxt}; @@ -55,7 +55,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { Place { // Replace with dummy - base: mem::replace(&mut place.base, PlaceBase::Local(Local::new(0))), + local: mem::replace(&mut place.local, Local::new(0)), projection: self.tcx().intern_place_elems(proj_l), } } else { @@ -92,10 +92,10 @@ impl OptimizationFinder<'b, 'tcx> { impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Ref(_, _, place) = rvalue { - if let PlaceRef { base, projection: &[ref proj_base @ .., ProjectionElem::Deref] } = + if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } = place.as_ref() { - if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() { + if Place::ty_from(local, proj_base, self.body, self.tcx).ty.is_region_ptr() { self.optimizations.and_stars.insert(location); } } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 494b61c5d1ee7..90393ec6c8c80 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -308,17 +308,14 @@ impl<'tcx> Validator<'_, 'tcx> { // We can only promote interior borrows of promotable temps (non-temps // don't get promoted anyway). - let base = match place.base { - PlaceBase::Local(local) => local, - }; - self.validate_local(base)?; + self.validate_local(place.local)?; if place.projection.contains(&ProjectionElem::Deref) { return Err(Unpromotable); } let mut has_mut_interior = - self.qualif_local::(base); + self.qualif_local::(place.local); // HACK(eddyb) this should compute the same thing as // `::in_projection` from // `check_consts::qualifs` but without recursion. @@ -332,7 +329,7 @@ impl<'tcx> Validator<'_, 'tcx> { // FIXME(eddyb) this is probably excessive, with // the exception of `union` member accesses. let ty = - Place::ty_from(&place.base, proj_base, *self.body, self.tcx) + Place::ty_from(&place.local, proj_base, *self.body, self.tcx) .projection_ty(self.tcx, elem) .ty; if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { @@ -348,7 +345,7 @@ impl<'tcx> Validator<'_, 'tcx> { if has_mut_interior { return Err(Unpromotable); } - if self.qualif_local::(base) { + if self.qualif_local::(place.local) { return Err(Unpromotable); } @@ -478,10 +475,8 @@ impl<'tcx> Validator<'_, 'tcx> { fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> { match place { - PlaceRef { base: PlaceBase::Local(local), projection: [] } => { - self.validate_local(*local) - } - PlaceRef { base: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local, projection: [] } => self.validate_local(*local), + PlaceRef { local: _, projection: [proj_base @ .., elem] } => { match *elem { ProjectionElem::Deref | ProjectionElem::Downcast(..) => { return Err(Unpromotable); @@ -496,7 +491,7 @@ impl<'tcx> Validator<'_, 'tcx> { ProjectionElem::Field(..) => { if self.const_kind.is_none() { let base_ty = - Place::ty_from(place.base, proj_base, *self.body, self.tcx).ty; + Place::ty_from(place.local, proj_base, *self.body, self.tcx).ty; if let Some(def) = base_ty.ty_adt_def() { // No promotion of union field accesses. if def.is_union() { @@ -507,7 +502,7 @@ impl<'tcx> Validator<'_, 'tcx> { } } - self.validate_place(PlaceRef { base: place.base, projection: proj_base }) + self.validate_place(PlaceRef { local: place.local, projection: proj_base }) } } } @@ -594,10 +589,12 @@ impl<'tcx> Validator<'_, 'tcx> { // Raw reborrows can come from reference to pointer coercions, // so are allowed. if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - return self - .validate_place(PlaceRef { base: &place.base, projection: proj_base }); + return self.validate_place(PlaceRef { + local: &place.local, + projection: proj_base, + }); } } Err(Unpromotable) @@ -631,9 +628,9 @@ impl<'tcx> Validator<'_, 'tcx> { // Special-case reborrows to be more like a copy of the reference. let mut place = place.as_ref(); if let [proj_base @ .., ProjectionElem::Deref] = &place.projection { - let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.local, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - place = PlaceRef { base: &place.base, projection: proj_base }; + place = PlaceRef { local: &place.local, projection: proj_base }; } } @@ -642,16 +639,15 @@ impl<'tcx> Validator<'_, 'tcx> { // HACK(eddyb) this should compute the same thing as // `::in_projection` from // `check_consts::qualifs` but without recursion. - let mut has_mut_interior = match place.base { - PlaceBase::Local(local) => self.qualif_local::(*local), - }; + let mut has_mut_interior = + self.qualif_local::(*place.local); if has_mut_interior { let mut place_projection = place.projection; // FIXME(eddyb) use a forward loop instead of a reverse one. while let [proj_base @ .., elem] = place_projection { // FIXME(eddyb) this is probably excessive, with // the exception of `union` member accesses. - let ty = Place::ty_from(place.base, proj_base, *self.body, self.tcx) + let ty = Place::ty_from(place.local, proj_base, *self.body, self.tcx) .projection_ty(self.tcx, elem) .ty; if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { @@ -930,7 +926,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { Rvalue::Ref(ref mut region, borrow_kind, ref mut place), )) => { // Use the underlying local for this (necessarily interior) borrow. - let ty = place.base.ty(local_decls).ty; + let ty = local_decls.local_decls()[place.local].ty; let span = statement.source_info.span; let ref_ty = tcx.mk_ref( @@ -965,10 +961,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { tcx.lifetimes.re_static, borrow_kind, Place { - base: mem::replace( - &mut place.base, - PlaceBase::Local(promoted_ref), - ), + local: mem::replace(&mut place.local, promoted_ref), projection: List::empty(), }, ) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index fcdabb29cd0e2..ab96ae3b6d6ee 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -261,7 +261,7 @@ fn check_place( ProjectionElem::Downcast(_symbol, _variant_index) => {} ProjectionElem::Field(..) => { - let base_ty = Place::ty_from(&place.base, &proj_base, body, tcx).ty; + let base_ty = Place::ty_from(&place.local, &proj_base, body, tcx).ty; if let Some(def) = base_ty.ty_adt_def() { // No union field accesses in `const fn` if def.is_union() { diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index e96baefc8229b..ddf8d73e5481f 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -388,9 +388,7 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { // Remove unnecessary StorageLive and StorageDead annotations. data.statements.retain(|stmt| match &stmt.kind { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), - StatementKind::Assign(box (place, _)) => match place.base { - PlaceBase::Local(local) => self.map[local].is_some(), - }, + StatementKind::Assign(box (place, _)) => self.map[place.local].is_some(), _ => true, }); self.super_basic_block_data(block, data); diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs index 3b8871f86b289..e733b0a5b5928 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/src/librustc_mir/transform/simplify_try.rs @@ -137,9 +137,9 @@ struct VarField<'tcx> { fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> { match place.as_ref() { PlaceRef { - base: &PlaceBase::Local(local), + local, projection: &[ProjectionElem::Downcast(_, var_idx), ProjectionElem::Field(field, ty)], - } => Some((local, VarField { field, field_ty: ty, var_idx })), + } => Some((*local, VarField { field, field_ty: ty, var_idx })), _ => None, } } diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 70d6aaf70eb09..e17c7a80f1a76 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -46,7 +46,7 @@ where // encountered a Deref, which is ABI-aligned ProjectionElem::Deref => break, ProjectionElem::Field(..) => { - let ty = Place::ty_from(&place.base, proj_base, local_decls, tcx).ty; + let ty = Place::ty_from(&place.local, proj_base, local_decls, tcx).ty; match ty.kind { ty::Adt(def, _) if def.repr.packed() => return true, _ => {} From a9de4f11edca51c48ca2fc835f437cecc1a9d497 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Dec 2019 16:23:23 -0300 Subject: [PATCH 0155/1253] Fix print const on librustdoc --- src/librustdoc/clean/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 089b4bd8445ff..8058536d60b31 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -467,7 +467,7 @@ pub fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String { inline::print_inlined_const(cx, def_id) }; if let Some(promoted) = promoted { - s.push_str(&format!("{:?}", promoted)) + s.push_str(&format!("::{:?}", promoted)) } s } From 7f3459a3b3c087f7746d420dbb6f2d1f136b3601 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Dec 2019 16:23:38 -0300 Subject: [PATCH 0156/1253] No need to use local.into here --- src/librustc/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 32d85314c7ab7..84fe077513e4d 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1793,7 +1793,7 @@ impl<'tcx> Place<'tcx> { impl From for Place<'_> { fn from(local: Local) -> Self { - Place { local: local.into(), projection: List::empty() } + Place { local, projection: List::empty() } } } From a5715a32b5a15180d6d7b8fe099151bd0713af07 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 19 Dec 2019 14:09:04 -0300 Subject: [PATCH 0157/1253] Use re_erased instead of re_static --- src/librustc_mir/transform/promote_consts.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 90393ec6c8c80..f058ac834ef34 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -930,11 +930,11 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let span = statement.source_info.span; let ref_ty = tcx.mk_ref( - tcx.lifetimes.re_static, + tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() }, ); - *region = tcx.lifetimes.re_static; + *region = tcx.lifetimes.re_erased; let mut projection = vec![PlaceElem::Deref]; projection.extend(place.projection); @@ -958,7 +958,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.extra_statements.push((loc, promoted_ref_statement)); Rvalue::Ref( - tcx.lifetimes.re_static, + tcx.lifetimes.re_erased, borrow_kind, Place { local: mem::replace(&mut place.local, promoted_ref), From 8533caa26f18d60ab6728d1ba97a8dc0ce8ba1ac Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 19 Dec 2019 14:10:48 -0300 Subject: [PATCH 0158/1253] Make Place Copy --- src/librustc/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 84fe077513e4d..281cf46bdc2dc 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1653,7 +1653,7 @@ impl Debug for Statement<'_> { /// A path to a value; something that can be evaluated without /// changing or disturbing program state. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] pub struct Place<'tcx> { pub local: Local, From 156561267ea9625d9d8344cf0a7755aff96431a4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 19 Dec 2019 14:14:36 -0300 Subject: [PATCH 0159/1253] Add span_bug that notes that shuffle indices must be constant --- src/librustc_codegen_ssa/mir/block.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index fa79541701e41..9169010da8801 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -618,6 +618,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { c, ); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) }; + } else { + span_bug!(span, "shuffle indices must be constant"); } } From 36b17567117a881f94b83ae6c80b6808a208e026 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 1 Jan 2020 12:35:50 -0300 Subject: [PATCH 0160/1253] Do not store lint_root --- src/librustc_mir/transform/const_prop.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 79506f3f22a67..b3ef639109735 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -264,7 +264,6 @@ struct ConstPropagator<'mir, 'tcx> { // Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store // the last known `SourceInfo` here and just keep revisiting it. source_info: Option, - lint_root: Option, } impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> { @@ -344,7 +343,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { local_decls: body.local_decls.clone(), ret: ret.map(Into::into), source_info: None, - lint_root: None, } } @@ -378,6 +376,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { self.ecx.tcx.span = source_info.span; + // FIXME(eddyb) move this to the `Panic(_)` error case, so that + // `f(self)` is always called, and that the only difference when the + // scope's `local_data` is missing, is that the lint isn't emitted. + let lint_root = self.lint_root(source_info)?; let r = match f(self) { Ok(val) => Some(val), Err(error) => { @@ -411,7 +413,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { diagnostic.report_as_lint( self.ecx.tcx, "this expression will panic at runtime", - self.lint_root?, + lint_root, None, ); } @@ -423,7 +425,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { r } - fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option> { + fn eval_constant( + &mut self, + c: &Constant<'tcx>, + source_info: SourceInfo, + ) -> Option> { self.ecx.tcx.span = c.span; // FIXME we need to revisit this for #67176 @@ -435,7 +441,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ok(op) => Some(op), Err(error) => { let err = error_to_const_error(&self.ecx, error); - match self.lint_root { + match self.lint_root(source_info) { Some(lint_root) if c.literal.needs_subst() => { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. @@ -462,7 +468,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { - Operand::Constant(ref c) => self.eval_constant(c), + Operand::Constant(ref c) => self.eval_constant(c, source_info), Operand::Move(ref place) | Operand::Copy(ref place) => { self.eval_place(place, source_info) } @@ -801,14 +807,13 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { trace!("visit_constant: {:?}", constant); self.super_constant(constant, location); - self.eval_constant(constant); + self.eval_constant(constant, self.source_info.unwrap()); } fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { trace!("visit_statement: {:?}", statement); let source_info = statement.source_info; self.source_info = Some(source_info); - self.lint_root = self.lint_root(source_info); if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind { let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty; if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { @@ -860,7 +865,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { let source_info = terminator.source_info; self.source_info = Some(source_info); self.super_terminator(terminator, location); - self.lint_root = self.lint_root(source_info); match &mut terminator.kind { TerminatorKind::Assert { expected, ref msg, ref mut cond, .. } => { if let Some(value) = self.eval_operand(&cond, source_info) { From 6e1bbff2c6816236bc3fe0a396c35c405b58fe23 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 8 Jan 2020 20:50:59 +0100 Subject: [PATCH 0161/1253] Promoteds also need param envs. This also allows us to use the `const_eval` query again without causing cycles --- src/librustc/mir/interpret/queries.rs | 4 ++-- src/librustc_mir/interpret/eval_context.rs | 19 ++++++++++++++----- src/librustc_mir/interpret/operand.rs | 9 +-------- .../ui/consts/const-eval/ub-nonnull.stderr | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs index 2b094bf911f88..ed57f81e78216 100644 --- a/src/librustc/mir/interpret/queries.rs +++ b/src/librustc/mir/interpret/queries.rs @@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> { let instance = ty::Instance::resolve(self, param_env, def_id, substs); if let Some(instance) = instance { if let Some(promoted) = promoted { - self.const_eval_promoted(instance, promoted) + self.const_eval_promoted(param_env, instance, promoted) } else { self.const_eval_instance(param_env, instance, span) } @@ -68,11 +68,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Evaluate a promoted constant. pub fn const_eval_promoted( self, + param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, promoted: mir::Promoted, ) -> ConstEvalResult<'tcx> { let cid = GlobalId { instance, promoted: Some(promoted) }; - let param_env = ty::ParamEnv::reveal_all(); self.const_eval_validated(param_env.and(cid)) } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 864f4f9487c88..206d3d156735e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -757,13 +757,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, gid: GlobalId<'tcx>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let val = if self.tcx.is_static(gid.instance.def_id()) { - self.tcx.const_eval_poly(gid.instance.def_id())? - } else if let Some(promoted) = gid.promoted { - self.tcx.const_eval_promoted(gid.instance, promoted)? + // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics + // and thus don't care about the parameter environment. While we could just use + // `self.param_env`, that would mean we invoke the query to evaluate the static + // with different parameter environments, thus causing the static to be evaluated + // multiple times. + let param_env = if self.tcx.is_static(gid.instance.def_id()) { + ty::ParamEnv::reveal_all() } else { - self.tcx.const_eval_instance(self.param_env, gid.instance, Some(self.tcx.span))? + self.param_env }; + let val = if let Some(promoted) = gid.promoted { + self.tcx.const_eval_promoted(param_env, gid.instance, promoted)? + } else { + self.tcx.const_eval_instance(param_env, gid.instance, Some(self.tcx.span))? + }; + // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not // return `ConstValue::Unevaluated`, which is the only way that `eval_const_to_op` will call diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 6df3e6fc5962e..2cb574bc681b1 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -537,14 +537,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // potentially requiring the current static to be evaluated again. This is not a // problem here, because we are building an operand which means an actual read is // happening. - // FIXME(oli-obk): eliminate all the `const_eval_raw` usages when we get rid of - // `StaticKind` once and for all. - // FIXME the following line should have been: - // return self.const_eval(GlobalId { instance, promoted }); - // but since the addition of Promoteds being Constants is causing const validation - // cycles. Promoteds being Constants exercise const validation more often and it - // may have made show up a pre-existing bug. - return Ok(OpTy::from(self.const_eval_raw(GlobalId { instance, promoted })?)); + return Ok(OpTy::from(self.const_eval(GlobalId { instance, promoted })?)); } ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index c2446d1404019..ea9fffa883ea5 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! LL | | let out_of_bounds_ptr = &ptr[255]; - | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1 + | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 9 which has size 1 LL | | mem::transmute(out_of_bounds_ptr) LL | | } }; | |____- From ecd5852194f43511443f134aebf0462b58c8e197 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 8 Jan 2020 21:31:08 +0100 Subject: [PATCH 0162/1253] Errors in promoteds may only cause lints not hard errors --- src/librustc_codegen_ssa/mir/constant.rs | 15 +++-- src/librustc_mir/transform/const_prop.rs | 18 ++++-- .../promoted_div_by_zero.rs | 2 +- src/test/ui/consts/array-literal-index-oob.rs | 12 ++-- .../ui/consts/array-literal-index-oob.stderr | 37 ++++++------ .../const-eval/conditional_array_execution.rs | 2 +- .../conditional_array_execution.stderr | 4 +- .../consts/const-eval/const_fn_ptr_fail2.rs | 6 +- .../const-eval/const_fn_ptr_fail2.stderr | 24 ++------ src/test/ui/consts/const-eval/issue-43197.rs | 8 +-- .../ui/consts/const-eval/issue-43197.stderr | 14 ++--- src/test/ui/consts/const-eval/issue-44578.rs | 3 +- .../ui/consts/const-eval/issue-44578.stderr | 8 +-- .../ui/consts/const-eval/promoted_errors.rs | 30 +++++----- .../consts/const-eval/promoted_errors.stderr | 55 +++++++++--------- .../ui/consts/const-eval/promoted_errors2.rs | 32 +++++------ .../consts/const-eval/promoted_errors2.stderr | 57 +++++++++---------- .../ui/consts/miri_unleashed/non_const_fn.rs | 2 +- .../consts/miri_unleashed/non_const_fn.stderr | 4 +- 19 files changed, 157 insertions(+), 176 deletions(-) rename src/test/{compile-fail => run-fail}/promoted_div_by_zero.rs (57%) diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index c6adbc81ce0b0..3ce916d781279 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -20,10 +20,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // use `get_static` to get at their id. // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics // always produce `&STATIC`. This may also simplify how const eval works with statics. - ty::ConstKind::Unevaluated(def_id, substs, promoted) - if self.cx.tcx().is_static(def_id) => - { - assert!(promoted.is_none()); + ty::ConstKind::Unevaluated(def_id, substs, None) if self.cx.tcx().is_static(def_id) => { assert!(substs.is_empty(), "we don't support generic statics yet"); let static_ = bx.get_static(def_id); // we treat operands referring to statics as if they were `&STATIC` instead @@ -49,10 +46,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None) .map_err(|err| { - self.cx - .tcx() - .sess - .span_err(constant.span, "erroneous constant encountered"); + if promoted.is_none() { + self.cx + .tcx() + .sess + .span_err(constant.span, "erroneous constant encountered"); + } err }) } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index b3ef639109735..1d5a643484a73 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -18,7 +18,7 @@ use rustc::ty::layout::{ HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; use rustc::ty::subst::{InternalSubsts, Subst}; -use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -441,8 +441,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ok(op) => Some(op), Err(error) => { let err = error_to_const_error(&self.ecx, error); - match self.lint_root(source_info) { - Some(lint_root) if c.literal.needs_subst() => { + if let Some(lint_root) = self.lint_root(source_info) { + let lint_only = match c.literal.val { + // Promoteds must lint and not error as the user didn't ask for them + ConstKind::Unevaluated(_, _, Some(_)) => true, + // Out of backwards compatibility we cannot report hard errors in unused + // generic functions using associated constants of the generic parameters. + _ => c.literal.needs_subst(), + }; + if lint_only { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. err.report_as_lint( @@ -451,10 +458,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { lint_root, Some(c.span), ); - } - _ => { + } else { err.report_as_error(self.ecx.tcx, "erroneous constant used"); } + } else { + err.report_as_error(self.ecx.tcx, "erroneous constant used"); } None } diff --git a/src/test/compile-fail/promoted_div_by_zero.rs b/src/test/run-fail/promoted_div_by_zero.rs similarity index 57% rename from src/test/compile-fail/promoted_div_by_zero.rs rename to src/test/run-fail/promoted_div_by_zero.rs index de55b5360f31d..3fe51a19c20bb 100644 --- a/src/test/compile-fail/promoted_div_by_zero.rs +++ b/src/test/run-fail/promoted_div_by_zero.rs @@ -1,6 +1,6 @@ #![allow(const_err)] -// error-pattern: referenced constant has errors +// error-pattern: attempt to divide by zero fn main() { let x = &(1 / (1 - 1)); diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs index 59b2fdb78216e..64aeb46894d16 100644 --- a/src/test/ui/consts/array-literal-index-oob.rs +++ b/src/test/ui/consts/array-literal-index-oob.rs @@ -1,8 +1,10 @@ -// build-fail +// build-pass + +#![warn(const_err)] fn main() { - &{[1, 2, 3][4]}; - //~^ ERROR index out of bounds - //~| ERROR reaching this expression at runtime will panic or abort - //~| ERROR erroneous constant used [E0080] + &{ [1, 2, 3][4] }; + //~^ WARN index out of bounds + //~| WARN reaching this expression at runtime will panic or abort + //~| WARN erroneous constant used [const_err] } diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr index 261c10d1391ad..50ad8e83e905c 100644 --- a/src/test/ui/consts/array-literal-index-oob.stderr +++ b/src/test/ui/consts/array-literal-index-oob.stderr @@ -1,25 +1,26 @@ -error: index out of bounds: the len is 3 but the index is 4 - --> $DIR/array-literal-index-oob.rs:4:7 +warning: index out of bounds: the len is 3 but the index is 4 + --> $DIR/array-literal-index-oob.rs:6:8 | -LL | &{[1, 2, 3][4]}; - | ^^^^^^^^^^^^ +LL | &{ [1, 2, 3][4] }; + | ^^^^^^^^^^^^ | - = note: `#[deny(const_err)]` on by default - -error: reaching this expression at runtime will panic or abort - --> $DIR/array-literal-index-oob.rs:4:7 +note: lint level defined here + --> $DIR/array-literal-index-oob.rs:3:9 | -LL | &{[1, 2, 3][4]}; - | --^^^^^^^^^^^^- - | | - | indexing out of bounds: the len is 3 but the index is 4 +LL | #![warn(const_err)] + | ^^^^^^^^^ -error[E0080]: erroneous constant used - --> $DIR/array-literal-index-oob.rs:4:5 +warning: reaching this expression at runtime will panic or abort + --> $DIR/array-literal-index-oob.rs:6:8 | -LL | &{[1, 2, 3][4]}; - | ^^^^^^^^^^^^^^^ referenced constant has errors +LL | &{ [1, 2, 3][4] }; + | ---^^^^^^^^^^^^-- + | | + | indexing out of bounds: the len is 3 but the index is 4 -error: aborting due to 3 previous errors +warning: erroneous constant used + --> $DIR/array-literal-index-oob.rs:6:5 + | +LL | &{ [1, 2, 3][4] }; + | ^^^^^^^^^^^^^^^^^ referenced constant has errors -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.rs b/src/test/ui/consts/const-eval/conditional_array_execution.rs index 107d0817dafc8..2058d2e218473 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.rs +++ b/src/test/ui/consts/const-eval/conditional_array_execution.rs @@ -10,5 +10,5 @@ const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; fn main() { println!("{}", FOO); //~^ ERROR - //~| ERROR erroneous constant used [E0080] + //~| WARN erroneous constant used [const_err] } diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index f161ab6f19892..b5f5f84cf3894 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -18,12 +18,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{}", FOO); | ^^^ referenced constant has errors -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/conditional_array_execution.rs:11:20 | LL | println!("{}", FOO); | ^^^ referenced constant has errors -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs index 21dbe72418a72..81f53826d8103 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -4,7 +4,9 @@ #![feature(const_fn)] #![allow(const_err)] -fn double(x: usize) -> usize { x * 2 } +fn double(x: usize) -> usize { + x * 2 +} const X: fn(usize) -> usize = double; const fn bar(x: fn(usize) -> usize, y: usize) -> usize { @@ -17,8 +19,6 @@ const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday fn main() { assert_eq!(Y, 4); //~^ ERROR evaluation of constant expression failed - //~| ERROR erroneous constant used [E0080] assert_eq!(Z, 4); //~^ ERROR evaluation of constant expression failed - //~| ERROR erroneous constant used [E0080] } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index ebbd18bbd253b..f99505c30901d 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -1,11 +1,11 @@ warning: skipping const checks - --> $DIR/const_fn_ptr_fail2.rs:11:5 + --> $DIR/const_fn_ptr_fail2.rs:13:5 | LL | x(y) | ^^^^ error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:18:5 + --> $DIR/const_fn_ptr_fail2.rs:20:5 | LL | assert_eq!(Y, 4); | ^^^^^^^^^^^-^^^^^ @@ -14,16 +14,8 @@ LL | assert_eq!(Y, 4); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error[E0080]: erroneous constant used - --> $DIR/const_fn_ptr_fail2.rs:18:5 - | -LL | assert_eq!(Y, 4); - | ^^^^^^^^^^^^^^^^^ referenced constant has errors - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:21:5 + --> $DIR/const_fn_ptr_fail2.rs:22:5 | LL | assert_eq!(Z, 4); | ^^^^^^^^^^^-^^^^^ @@ -32,14 +24,6 @@ LL | assert_eq!(Z, 4); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error[E0080]: erroneous constant used - --> $DIR/const_fn_ptr_fail2.rs:21:5 - | -LL | assert_eq!(Z, 4); - | ^^^^^^^^^^^^^^^^^ referenced constant has errors - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-43197.rs b/src/test/ui/consts/const-eval/issue-43197.rs index 23890be693431..9109307632b59 100644 --- a/src/test/ui/consts/const-eval/issue-43197.rs +++ b/src/test/ui/consts/const-eval/issue-43197.rs @@ -7,13 +7,13 @@ const fn foo(x: u32) -> u32 { } fn main() { - const X: u32 = 0-1; + const X: u32 = 0 - 1; //~^ WARN any use of this value will cause - const Y: u32 = foo(0-1); + const Y: u32 = foo(0 - 1); //~^ WARN any use of this value will cause println!("{} {}", X, Y); //~^ ERROR evaluation of constant expression failed //~| ERROR evaluation of constant expression failed - //~| ERROR erroneous constant used [E0080] - //~| ERROR erroneous constant used [E0080] + //~| WARN erroneous constant used [const_err] + //~| WARN erroneous constant used [const_err] } diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 50bc07d459c78..23b54d954c658 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -1,8 +1,8 @@ warning: any use of this value will cause an error --> $DIR/issue-43197.rs:10:20 | -LL | const X: u32 = 0-1; - | ---------------^^^- +LL | const X: u32 = 0 - 1; + | ---------------^^^^^- | | | attempt to subtract with overflow | @@ -15,8 +15,8 @@ LL | #![warn(const_err)] warning: any use of this value will cause an error --> $DIR/issue-43197.rs:12:24 | -LL | const Y: u32 = foo(0-1); - | -------------------^^^-- +LL | const Y: u32 = foo(0 - 1); + | -------------------^^^^^-- | | | attempt to subtract with overflow @@ -26,7 +26,7 @@ error[E0080]: evaluation of constant expression failed LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/issue-43197.rs:14:23 | LL | println!("{} {}", X, Y); @@ -38,12 +38,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/issue-43197.rs:14:26 | LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index 607f78f70b308..f9194709dc0b7 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -25,6 +25,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR erroneous constant used [E0080] - //~| ERROR evaluation of constant expression failed [E0080] + //~^ ERROR evaluation of constant expression failed [E0080] } diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index 5c0ac17acebe6..f4323713e682b 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -4,12 +4,6 @@ error[E0080]: evaluation of constant expression failed LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors -error[E0080]: erroneous constant used - --> $DIR/issue-44578.rs:27:20 - | -LL | println!("{}", as Foo>::AMT); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index 6d83839a8d1cd..fee232185d29a 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -1,22 +1,22 @@ -// build-fail +// build-pass // compile-flags: -O -#![deny(const_err)] +#![warn(const_err)] fn main() { println!("{}", 0u32 - 1); let _x = 0u32 - 1; - //~^ ERROR const_err - println!("{}", 1/(1-1)); - //~^ ERROR attempt to divide by zero [const_err] - //~| ERROR const_err - //~| ERROR erroneous constant used [E0080] - let _x = 1/(1-1); - //~^ ERROR const_err - println!("{}", 1/(false as u32)); - //~^ ERROR attempt to divide by zero [const_err] - //~| ERROR const_err - //~| ERROR erroneous constant used [E0080] - let _x = 1/(false as u32); - //~^ ERROR const_err + //~^ WARN const_err + println!("{}", 1 / (1 - 1)); + //~^ WARN attempt to divide by zero [const_err] + //~| WARN const_err + //~| WARN erroneous constant used [const_err] + let _x = 1 / (1 - 1); + //~^ WARN const_err + println!("{}", 1 / (false as u32)); + //~^ WARN attempt to divide by zero [const_err] + //~| WARN const_err + //~| WARN erroneous constant used [const_err] + let _x = 1 / (false as u32); + //~^ WARN const_err } diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 32672ca856641..4de22fdf4ab1e 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,4 +1,4 @@ -error: this expression will panic at runtime +warning: this expression will panic at runtime --> $DIR/promoted_errors.rs:8:14 | LL | let _x = 0u32 - 1; @@ -7,57 +7,54 @@ LL | let _x = 0u32 - 1; note: lint level defined here --> $DIR/promoted_errors.rs:4:9 | -LL | #![deny(const_err)] +LL | #![warn(const_err)] | ^^^^^^^^^ -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors.rs:10:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ -error: reaching this expression at runtime will panic or abort +warning: reaching this expression at runtime will panic or abort --> $DIR/promoted_errors.rs:10:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ dividing by zero +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ dividing by zero -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/promoted_errors.rs:10:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ referenced constant has errors +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ referenced constant has errors -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors.rs:14:14 | -LL | let _x = 1/(1-1); - | ^^^^^^^ +LL | let _x = 1 / (1 - 1); + | ^^^^^^^^^^^ -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors.rs:16:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ -error: reaching this expression at runtime will panic or abort +warning: reaching this expression at runtime will panic or abort --> $DIR/promoted_errors.rs:16:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ dividing by zero +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ dividing by zero -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/promoted_errors.rs:16:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ referenced constant has errors +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ referenced constant has errors -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors.rs:20:14 | -LL | let _x = 1/(false as u32); - | ^^^^^^^^^^^^^^^^ +LL | let _x = 1 / (false as u32); + | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors - -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs index 8ea6cdf6a8f61..41a989d91c5d3 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.rs +++ b/src/test/ui/consts/const-eval/promoted_errors2.rs @@ -1,23 +1,23 @@ -// build-fail +// build-pass // compile-flags: -C overflow-checks=on -O -#![deny(const_err)] +#![warn(const_err)] fn main() { println!("{}", 0u32 - 1); - //~^ ERROR attempt to subtract with overflow + //~^ WARN attempt to subtract with overflow let _x = 0u32 - 1; - //~^ ERROR attempt to subtract with overflow - println!("{}", 1/(1-1)); - //~^ ERROR attempt to divide by zero [const_err] - //~| ERROR const_err - //~| ERROR erroneous constant used [E0080] - let _x = 1/(1-1); - //~^ ERROR const_err - println!("{}", 1/(false as u32)); - //~^ ERROR attempt to divide by zero [const_err] - //~| ERROR const_err - //~| ERROR erroneous constant used [E0080] - let _x = 1/(false as u32); - //~^ ERROR const_err + //~^ WARN attempt to subtract with overflow + println!("{}", 1 / (1 - 1)); + //~^ WARN attempt to divide by zero [const_err] + //~| WARN const_err + //~| WARN erroneous constant used [const_err] + let _x = 1 / (1 - 1); + //~^ WARN const_err + println!("{}", 1 / (false as u32)); + //~^ WARN attempt to divide by zero [const_err] + //~| WARN const_err + //~| WARN erroneous constant used [const_err] + let _x = 1 / (false as u32); + //~^ WARN const_err } diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr index e7a73aa8118e3..4f7ba8bf385d3 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr @@ -1,4 +1,4 @@ -error: attempt to subtract with overflow +warning: attempt to subtract with overflow --> $DIR/promoted_errors2.rs:7:20 | LL | println!("{}", 0u32 - 1); @@ -7,63 +7,60 @@ LL | println!("{}", 0u32 - 1); note: lint level defined here --> $DIR/promoted_errors2.rs:4:9 | -LL | #![deny(const_err)] +LL | #![warn(const_err)] | ^^^^^^^^^ -error: attempt to subtract with overflow +warning: attempt to subtract with overflow --> $DIR/promoted_errors2.rs:9:14 | LL | let _x = 0u32 - 1; | ^^^^^^^^ -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors2.rs:11:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ -error: reaching this expression at runtime will panic or abort +warning: reaching this expression at runtime will panic or abort --> $DIR/promoted_errors2.rs:11:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ dividing by zero +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ dividing by zero -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/promoted_errors2.rs:11:20 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ referenced constant has errors +LL | println!("{}", 1 / (1 - 1)); + | ^^^^^^^^^^^ referenced constant has errors -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors2.rs:15:14 | -LL | let _x = 1/(1-1); - | ^^^^^^^ +LL | let _x = 1 / (1 - 1); + | ^^^^^^^^^^^ -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors2.rs:17:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ -error: reaching this expression at runtime will panic or abort +warning: reaching this expression at runtime will panic or abort --> $DIR/promoted_errors2.rs:17:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ dividing by zero +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ dividing by zero -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/promoted_errors2.rs:17:20 | -LL | println!("{}", 1/(false as u32)); - | ^^^^^^^^^^^^^^^^ referenced constant has errors +LL | println!("{}", 1 / (false as u32)); + | ^^^^^^^^^^^^^^^^^^ referenced constant has errors -error: attempt to divide by zero +warning: attempt to divide by zero --> $DIR/promoted_errors2.rs:21:14 | -LL | let _x = 1/(false as u32); - | ^^^^^^^^^^^^^^^^ +LL | let _x = 1 / (false as u32); + | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 10 previous errors - -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/non_const_fn.rs b/src/test/ui/consts/miri_unleashed/non_const_fn.rs index 23b0cfa83211f..cfb57d21ceec5 100644 --- a/src/test/ui/consts/miri_unleashed/non_const_fn.rs +++ b/src/test/ui/consts/miri_unleashed/non_const_fn.rs @@ -13,5 +13,5 @@ const C: () = foo(); //~ WARN: skipping const checks fn main() { println!("{:?}", C); //~^ ERROR: evaluation of constant expression failed - //~| ERROR: erroneous constant used [E0080] + //~| WARN: erroneous constant used [const_err] } diff --git a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr index a7364ddf72c87..6a7df858febcf 100644 --- a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr +++ b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr @@ -24,12 +24,12 @@ error[E0080]: evaluation of constant expression failed LL | println!("{:?}", C); | ^ referenced constant has errors -error[E0080]: erroneous constant used +warning: erroneous constant used --> $DIR/non_const_fn.rs:14:22 | LL | println!("{:?}", C); | ^ referenced constant has errors -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. From 050146f7f0d6ba4c0241a6fd8fa5d3fd67766e45 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 10:33:49 +0100 Subject: [PATCH 0163/1253] Add regression tests for promotion mir expansion --- src/test/mir-opt/const_prop/ref_deref.rs | 18 ++++++++ .../mir-opt/const_prop/ref_deref_project.rs | 41 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/test/mir-opt/const_prop/ref_deref_project.rs diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs index 6b5101af5fcd8..8b48296a5d911 100644 --- a/src/test/mir-opt/const_prop/ref_deref.rs +++ b/src/test/mir-opt/const_prop/ref_deref.rs @@ -3,6 +3,24 @@ fn main() { } // END RUST SOURCE +// START rustc.main.PromoteTemps.before.mir +// bb0: { +// ... +// _3 = const 4i32; +// _2 = &_3; +// _1 = (*_2); +// ... +//} +// END rustc.main.PromoteTemps.before.mir +// START rustc.main.PromoteTemps.after.mir +// bb0: { +// ... +// _4 = const main::promoted[0]; +// _2 = &(*_4); +// _1 = (*_2); +// ... +//} +// END rustc.main.PromoteTemps.after.mir // START rustc.main.ConstProp.before.mir // bb0: { // ... diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs new file mode 100644 index 0000000000000..5808a8be176d4 --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -0,0 +1,41 @@ +fn main() { + *(&(4, 5).1); +} + +// END RUST SOURCE +// START rustc.main.PromoteTemps.before.mir +// bb0: { +// ... +// _3 = (const 4i32, const 5i32); +// _2 = &(_3.1: i32); +// _1 = (*_2); +// ... +//} +// END rustc.main.PromoteTemps.before.mir +// START rustc.main.PromoteTemps.after.mir +// bb0: { +// ... +// _4 = const main::promoted[0]; +// _2 = &((*_4).1: i32); +// _1 = (*_2); +// ... +//} +// END rustc.main.PromoteTemps.after.mir +// START rustc.main.ConstProp.before.mir +// bb0: { +// ... +// _4 = const main::promoted[0]; +// _2 = &((*_4).1: i32); +// _1 = (*_2); +// ... +//} +// END rustc.main.ConstProp.before.mir +// START rustc.main.ConstProp.after.mir +// bb0: { +// ... +// _4 = const main::promoted[0]; +// _2 = &((*_4).1: i32); +// _1 = const 5i32; +// ... +// } +// END rustc.main.ConstProp.after.mir From 43313d574394de6b9be6bbf0eb782c9cef56e69f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 14:46:32 +0100 Subject: [PATCH 0164/1253] Remove an outdated comment --- src/librustc_mir/interpret/operand.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 2cb574bc681b1..b37eff3f40626 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -467,7 +467,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { local => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. - // FIXME use place_projection.is_empty() when is available let layout = if place.projection.is_empty() { layout } else { None }; self.access_local(self.frame(), local, layout)? From a5d8ab713ad9871283d07c8920be14f0d6132705 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 15:32:14 +0100 Subject: [PATCH 0165/1253] Rebase fallout --- src/test/mir-opt/const-promotion-extern-static.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs index d611ec22c38ec..3abc90e42e8ca 100644 --- a/src/test/mir-opt/const-promotion-extern-static.rs +++ b/src/test/mir-opt/const-promotion-extern-static.rs @@ -48,7 +48,8 @@ fn main() {} // START rustc.BAR.PromoteTemps.after.mir // bb0: { // ... -// _2 = &(promoted[0]: [&'static i32; 1]); +// _6 = const BAR::promoted[0]; +// _2 = &(*_6); // _1 = move _2 as &[&'static i32] (Pointer(Unsize)); // _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // } @@ -60,7 +61,8 @@ fn main() {} // START rustc.FOO.PromoteTemps.after.mir // bb0: { // ... -// _2 = &(promoted[0]: [&'static i32; 1]); +// _6 = const FOO::promoted[0]; +// _2 = &(*_6); // _1 = move _2 as &[&'static i32] (Pointer(Unsize)); // _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // } From c899f676733c8b7a732294ca7484c64ae3d6dddf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 10:05:49 +0100 Subject: [PATCH 0166/1253] Improve E0185 wording --- src/librustc_error_codes/error_codes/E0185.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0185.md b/src/librustc_error_codes/error_codes/E0185.md index ea29e2d451622..ac5d8bd766f40 100644 --- a/src/librustc_error_codes/error_codes/E0185.md +++ b/src/librustc_error_codes/error_codes/E0185.md @@ -19,8 +19,8 @@ impl Foo for Bar { ``` When a type implements a trait's associated function, it has to use the same -signature. So in this case, since `Foo::foo` doesn't take argument and doesn't -return anything, its implementation on `Bar` should the same: +signature. So in this case, since `Foo::foo` doesn't take any argument and +doesn't return anything, its implementation on `Bar` should be the same: ``` trait Foo { From a62c040929a0620498c85f7a051e4005c28ff4d7 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 13 Dec 2019 14:44:08 +0100 Subject: [PATCH 0167/1253] self-profile: Switch to new approach for event_id generation that enables query-invocation-specific event_ids. --- Cargo.lock | 4 +- src/librustc/Cargo.toml | 1 + src/librustc/dep_graph/graph.rs | 30 +++- src/librustc/ty/query/config.rs | 5 +- src/librustc/ty/query/plumbing.rs | 117 ++++++------- src/librustc_codegen_ssa/base.rs | 31 +++- src/librustc_data_structures/Cargo.toml | 2 +- src/librustc_data_structures/profiling.rs | 191 ++++++++++++++++++---- src/librustc_interface/util.rs | 4 - 9 files changed, 277 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a2223814918a..96f37457a0e05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,9 +1995,9 @@ dependencies = [ [[package]] name = "measureme" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c420bbc064623934620b5ab2dc0cf96451b34163329e82f95e7fa1b7b99a6ac8" +checksum = "36dcc09c1a633097649f7d48bde3d8a61d2a43c01ce75525e31fbbc82c0fccf4" dependencies = [ "byteorder", "memmap", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 1a04a9d86b58b..567dc85213ab6 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -36,5 +36,6 @@ parking_lot = "0.9" byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } smallvec = { version = "1.0", features = ["union", "may_dangle"] } +measureme = "0.6.0" rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0d03c834e0f7b..0616f00b8c472 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -8,6 +8,8 @@ use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::collections::hash_map::Entry; +use rustc_data_structures::profiling::QueryInvocationId; +use std::sync::atomic::Ordering::Relaxed; use std::env; use std::hash::Hash; use std::mem; @@ -25,6 +27,12 @@ use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; #[derive(Clone)] pub struct DepGraph { data: Option>, + + /// This field is used for assigning DepNodeIndices when running in + /// non-incremental mode. Even in non-incremental mode we make sure that + /// each task as a `DepNodeIndex` that uniquely identifies it. This unique + /// ID is used for self-profiling. + virtual_dep_node_index: Lrc, } rustc_index::newtype_index! { @@ -35,6 +43,13 @@ impl DepNodeIndex { pub const INVALID: DepNodeIndex = DepNodeIndex::MAX; } +impl std::convert::From for QueryInvocationId { + #[inline] + fn from(dep_node_index: DepNodeIndex) -> Self { + QueryInvocationId(dep_node_index.as_u32()) + } +} + #[derive(PartialEq)] pub enum DepNodeColor { Red, @@ -105,11 +120,15 @@ impl DepGraph { previous: prev_graph, colors: DepNodeColorMap::new(prev_graph_node_count), })), + virtual_dep_node_index: Lrc::new(AtomicU32::new(0)), } } pub fn new_disabled() -> DepGraph { - DepGraph { data: None } + DepGraph { + data: None, + virtual_dep_node_index: Lrc::new(AtomicU32::new(0)), + } } /// Returns `true` if we are actually building the full dep-graph, and `false` otherwise. @@ -322,7 +341,7 @@ impl DepGraph { (result, dep_node_index) } else { - (task(cx, arg), DepNodeIndex::INVALID) + (task(cx, arg), self.next_virtual_depnode_index()) } } @@ -352,7 +371,7 @@ impl DepGraph { let dep_node_index = data.current.complete_anon_task(dep_kind, task_deps); (result, dep_node_index) } else { - (op(), DepNodeIndex::INVALID) + (op(), self.next_virtual_depnode_index()) } } @@ -877,6 +896,11 @@ impl DepGraph { } } } + + fn next_virtual_depnode_index(&self) -> DepNodeIndex { + let index = self.virtual_dep_node_index.fetch_add(1, Relaxed); + DepNodeIndex::from_u32(index) + } } /// A "work product" is an intermediate result that we save into the diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index c77cf8c41be9a..dbb6a1080e6d4 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -2,8 +2,7 @@ use crate::dep_graph::SerializedDepNodeIndex; use crate::dep_graph::{DepKind, DepNode}; use crate::ty::query::plumbing::CycleError; use crate::ty::query::queries; -use crate::ty::query::QueryCache; -use crate::ty::query::{Query, QueryName}; +use crate::ty::query::{Query, QueryCache}; use crate::ty::TyCtxt; use rustc_data_structures::profiling::ProfileCategory; use rustc_hir::def_id::{CrateNum, DefId}; @@ -20,7 +19,7 @@ use std::hash::Hash; // FIXME(eddyb) false positive, the lifetime parameter is used for `Key`/`Value`. #[allow(unused_lifetimes)] pub trait QueryConfig<'tcx> { - const NAME: QueryName; + const NAME: &'static str; const CATEGORY: ProfileCategory; type Key: Eq + Hash + Clone + Debug; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 35608540383b0..5792995826781 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { if let Some((_, value)) = lock.results.raw_entry().from_key_hashed_nocheck(key_hash, key) { - tcx.prof.query_cache_hit(Q::NAME); + tcx.prof.query_cache_hit(value.index.into()); let result = (value.value.clone(), value.index); #[cfg(debug_assertions)] { @@ -347,7 +347,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(never)] pub(super) fn get_query>(self, span: Span, key: Q::Key) -> Q::Value { - debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME.as_str(), key, span); + debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span); let job = match JobOwner::try_get(self, span, &key) { TryGetJob::NotYetStarted(job) => job, @@ -366,7 +366,7 @@ impl<'tcx> TyCtxt<'tcx> { } if Q::ANON { - let prof_timer = self.prof.query_provider(Q::NAME); + let prof_timer = self.prof.query_provider(); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { @@ -374,7 +374,7 @@ impl<'tcx> TyCtxt<'tcx> { }) }); - drop(prof_timer); + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); self.dep_graph.read_index(dep_node_index); @@ -436,8 +436,9 @@ impl<'tcx> TyCtxt<'tcx> { let result = if Q::cache_on_disk(self, key.clone(), None) && self.sess.opts.debugging_opts.incremental_queries { - let _prof_timer = self.prof.incr_cache_loading(Q::NAME); + let prof_timer = self.prof.incr_cache_loading(); let result = Q::try_load_from_disk(self, prev_dep_node_index); + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); // We always expect to find a cached result for things that // can be forced from `DepNode`. @@ -457,11 +458,13 @@ impl<'tcx> TyCtxt<'tcx> { } else { // We could not load a result from the on-disk cache, so // recompute. - let _prof_timer = self.prof.query_provider(Q::NAME); + let prof_timer = self.prof.query_provider(); // The dep-graph for this computation is already in-place. let result = self.dep_graph.with_ignore(|| Q::compute(self, key)); + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); + result }; @@ -523,7 +526,7 @@ impl<'tcx> TyCtxt<'tcx> { dep_node ); - let prof_timer = self.prof.query_provider(Q::NAME); + let prof_timer = self.prof.query_provider(); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { @@ -541,7 +544,7 @@ impl<'tcx> TyCtxt<'tcx> { }) }); - drop(prof_timer); + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); if unlikely!(!diagnostics.is_empty()) { if dep_node.kind != crate::dep_graph::DepKind::Null { @@ -572,17 +575,19 @@ impl<'tcx> TyCtxt<'tcx> { let dep_node = Q::to_dep_node(self, &key); - if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { - // A None return from `try_mark_green_and_read` means that this is either - // a new dep node or that the dep node has already been marked red. - // Either way, we can't call `dep_graph.read()` as we don't have the - // DepNodeIndex. We must invoke the query itself. The performance cost - // this introduces should be negligible as we'll immediately hit the - // in-memory cache, or another query down the line will. - - let _ = self.get_query::(DUMMY_SP, key); - } else { - self.prof.query_cache_hit(Q::NAME); + match self.dep_graph.try_mark_green_and_read(self, &dep_node) { + None => { + // A None return from `try_mark_green_and_read` means that this is either + // a new dep node or that the dep node has already been marked red. + // Either way, we can't call `dep_graph.read()` as we don't have the + // DepNodeIndex. We must invoke the query itself. The performance cost + // this introduces should be negligible as we'll immediately hit the + // in-memory cache, or another query down the line will. + let _ = self.get_query::(DUMMY_SP, key); + } + Some((_, dep_node_index)) => { + self.prof.query_cache_hit(dep_node_index.into()); + } } } @@ -696,6 +701,42 @@ macro_rules! define_queries_inner { } } + /// All self-profiling events generated by the query engine use a + /// virtual `StringId`s for their `event_id`. This method makes all + /// those virtual `StringId`s point to actual strings. + /// + /// If we are recording only summary data, the ids will point to + /// just the query names. If we are recording query keys too, we + /// allocate the corresponding strings here. (The latter is not yet + /// implemented.) + pub fn allocate_self_profile_query_strings( + &self, + profiler: &rustc_data_structures::profiling::SelfProfiler + ) { + // Walk the entire query cache and allocate the appropriate + // string representation. Each cache entry is uniquely + // identified by its dep_node_index. + $({ + let query_name_string_id = + profiler.get_or_alloc_cached_string(stringify!($name)); + + let result_cache = self.$name.lock_shards(); + + for shard in result_cache.iter() { + let query_invocation_ids = shard + .results + .values() + .map(|v| v.index) + .map(|dep_node_index| dep_node_index.into()); + + profiler.bulk_map_query_invocation_id_to_single_string( + query_invocation_ids, + query_name_string_id + ); + } + })* + } + #[cfg(parallel_compiler)] pub fn collect_active_jobs(&self) -> Vec>> { let mut jobs = Vec::new(); @@ -813,36 +854,6 @@ macro_rules! define_queries_inner { } } - #[allow(nonstandard_style)] - #[derive(Clone, Copy)] - pub enum QueryName { - $($name),* - } - - impl rustc_data_structures::profiling::QueryName for QueryName { - fn discriminant(self) -> std::mem::Discriminant { - std::mem::discriminant(&self) - } - - fn as_str(self) -> &'static str { - QueryName::as_str(&self) - } - } - - impl QueryName { - pub fn register_with_profiler( - profiler: &rustc_data_structures::profiling::SelfProfiler, - ) { - $(profiler.register_query_name(QueryName::$name);)* - } - - pub fn as_str(&self) -> &'static str { - match self { - $(QueryName::$name => stringify!($name),)* - } - } - } - #[allow(nonstandard_style)] #[derive(Clone, Debug)] pub enum Query<$tcx> { @@ -883,12 +894,6 @@ macro_rules! define_queries_inner { $(Query::$name(key) => key.default_span(tcx),)* } } - - pub fn query_name(&self) -> QueryName { - match self { - $(Query::$name(_) => QueryName::$name,)* - } - } } impl<'a, $tcx> HashStable> for Query<$tcx> { @@ -923,7 +928,7 @@ macro_rules! define_queries_inner { type Key = $K; type Value = $V; - const NAME: QueryName = QueryName::$name; + const NAME: &'static str = stringify!($name); const CATEGORY: ProfileCategory = $category; } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index c838109072775..8087db9fabc2f 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -85,7 +85,7 @@ pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, signed: bool) -> IntPredicat } op => bug!( "comparison_op_to_icmp_predicate: expected comparison operator, \ - found {:?}", + found {:?}", op ), } @@ -102,7 +102,7 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> RealPredicate { op => { bug!( "comparison_op_to_fcmp_predicate: expected comparison operator, \ - found {:?}", + found {:?}", op ); } @@ -334,7 +334,11 @@ pub fn from_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, val: Bx::Value, ) -> Bx::Value { - if bx.cx().val_ty(val) == bx.cx().type_i1() { bx.zext(val, bx.cx().type_i8()) } else { val } + if bx.cx().val_ty(val) == bx.cx().type_i1() { + bx.zext(val, bx.cx().type_i8()) + } else { + val + } } pub fn to_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( @@ -519,7 +523,7 @@ pub fn codegen_crate( ongoing_codegen.codegen_finished(tcx); - assert_and_save_dep_graph(tcx); + finalize_tcx(tcx); ongoing_codegen.check_for_errors(tcx.sess); @@ -660,7 +664,8 @@ pub fn codegen_crate( ongoing_codegen.check_for_errors(tcx.sess); - assert_and_save_dep_graph(tcx); + finalize_tcx(tcx); + ongoing_codegen.into_inner() } @@ -711,10 +716,16 @@ impl Drop for AbortCodegenOnDrop { } } -fn assert_and_save_dep_graph(tcx: TyCtxt<'_>) { +fn finalize_tcx(tcx: TyCtxt<'_>) { tcx.sess.time("assert_dep_graph", || ::rustc_incremental::assert_dep_graph(tcx)); - tcx.sess.time("serialize_dep_graph", || ::rustc_incremental::save_dep_graph(tcx)); + + // We assume that no queries are run past here. If there are new queries + // after this point, they'll show up as "" in self-profiling data. + tcx.prof.with_profiler(|profiler| { + let _prof_timer = tcx.prof.generic_activity("self_profile_alloc_query_strings"); + tcx.queries.allocate_self_profile_query_strings(profiler); + }); } impl CrateInfo { @@ -876,7 +887,11 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { // We can re-use either the pre- or the post-thinlto state - if tcx.sess.lto() != Lto::No { CguReuse::PreLto } else { CguReuse::PostLto } + if tcx.sess.lto() != Lto::No { + CguReuse::PreLto + } else { + CguReuse::PostLto + } } else { CguReuse::No } diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 7fa40b8a86905..9c42f3633f2c0 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -26,7 +26,7 @@ rustc-hash = "1.0.1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_index = { path = "../librustc_index", package = "rustc_index" } bitflags = "1.2.1" -measureme = "0.5" +measureme = "0.6.0" [dependencies.parking_lot] version = "0.9" diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index a9d3a2668aab1..db56023560a0d 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -1,6 +1,90 @@ +//! # Rust Compiler Self-Profiling +//! +//! This module implements the basic framework for the compiler's self- +//! profiling support. It provides the `SelfProfiler` type which enables +//! recording "events". An event is something that starts and ends at a given +//! point in time and has an ID and a kind attached to it. This allows for +//! tracing the compiler's activity. +//! +//! Internally this module uses the custom tailored [measureme][mm] crate for +//! efficiently recording events to disk in a compact format that can be +//! post-processed and analyzed by the suite of tools in the `measureme` +//! project. The highest priority for the tracing framework is on incurring as +//! little overhead as possible. +//! +//! +//! ## Event Overview +//! +//! Events have a few properties: +//! +//! - The `event_kind` designates the broad category of an event (e.g. does it +//! correspond to the execution of a query provider or to loading something +//! from the incr. comp. on-disk cache, etc). +//! - The `event_id` designates the query invocation or function call it +//! corresponds to, possibly including the query key or function arguments. +//! - Each event stores the ID of the thread it was recorded on. +//! - The timestamp stores beginning and end of the event, or the single point +//! in time it occurred at for "instant" events. +//! +//! +//! ## Event Filtering +//! +//! Event generation can be filtered by event kind. Recording all possible +//! events generates a lot of data, much of which is not needed for most kinds +//! of analysis. So, in order to keep overhead as low as possible for a given +//! use case, the `SelfProfiler` will only record the kinds of events that +//! pass the filter specified as a command line argument to the compiler. +//! +//! +//! ## `event_id` Assignment +//! +//! As far as `measureme` is concerned, `event_id`s are just strings. However, +//! it would incur way too much overhead to generate and persist each `event_id` +//! string at the point where the event is recorded. In order to make this more +//! efficient `measureme` has two features: +//! +//! - Strings can share their content, so that re-occurring parts don't have to +//! be copied over and over again. One allocates a string in `measureme` and +//! gets back a `StringId`. This `StringId` is then used to refer to that +//! string. `measureme` strings are actually DAGs of string components so that +//! arbitrary sharing of substrings can be done efficiently. This is useful +//! because `event_id`s contain lots of redundant text like query names or +//! def-path components. +//! +//! - `StringId`s can be "virtual" which means that the client picks a numeric +//! ID according to some application-specific scheme and can later make that +//! ID be mapped to an actual string. This is used to cheaply generate +//! `event_id`s while the events actually occur, causing little timing +//! distortion, and then later map those `StringId`s, in bulk, to actual +//! `event_id` strings. This way the largest part of tracing overhead is +//! localized to one contiguous chunk of time. +//! +//! How are these `event_id`s generated in the compiler? For things that occur +//! infrequently (e.g. "generic activities"), we just allocate the string the +//! first time it is used and then keep the `StringId` in a hash table. This +//! is implemented in `SelfProfiler::get_or_alloc_cached_string()`. +//! +//! For queries it gets more interesting: First we need a unique numeric ID for +//! each query invocation (the `QueryInvocationId`). This ID is used as the +//! virtual `StringId` we use as `event_id` for a given event. This ID has to +//! be available both when the query is executed and later, together with the +//! query key, when we allocate the actual `event_id` strings in bulk. +//! +//! We could make the compiler generate and keep track of such an ID for each +//! query invocation but luckily we already have something that fits all the +//! the requirements: the query's `DepNodeIndex`. So we use the numeric value +//! of the `DepNodeIndex` as `event_id` when recording the event and then, +//! just before the query context is dropped, we walk the entire query cache +//! (which stores the `DepNodeIndex` along with the query key for each +//! invocation) and allocate the corresponding strings together with a mapping +//! for `DepNodeIndex as StringId`. +//! +//! [mm]: https://github.com/rust-lang/measureme/ + +use crate::fx::FxHashMap; + use std::error::Error; use std::fs; -use std::mem::{self, Discriminant}; use std::path::Path; use std::process; use std::sync::Arc; @@ -9,6 +93,7 @@ use std::time::{Duration, Instant}; use std::u32; use measureme::StringId; +use parking_lot::RwLock; /// MmapSerializatioSink is faster on macOS and Linux /// but FileSerializationSink is faster on Windows @@ -19,11 +104,6 @@ type SerializationSink = measureme::FileSerializationSink; type Profiler = measureme::Profiler; -pub trait QueryName: Sized + Copy { - fn discriminant(self) -> Discriminant; - fn as_str(self) -> &'static str; -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)] pub enum ProfileCategory { Parsing, @@ -65,9 +145,12 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ]; fn thread_id_to_u32(tid: ThreadId) -> u32 { - unsafe { mem::transmute::(tid) as u32 } + unsafe { std::mem::transmute::(tid) as u32 } } +/// Something that uniquely identifies a query invocation. +pub struct QueryInvocationId(pub u32); + /// A reference to the SelfProfiler. It can be cloned and sent across thread /// boundaries at will. #[derive(Clone)] @@ -167,29 +250,32 @@ impl SelfProfilerRef { /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] - pub fn generic_activity(&self, event_id: &str) -> TimingGuard<'_> { + pub fn generic_activity(&self, event_id: &'static str) -> TimingGuard<'_> { self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| { - let event_id = profiler.profiler.alloc_string(event_id); - TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id) + let event_id = profiler.get_or_alloc_cached_string(event_id); + TimingGuard::start( + profiler, + profiler.generic_activity_event_kind, + event_id + ) }) } /// Start profiling a query provider. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] - pub fn query_provider(&self, query_name: impl QueryName) -> TimingGuard<'_> { + pub fn query_provider(&self) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_PROVIDERS, |profiler| { - let event_id = SelfProfiler::get_query_name_string_id(query_name); - TimingGuard::start(profiler, profiler.query_event_kind, event_id) + TimingGuard::start(profiler, profiler.query_event_kind, StringId::INVALID) }) } /// Record a query in-memory cache hit. #[inline(always)] - pub fn query_cache_hit(&self, query_name: impl QueryName) { + pub fn query_cache_hit(&self, query_invocation_id: QueryInvocationId) { self.instant_query_event( |profiler| profiler.query_cache_hit_event_kind, - query_name, + query_invocation_id, EventFilter::QUERY_CACHE_HITS, ); } @@ -198,10 +284,13 @@ impl SelfProfilerRef { /// Profiling continues until the TimingGuard returned from this call is /// dropped. #[inline(always)] - pub fn query_blocked(&self, query_name: impl QueryName) -> TimingGuard<'_> { + pub fn query_blocked(&self) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_BLOCKED, |profiler| { - let event_id = SelfProfiler::get_query_name_string_id(query_name); - TimingGuard::start(profiler, profiler.query_blocked_event_kind, event_id) + TimingGuard::start( + profiler, + profiler.query_blocked_event_kind, + StringId::INVALID, + ) }) } @@ -209,10 +298,13 @@ impl SelfProfilerRef { /// incremental compilation on-disk cache. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] - pub fn incr_cache_loading(&self, query_name: impl QueryName) -> TimingGuard<'_> { + pub fn incr_cache_loading(&self) -> TimingGuard<'_> { self.exec(EventFilter::INCR_CACHE_LOADS, |profiler| { - let event_id = SelfProfiler::get_query_name_string_id(query_name); - TimingGuard::start(profiler, profiler.incremental_load_result_event_kind, event_id) + TimingGuard::start( + profiler, + profiler.incremental_load_result_event_kind, + StringId::INVALID, + ) }) } @@ -220,11 +312,11 @@ impl SelfProfilerRef { fn instant_query_event( &self, event_kind: fn(&SelfProfiler) -> StringId, - query_name: impl QueryName, + query_invocation_id: QueryInvocationId, event_filter: EventFilter, ) { drop(self.exec(event_filter, |profiler| { - let event_id = SelfProfiler::get_query_name_string_id(query_name); + let event_id = StringId::new_virtual(query_invocation_id.0); let thread_id = thread_id_to_u32(std::thread::current().id()); profiler.profiler.record_instant_event(event_kind(profiler), event_id, thread_id); @@ -233,7 +325,7 @@ impl SelfProfilerRef { })); } - pub fn register_queries(&self, f: impl FnOnce(&SelfProfiler)) { + pub fn with_profiler(&self, f: impl FnOnce(&SelfProfiler)) { if let Some(profiler) = &self.profiler { f(&profiler) } @@ -243,6 +335,9 @@ impl SelfProfilerRef { pub struct SelfProfiler { profiler: Profiler, event_filter_mask: EventFilter, + + string_cache: RwLock>, + query_event_kind: StringId, generic_activity_event_kind: StringId, incremental_load_result_event_kind: StringId, @@ -305,6 +400,7 @@ impl SelfProfiler { Ok(SelfProfiler { profiler, event_filter_mask, + string_cache: RwLock::new(FxHashMap::default()), query_event_kind, generic_activity_event_kind, incremental_load_result_event_kind, @@ -313,16 +409,41 @@ impl SelfProfiler { }) } - fn get_query_name_string_id(query_name: impl QueryName) -> StringId { - let discriminant = - unsafe { mem::transmute::, u64>(query_name.discriminant()) }; + pub fn get_or_alloc_cached_string(&self, s: &'static str) -> StringId { + // Only acquire a read-lock first since we assume that the string is + // already present in the common case. + { + let string_cache = self.string_cache.read(); + + if let Some(&id) = string_cache.get(s) { + return id + } + } + + let mut string_cache = self.string_cache.write(); + // Check if the string has already been added in the small time window + // between dropping the read lock and acquiring the write lock. + *string_cache.entry(s).or_insert_with(|| self.profiler.alloc_string(s)) + } - StringId::reserved(discriminant as u32) + pub fn map_query_invocation_id_to_string( + &self, + from: QueryInvocationId, + to: StringId + ) { + let from = StringId::new_virtual(from.0); + self.profiler.map_virtual_to_concrete_string(from, to); } - pub fn register_query_name(&self, query_name: impl QueryName) { - let id = SelfProfiler::get_query_name_string_id(query_name); - self.profiler.alloc_string_with_reserved_id(id, query_name.as_str()); + pub fn bulk_map_query_invocation_id_to_single_string( + &self, + from: I, + to: StringId + ) + where I: Iterator + ExactSizeIterator + { + let from = from.map(|qid| StringId::new_virtual(qid.0)); + self.profiler.bulk_map_virtual_to_single_concrete_string(from, to); } } @@ -343,6 +464,14 @@ impl<'a> TimingGuard<'a> { TimingGuard(Some(timing_guard)) } + #[inline] + pub fn finish_with_query_invocation_id(self, query_invocation_id: QueryInvocationId) { + if let Some(guard) = self.0 { + let event_id = StringId::new_virtual(query_invocation_id.0); + guard.finish_with_override_event_id(event_id); + } + } + #[inline] pub fn none() -> TimingGuard<'a> { TimingGuard(None) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index c15dc2fe704b9..8e381a27b414f 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -71,10 +71,6 @@ pub fn create_session( lint_caps, ); - sess.prof.register_queries(|profiler| { - rustc::ty::query::QueryName::register_with_profiler(&profiler); - }); - let codegen_backend = get_codegen_backend(&sess); let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); From 996511a45655e452ec3132094e08dcbebee36a67 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 13 Dec 2019 14:46:10 +0100 Subject: [PATCH 0168/1253] Use 'relaxed' memory ordering for simple atomic counters in dep-graph. --- src/librustc/dep_graph/graph.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0616f00b8c472..0148997ca9ee7 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -497,8 +497,8 @@ impl DepGraph { let current_dep_graph = &self.data.as_ref().unwrap().current; Some(( - current_dep_graph.total_read_count.load(SeqCst), - current_dep_graph.total_duplicate_read_count.load(SeqCst), + current_dep_graph.total_read_count.load(Relaxed), + current_dep_graph.total_duplicate_read_count.load(Relaxed), )) } else { None @@ -1111,7 +1111,7 @@ impl DepGraphData { if let Some(task_deps) = icx.task_deps { let mut task_deps = task_deps.lock(); if cfg!(debug_assertions) { - self.current.total_read_count.fetch_add(1, SeqCst); + self.current.total_read_count.fetch_add(1, Relaxed); } if task_deps.read_set.insert(source) { task_deps.reads.push(source); @@ -1129,7 +1129,7 @@ impl DepGraphData { } } } else if cfg!(debug_assertions) { - self.current.total_duplicate_read_count.fetch_add(1, SeqCst); + self.current.total_duplicate_read_count.fetch_add(1, Relaxed); } } }) From b8ead417a6c2c6befff26f05393a4c213bf4a66c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 17 Dec 2019 14:44:07 +0100 Subject: [PATCH 0169/1253] Initial support for recording query keys in self-profiling data. --- Cargo.lock | 4 +- src/librustc/Cargo.toml | 2 +- src/librustc/dep_graph/graph.rs | 2 +- src/librustc/ty/query/mod.rs | 3 + src/librustc/ty/query/plumbing.rs | 65 +++-- src/librustc/ty/query/profiling_support.rs | 276 +++++++++++++++++++++ src/librustc_codegen_ssa/base.rs | 6 +- src/librustc_data_structures/Cargo.toml | 2 +- src/librustc_data_structures/profiling.rs | 46 +++- 9 files changed, 354 insertions(+), 52 deletions(-) create mode 100644 src/librustc/ty/query/profiling_support.rs diff --git a/Cargo.lock b/Cargo.lock index 96f37457a0e05..71c4faae9bf77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,9 +1995,9 @@ dependencies = [ [[package]] name = "measureme" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36dcc09c1a633097649f7d48bde3d8a61d2a43c01ce75525e31fbbc82c0fccf4" +checksum = "ebefdcb02b2ddeee50178a218aeaf6d752d0777cd07914542f202cb7440e6e38" dependencies = [ "byteorder", "memmap", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 567dc85213ab6..b9207cd36ff38 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -36,6 +36,6 @@ parking_lot = "0.9" byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -measureme = "0.6.0" +measureme = "0.7.0" rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0148997ca9ee7..f41653e9eaae0 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -30,7 +30,7 @@ pub struct DepGraph { /// This field is used for assigning DepNodeIndices when running in /// non-incremental mode. Even in non-incremental mode we make sure that - /// each task as a `DepNodeIndex` that uniquely identifies it. This unique + /// each task has a `DepNodeIndex` that uniquely identifies it. This unique /// ID is used for self-profiling. virtual_dep_node_index: Lrc, } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index b163d23e2394b..6b272ab3d4a9b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -81,6 +81,9 @@ pub(crate) use self::config::QueryDescription; mod on_disk_cache; pub use self::on_disk_cache::OnDiskCache; +mod profiling_support; +pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder}; + // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 5792995826781..76425f589f70a 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -701,42 +701,6 @@ macro_rules! define_queries_inner { } } - /// All self-profiling events generated by the query engine use a - /// virtual `StringId`s for their `event_id`. This method makes all - /// those virtual `StringId`s point to actual strings. - /// - /// If we are recording only summary data, the ids will point to - /// just the query names. If we are recording query keys too, we - /// allocate the corresponding strings here. (The latter is not yet - /// implemented.) - pub fn allocate_self_profile_query_strings( - &self, - profiler: &rustc_data_structures::profiling::SelfProfiler - ) { - // Walk the entire query cache and allocate the appropriate - // string representation. Each cache entry is uniquely - // identified by its dep_node_index. - $({ - let query_name_string_id = - profiler.get_or_alloc_cached_string(stringify!($name)); - - let result_cache = self.$name.lock_shards(); - - for shard in result_cache.iter() { - let query_invocation_ids = shard - .results - .values() - .map(|v| v.index) - .map(|dep_node_index| dep_node_index.into()); - - profiler.bulk_map_query_invocation_id_to_single_string( - query_invocation_ids, - query_name_string_id - ); - } - })* - } - #[cfg(parallel_compiler)] pub fn collect_active_jobs(&self) -> Vec>> { let mut jobs = Vec::new(); @@ -1040,6 +1004,35 @@ macro_rules! define_queries_inner { pub fn $name(self, key: $K) -> $V { self.at(DUMMY_SP).$name(key) })* + + /// All self-profiling events generated by the query engine use + /// virtual `StringId`s for their `event_id`. This method makes all + /// those virtual `StringId`s point to actual strings. + /// + /// If we are recording only summary data, the ids will point to + /// just the query names. If we are recording query keys too, we + /// allocate the corresponding strings here. + pub fn alloc_self_profile_query_strings(self) { + use crate::ty::query::profiling_support::{ + alloc_self_profile_query_strings_for_query_cache, + QueryKeyStringCache, + }; + + if !self.prof.enabled() { + return; + } + + let mut string_cache = QueryKeyStringCache::new(); + + $({ + alloc_self_profile_query_strings_for_query_cache( + self, + stringify!($name), + &self.queries.$name, + &mut string_cache, + ); + })* + } } impl TyCtxtAt<$tcx> { diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs new file mode 100644 index 0000000000000..ef30bd63be01c --- /dev/null +++ b/src/librustc/ty/query/profiling_support.rs @@ -0,0 +1,276 @@ + +use crate::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, DefIndex, LOCAL_CRATE}; +use crate::hir::map::definitions::DefPathData; +use crate::ty::context::TyCtxt; +use crate::ty::query::config::QueryConfig; +use crate::ty::query::plumbing::QueryCache; +use measureme::{StringId, StringComponent}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::profiling::SelfProfiler; +use rustc_data_structures::sharded::Sharded; +use std::fmt::Debug; +use std::io::Write; + +pub struct QueryKeyStringCache { + def_id_cache: FxHashMap, +} + +impl QueryKeyStringCache { + pub fn new() -> QueryKeyStringCache { + QueryKeyStringCache { + def_id_cache: Default::default(), + } + } +} + +pub struct QueryKeyStringBuilder<'p, 'c, 'tcx> { + profiler: &'p SelfProfiler, + tcx: TyCtxt<'tcx>, + string_cache: &'c mut QueryKeyStringCache, +} + +impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { + + pub fn new( + profiler: &'p SelfProfiler, + tcx: TyCtxt<'tcx>, + string_cache: &'c mut QueryKeyStringCache, + ) -> QueryKeyStringBuilder<'p, 'c, 'tcx> { + QueryKeyStringBuilder { + profiler, + tcx, + string_cache, + } + } + + // The current implementation is rather crude. In the future it might be a + // good idea to base this on `ty::print` in order to get nicer and more + // efficient query keys. + fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId { + + if let Some(&string_id) = self.string_cache.def_id_cache.get(&def_id) { + return string_id; + } + + let def_key = self.tcx.def_key(def_id); + + let (parent_string_id, start_index) = match def_key.parent { + Some(parent_index) => { + let parent_def_id = DefId { + index: parent_index, + krate: def_id.krate, + }; + + (self.def_id_to_string_id(parent_def_id), 0) + } + None => { + (StringId::INVALID, 2) + } + }; + + let dis_buffer = &mut [0u8; 16]; + let name; + let dis; + let end_index; + + match def_key.disambiguated_data.data { + DefPathData::CrateRoot => { + name = self.tcx.original_crate_name(def_id.krate).as_str(); + dis = ""; + end_index = 3; + } + other => { + name = other.as_symbol().as_str(); + if def_key.disambiguated_data.disambiguator == 0 { + dis = ""; + end_index = 3; + } else { + write!(&mut dis_buffer[..], + "[{}]", + def_key.disambiguated_data.disambiguator + ).unwrap(); + let end_of_dis = dis_buffer.iter().position(|&c| c == b']').unwrap(); + dis = std::str::from_utf8(&dis_buffer[.. end_of_dis + 1]).unwrap(); + end_index = 4; + } + } + } + + let components = [ + StringComponent::Ref(parent_string_id), + StringComponent::Value("::"), + StringComponent::Value(&name[..]), + StringComponent::Value(dis) + ]; + + let string_id = self.profiler.alloc_string( + &components[start_index .. end_index] + ); + + self.string_cache.def_id_cache.insert(def_id, string_id); + + string_id + } +} + +pub trait IntoSelfProfilingString { + fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId; +} + +// The default implementation of `IntoSelfProfilingString` just uses `Debug` +// which is slow and causes lots of duplication of string data. +// The specialized impls below take care of making the `DefId` case more +// efficient. +impl IntoSelfProfilingString for T { + + default fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId { + let s = format!("{:?}", self); + builder.profiler.alloc_string(&s[..]) + } +} + +impl IntoSelfProfilingString for DefId { + + fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId { + builder.def_id_to_string_id(*self) + } +} + +impl IntoSelfProfilingString for CrateNum { + + fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId { + builder.def_id_to_string_id(DefId { + krate: *self, + index: CRATE_DEF_INDEX, + }) + } +} + +impl IntoSelfProfilingString for DefIndex { + + fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId { + builder.def_id_to_string_id(DefId { + krate: LOCAL_CRATE, + index: *self, + }) + } +} + +impl IntoSelfProfilingString for (T0, T1) + where T0: IntoSelfProfilingString+Debug, + T1: IntoSelfProfilingString+Debug, +{ + default fn to_self_profile_string( + &self, + builder: &mut QueryKeyStringBuilder<'_, '_, '_> + ) -> StringId { + + let val0 = self.0.to_self_profile_string(builder); + let val1 = self.1.to_self_profile_string(builder); + + let components = &[ + StringComponent::Value("("), + StringComponent::Ref(val0), + StringComponent::Value(","), + StringComponent::Ref(val1), + StringComponent::Value(")"), + ]; + + builder.profiler.alloc_string(components) + } +} + +/// Allocate the self-profiling query strings for a single query cache. This +/// method is called from `alloc_self_profile_query_strings` which knows all +/// the queries via macro magic. +pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( + tcx: TyCtxt<'tcx>, + query_name: &'static str, + query_cache: &Sharded>, + string_cache: &mut QueryKeyStringCache, +) where Q: QueryConfig<'tcx> { + tcx.prof.with_profiler(|profiler| { + let event_id_builder = profiler.event_id_builder(); + + // Walk the entire query cache and allocate the appropriate + // string representations. Each cache entry is uniquely + // identified by its dep_node_index. + if profiler.query_key_recording_enabled() { + let mut query_string_builder = + QueryKeyStringBuilder::new(profiler, tcx, string_cache); + + let query_name = profiler.get_or_alloc_cached_string(query_name); + + // Since building the string representation of query keys might + // need to invoke queries itself, we cannot keep the query caches + // locked while doing so. Instead we copy out the + // `(query_key, dep_node_index)` pairs and release the lock again. + let query_keys_and_indices = { + let shards = query_cache.lock_shards(); + let len = shards.iter().map(|shard| shard.results.len()).sum(); + + let mut query_keys_and_indices = Vec::with_capacity(len); + + for shard in &shards { + query_keys_and_indices.extend(shard.results.iter().map(|(q_key, q_val)| { + (q_key.clone(), q_val.index) + })); + } + + query_keys_and_indices + }; + + // Now actually allocate the strings. If allocating the strings + // generates new entries in the query cache, we'll miss them but + // we don't actually care. + for (query_key, dep_node_index) in query_keys_and_indices { + // Translate the DepNodeIndex into a QueryInvocationId + let query_invocation_id = dep_node_index.into(); + + // Create the string version of the query-key + let query_key = query_key.to_self_profile_string(&mut query_string_builder); + let event_id = event_id_builder.from_label_and_arg(query_name, query_key); + + // Doing this in bulk might be a good idea: + profiler.map_query_invocation_id_to_string( + query_invocation_id, + event_id.to_string_id(), + ); + } + } else { + // In this branch we don't allocate query keys + let query_name = profiler.get_or_alloc_cached_string(query_name); + let event_id = event_id_builder.from_label(query_name).to_string_id(); + + let shards = query_cache.lock_shards(); + + for shard in shards.iter() { + let query_invocation_ids = shard + .results + .values() + .map(|v| v.index) + .map(|dep_node_index| dep_node_index.into()); + + profiler.bulk_map_query_invocation_id_to_single_string( + query_invocation_ids, + event_id, + ); + } + } + }); +} diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 8087db9fabc2f..857aa9c1bcc2e 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -722,10 +722,10 @@ fn finalize_tcx(tcx: TyCtxt<'_>) { // We assume that no queries are run past here. If there are new queries // after this point, they'll show up as "" in self-profiling data. - tcx.prof.with_profiler(|profiler| { + { let _prof_timer = tcx.prof.generic_activity("self_profile_alloc_query_strings"); - tcx.queries.allocate_self_profile_query_strings(profiler); - }); + tcx.alloc_self_profile_query_strings(); + } } impl CrateInfo { diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 9c42f3633f2c0..d6ca11364ea96 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -26,7 +26,7 @@ rustc-hash = "1.0.1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_index = { path = "../librustc_index", package = "rustc_index" } bitflags = "1.2.1" -measureme = "0.6.0" +measureme = "0.7.0" [dependencies.parking_lot] version = "0.9" diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index db56023560a0d..066a6727bb49d 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -39,7 +39,7 @@ //! ## `event_id` Assignment //! //! As far as `measureme` is concerned, `event_id`s are just strings. However, -//! it would incur way too much overhead to generate and persist each `event_id` +//! it would incur too much overhead to generate and persist each `event_id` //! string at the point where the event is recorded. In order to make this more //! efficient `measureme` has two features: //! @@ -56,7 +56,7 @@ //! ID be mapped to an actual string. This is used to cheaply generate //! `event_id`s while the events actually occur, causing little timing //! distortion, and then later map those `StringId`s, in bulk, to actual -//! `event_id` strings. This way the largest part of tracing overhead is +//! `event_id` strings. This way the largest part of the tracing overhead is //! localized to one contiguous chunk of time. //! //! How are these `event_id`s generated in the compiler? For things that occur @@ -92,7 +92,7 @@ use std::thread::ThreadId; use std::time::{Duration, Instant}; use std::u32; -use measureme::StringId; +use measureme::{EventId, EventIdBuilder, SerializableString, StringId}; use parking_lot::RwLock; /// MmapSerializatioSink is faster on macOS and Linux @@ -123,6 +123,8 @@ bitflags::bitflags! { const QUERY_BLOCKED = 1 << 3; const INCR_CACHE_LOADS = 1 << 4; + const QUERY_KEYS = 1 << 5; + const DEFAULT = Self::GENERIC_ACTIVITIES.bits | Self::QUERY_PROVIDERS.bits | Self::QUERY_BLOCKED.bits | @@ -142,6 +144,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("query-cache-hit", EventFilter::QUERY_CACHE_HITS), ("query-blocked", EventFilter::QUERY_BLOCKED), ("incr-cache-load", EventFilter::INCR_CACHE_LOADS), + ("query-keys", EventFilter::QUERY_KEYS), ]; fn thread_id_to_u32(tid: ThreadId) -> u32 { @@ -253,6 +256,7 @@ impl SelfProfilerRef { pub fn generic_activity(&self, event_id: &'static str) -> TimingGuard<'_> { self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| { let event_id = profiler.get_or_alloc_cached_string(event_id); + let event_id = EventId::from_label(event_id); TimingGuard::start( profiler, profiler.generic_activity_event_kind, @@ -266,7 +270,7 @@ impl SelfProfilerRef { #[inline(always)] pub fn query_provider(&self) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_PROVIDERS, |profiler| { - TimingGuard::start(profiler, profiler.query_event_kind, StringId::INVALID) + TimingGuard::start(profiler, profiler.query_event_kind, EventId::INVALID) }) } @@ -289,7 +293,7 @@ impl SelfProfilerRef { TimingGuard::start( profiler, profiler.query_blocked_event_kind, - StringId::INVALID, + EventId::INVALID, ) }) } @@ -303,7 +307,7 @@ impl SelfProfilerRef { TimingGuard::start( profiler, profiler.incremental_load_result_event_kind, - StringId::INVALID, + EventId::INVALID, ) }) } @@ -319,7 +323,11 @@ impl SelfProfilerRef { let event_id = StringId::new_virtual(query_invocation_id.0); let thread_id = thread_id_to_u32(std::thread::current().id()); - profiler.profiler.record_instant_event(event_kind(profiler), event_id, thread_id); + profiler.profiler.record_instant_event( + event_kind(profiler), + EventId::from_virtual(event_id), + thread_id, + ); TimingGuard::none() })); @@ -330,6 +338,10 @@ impl SelfProfilerRef { f(&profiler) } } + + pub fn enabled(&self) -> bool { + self.profiler.is_some() + } } pub struct SelfProfiler { @@ -409,6 +421,15 @@ impl SelfProfiler { }) } + /// Allocates a new string in the profiling data. Does not do any caching + /// or deduplication. + pub fn alloc_string(&self, s: &STR) -> StringId { + self.profiler.alloc_string(s) + } + + /// Gets a `StringId` for the given string. This method makes sure that + /// any strings going through it will only be allocated once in the + /// profiling data. pub fn get_or_alloc_cached_string(&self, s: &'static str) -> StringId { // Only acquire a read-lock first since we assume that the string is // already present in the common case. @@ -445,6 +466,14 @@ impl SelfProfiler { let from = from.map(|qid| StringId::new_virtual(qid.0)); self.profiler.bulk_map_virtual_to_single_concrete_string(from, to); } + + pub fn query_key_recording_enabled(&self) -> bool { + self.event_filter_mask.contains(EventFilter::QUERY_KEYS) + } + + pub fn event_id_builder(&self) -> EventIdBuilder<'_, SerializationSink> { + EventIdBuilder::new(&self.profiler) + } } #[must_use] @@ -455,7 +484,7 @@ impl<'a> TimingGuard<'a> { pub fn start( profiler: &'a SelfProfiler, event_kind: StringId, - event_id: StringId, + event_id: EventId, ) -> TimingGuard<'a> { let thread_id = thread_id_to_u32(std::thread::current().id()); let raw_profiler = &profiler.profiler; @@ -468,6 +497,7 @@ impl<'a> TimingGuard<'a> { pub fn finish_with_query_invocation_id(self, query_invocation_id: QueryInvocationId) { if let Some(guard) = self.0 { let event_id = StringId::new_virtual(query_invocation_id.0); + let event_id = EventId::from_virtual(event_id); guard.finish_with_override_event_id(event_id); } } From 6848ed2d6504d17bdd0c494b5fbe4841b1d21057 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 18 Dec 2019 16:39:06 +0100 Subject: [PATCH 0170/1253] self-profile: Fix issue with handling query blocking. --- src/librustc/ty/query/plumbing.rs | 37 ++++++++++++++++------ src/librustc/ty/query/profiling_support.rs | 1 - src/librustc_data_structures/profiling.rs | 1 + 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 76425f589f70a..33f2a5e3ffa75 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -13,6 +13,8 @@ use errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, Handler #[cfg(not(parallel_compiler))] use rustc_data_structures::cold_path; use rustc_data_structures::fx::{FxHashMap, FxHasher}; +#[cfg(parallel_compiler)] +use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::thin_vec::ThinVec; @@ -82,6 +84,19 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { /// for some compile-time benchmarks. #[inline(always)] pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> { + // Handling the `query_blocked_prof_timer` is a bit weird because of the + // control flow in this function: Blocking is implemented by + // awaiting a running job and, once that is done, entering the loop below + // again from the top. In that second iteration we will hit the + // cache which provides us with the information we need for + // finishing the "query-blocked" event. + // + // We thus allocate `query_blocked_prof_timer` outside the loop, + // initialize it during the first iteration and finish it during the + // second iteration. + #[cfg(parallel_compiler)] + let mut query_blocked_prof_timer: Option> = None; + let cache = Q::query_cache(tcx); loop { // We compute the key's hash once and then use it for both the @@ -95,7 +110,17 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { if let Some((_, value)) = lock.results.raw_entry().from_key_hashed_nocheck(key_hash, key) { - tcx.prof.query_cache_hit(value.index.into()); + if unlikely!(tcx.prof.enabled()) { + tcx.prof.query_cache_hit(value.index.into()); + + #[cfg(parallel_compiler)] + { + if let Some(prof_timer) = query_blocked_prof_timer.take() { + prof_timer.finish_with_query_invocation_id(value.index.into()); + } + } + } + let result = (value.value.clone(), value.index); #[cfg(debug_assertions)] { @@ -104,9 +129,6 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { return TryGetJob::JobCompleted(result); } - #[cfg(parallel_compiler)] - let query_blocked_prof_timer; - let job = match lock.active.entry((*key).clone()) { Entry::Occupied(entry) => { match *entry.get() { @@ -116,7 +138,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { // self-profiler. #[cfg(parallel_compiler)] { - query_blocked_prof_timer = tcx.prof.query_blocked(Q::NAME); + query_blocked_prof_timer = Some(tcx.prof.query_blocked()); } job.clone() @@ -153,11 +175,6 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { { let result = job.r#await(tcx, span); - // This `drop()` is not strictly necessary as the binding - // would go out of scope anyway. But it's good to have an - // explicit marker of how far the measurement goes. - drop(query_blocked_prof_timer); - if let Err(cycle) = result { return TryGetJob::Cycle(Q::handle_cycle_error(tcx, cycle)); } diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index ef30bd63be01c..ff280ffeb7882 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -1,4 +1,3 @@ - use crate::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, DefIndex, LOCAL_CRATE}; use crate::hir::map::definitions::DefPathData; use crate::ty::context::TyCtxt; diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 066a6727bb49d..7774cb86c5c91 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -339,6 +339,7 @@ impl SelfProfilerRef { } } + #[inline] pub fn enabled(&self) -> bool { self.profiler.is_some() } From 83e921d7707891bc68fd9728245f3c975a2a0f98 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 3 Jan 2020 11:49:14 +0100 Subject: [PATCH 0171/1253] Run 'x.py fmt'. --- src/librustc/dep_graph/graph.rs | 12 +-- src/librustc/ty/query/profiling_support.rs | 102 +++++++-------------- src/librustc_data_structures/profiling.rs | 29 ++---- 3 files changed, 42 insertions(+), 101 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index f41653e9eaae0..625aa25978e6e 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -2,18 +2,17 @@ use crate::ty::{self, TyCtxt}; use errors::Diagnostic; use parking_lot::{Condvar, Mutex}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::profiling::QueryInvocationId; use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::collections::hash_map::Entry; -use rustc_data_structures::profiling::QueryInvocationId; -use std::sync::atomic::Ordering::Relaxed; use std::env; use std::hash::Hash; use std::mem; -use std::sync::atomic::Ordering::SeqCst; +use std::sync::atomic::Ordering::Relaxed; use crate::ich::{Fingerprint, StableHashingContext, StableHashingContextProvider}; @@ -46,7 +45,7 @@ impl DepNodeIndex { impl std::convert::From for QueryInvocationId { #[inline] fn from(dep_node_index: DepNodeIndex) -> Self { - QueryInvocationId(dep_node_index.as_u32()) + QueryInvocationId(dep_node_index.as_u32()) } } @@ -125,10 +124,7 @@ impl DepGraph { } pub fn new_disabled() -> DepGraph { - DepGraph { - data: None, - virtual_dep_node_index: Lrc::new(AtomicU32::new(0)), - } + DepGraph { data: None, virtual_dep_node_index: Lrc::new(AtomicU32::new(0)) } } /// Returns `true` if we are actually building the full dep-graph, and `false` otherwise. diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index ff280ffeb7882..3a363c3f824cf 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -1,9 +1,9 @@ -use crate::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, DefIndex, LOCAL_CRATE}; +use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir::map::definitions::DefPathData; use crate::ty::context::TyCtxt; use crate::ty::query::config::QueryConfig; use crate::ty::query::plumbing::QueryCache; -use measureme::{StringId, StringComponent}; +use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; use rustc_data_structures::sharded::Sharded; @@ -16,9 +16,7 @@ pub struct QueryKeyStringCache { impl QueryKeyStringCache { pub fn new() -> QueryKeyStringCache { - QueryKeyStringCache { - def_id_cache: Default::default(), - } + QueryKeyStringCache { def_id_cache: Default::default() } } } @@ -29,24 +27,18 @@ pub struct QueryKeyStringBuilder<'p, 'c, 'tcx> { } impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { - pub fn new( profiler: &'p SelfProfiler, tcx: TyCtxt<'tcx>, string_cache: &'c mut QueryKeyStringCache, ) -> QueryKeyStringBuilder<'p, 'c, 'tcx> { - QueryKeyStringBuilder { - profiler, - tcx, - string_cache, - } + QueryKeyStringBuilder { profiler, tcx, string_cache } } // The current implementation is rather crude. In the future it might be a // good idea to base this on `ty::print` in order to get nicer and more // efficient query keys. fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId { - if let Some(&string_id) = self.string_cache.def_id_cache.get(&def_id) { return string_id; } @@ -55,16 +47,11 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { let (parent_string_id, start_index) = match def_key.parent { Some(parent_index) => { - let parent_def_id = DefId { - index: parent_index, - krate: def_id.krate, - }; + let parent_def_id = DefId { index: parent_index, krate: def_id.krate }; (self.def_id_to_string_id(parent_def_id), 0) } - None => { - (StringId::INVALID, 2) - } + None => (StringId::INVALID, 2), }; let dis_buffer = &mut [0u8; 16]; @@ -84,12 +71,10 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { dis = ""; end_index = 3; } else { - write!(&mut dis_buffer[..], - "[{}]", - def_key.disambiguated_data.disambiguator - ).unwrap(); + write!(&mut dis_buffer[..], "[{}]", def_key.disambiguated_data.disambiguator) + .unwrap(); let end_of_dis = dis_buffer.iter().position(|&c| c == b']').unwrap(); - dis = std::str::from_utf8(&dis_buffer[.. end_of_dis + 1]).unwrap(); + dis = std::str::from_utf8(&dis_buffer[..end_of_dis + 1]).unwrap(); end_index = 4; } } @@ -99,12 +84,10 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { StringComponent::Ref(parent_string_id), StringComponent::Value("::"), StringComponent::Value(&name[..]), - StringComponent::Value(dis) + StringComponent::Value(dis), ]; - let string_id = self.profiler.alloc_string( - &components[start_index .. end_index] - ); + let string_id = self.profiler.alloc_string(&components[start_index..end_index]); self.string_cache.def_id_cache.insert(def_id, string_id); @@ -113,10 +96,7 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { } pub trait IntoSelfProfilingString { - fn to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> - ) -> StringId; + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId; } // The default implementation of `IntoSelfProfilingString` just uses `Debug` @@ -124,10 +104,9 @@ pub trait IntoSelfProfilingString { // The specialized impls below take care of making the `DefId` case more // efficient. impl IntoSelfProfilingString for T { - default fn to_self_profile_string( &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> + builder: &mut QueryKeyStringBuilder<'_, '_, '_>, ) -> StringId { let s = format!("{:?}", self); builder.profiler.alloc_string(&s[..]) @@ -135,50 +114,32 @@ impl IntoSelfProfilingString for T { } impl IntoSelfProfilingString for DefId { - - fn to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> - ) -> StringId { + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { builder.def_id_to_string_id(*self) } } impl IntoSelfProfilingString for CrateNum { - - fn to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> - ) -> StringId { - builder.def_id_to_string_id(DefId { - krate: *self, - index: CRATE_DEF_INDEX, - }) + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { + builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX }) } } impl IntoSelfProfilingString for DefIndex { - - fn to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> - ) -> StringId { - builder.def_id_to_string_id(DefId { - krate: LOCAL_CRATE, - index: *self, - }) + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { + builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: *self }) } } impl IntoSelfProfilingString for (T0, T1) - where T0: IntoSelfProfilingString+Debug, - T1: IntoSelfProfilingString+Debug, +where + T0: IntoSelfProfilingString + Debug, + T1: IntoSelfProfilingString + Debug, { default fn to_self_profile_string( &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_> + builder: &mut QueryKeyStringBuilder<'_, '_, '_>, ) -> StringId { - let val0 = self.0.to_self_profile_string(builder); let val1 = self.1.to_self_profile_string(builder); @@ -202,7 +163,9 @@ pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( query_name: &'static str, query_cache: &Sharded>, string_cache: &mut QueryKeyStringCache, -) where Q: QueryConfig<'tcx> { +) where + Q: QueryConfig<'tcx>, +{ tcx.prof.with_profiler(|profiler| { let event_id_builder = profiler.event_id_builder(); @@ -210,8 +173,7 @@ pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( // string representations. Each cache entry is uniquely // identified by its dep_node_index. if profiler.query_key_recording_enabled() { - let mut query_string_builder = - QueryKeyStringBuilder::new(profiler, tcx, string_cache); + let mut query_string_builder = QueryKeyStringBuilder::new(profiler, tcx, string_cache); let query_name = profiler.get_or_alloc_cached_string(query_name); @@ -226,9 +188,9 @@ pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( let mut query_keys_and_indices = Vec::with_capacity(len); for shard in &shards { - query_keys_and_indices.extend(shard.results.iter().map(|(q_key, q_val)| { - (q_key.clone(), q_val.index) - })); + query_keys_and_indices.extend( + shard.results.iter().map(|(q_key, q_val)| (q_key.clone(), q_val.index)), + ); } query_keys_and_indices @@ -265,10 +227,8 @@ pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( .map(|v| v.index) .map(|dep_node_index| dep_node_index.into()); - profiler.bulk_map_query_invocation_id_to_single_string( - query_invocation_ids, - event_id, - ); + profiler + .bulk_map_query_invocation_id_to_single_string(query_invocation_ids, event_id); } } }); diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 7774cb86c5c91..93f8b943224a2 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -257,11 +257,7 @@ impl SelfProfilerRef { self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| { let event_id = profiler.get_or_alloc_cached_string(event_id); let event_id = EventId::from_label(event_id); - TimingGuard::start( - profiler, - profiler.generic_activity_event_kind, - event_id - ) + TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id) }) } @@ -290,11 +286,7 @@ impl SelfProfilerRef { #[inline(always)] pub fn query_blocked(&self) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_BLOCKED, |profiler| { - TimingGuard::start( - profiler, - profiler.query_blocked_event_kind, - EventId::INVALID, - ) + TimingGuard::start(profiler, profiler.query_blocked_event_kind, EventId::INVALID) }) } @@ -438,7 +430,7 @@ impl SelfProfiler { let string_cache = self.string_cache.read(); if let Some(&id) = string_cache.get(s) { - return id + return id; } } @@ -448,21 +440,14 @@ impl SelfProfiler { *string_cache.entry(s).or_insert_with(|| self.profiler.alloc_string(s)) } - pub fn map_query_invocation_id_to_string( - &self, - from: QueryInvocationId, - to: StringId - ) { + pub fn map_query_invocation_id_to_string(&self, from: QueryInvocationId, to: StringId) { let from = StringId::new_virtual(from.0); self.profiler.map_virtual_to_concrete_string(from, to); } - pub fn bulk_map_query_invocation_id_to_single_string( - &self, - from: I, - to: StringId - ) - where I: Iterator + ExactSizeIterator + pub fn bulk_map_query_invocation_id_to_single_string(&self, from: I, to: StringId) + where + I: Iterator + ExactSizeIterator, { let from = from.map(|qid| StringId::new_virtual(qid.0)); self.profiler.bulk_map_virtual_to_single_concrete_string(from, to); From 11e4844480230f42f59377629bb72cbc649b4a48 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 3 Jan 2020 12:01:53 +0100 Subject: [PATCH 0172/1253] Update measureme to 0.7.1 in order to fix compilation error on big-endian platforms. --- Cargo.lock | 4 ++-- src/librustc/Cargo.toml | 2 +- src/librustc_data_structures/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71c4faae9bf77..044e14971a35f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,9 +1995,9 @@ dependencies = [ [[package]] name = "measureme" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebefdcb02b2ddeee50178a218aeaf6d752d0777cd07914542f202cb7440e6e38" +checksum = "fef709d3257013bba7cff14fc504e07e80631d3fe0f6d38ce63b8f6510ccb932" dependencies = [ "byteorder", "memmap", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index b9207cd36ff38..bca960202316c 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -36,6 +36,6 @@ parking_lot = "0.9" byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -measureme = "0.7.0" +measureme = "0.7.1" rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index d6ca11364ea96..19db9834fd48e 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -26,7 +26,7 @@ rustc-hash = "1.0.1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_index = { path = "../librustc_index", package = "rustc_index" } bitflags = "1.2.1" -measureme = "0.7.0" +measureme = "0.7.1" [dependencies.parking_lot] version = "0.9" From ad65e3e6bc8ded92db38507b84ec4a2bf2677d62 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 10 Jan 2020 10:32:16 +0100 Subject: [PATCH 0173/1253] Fix some rebasing fallout. --- Cargo.lock | 1 + src/librustc/ty/query/profiling_support.rs | 2 +- src/librustc_codegen_ssa/base.rs | 12 ++---------- src/librustc_data_structures/profiling.rs | 9 ++++++--- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 044e14971a35f..bbe014baa498b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3079,6 +3079,7 @@ dependencies = [ "graphviz", "jobserver", "log", + "measureme", "parking_lot", "polonius-engine", "rustc-rayon", diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index 3a363c3f824cf..79b32ba83aea0 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -1,4 +1,3 @@ -use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir::map::definitions::DefPathData; use crate::ty::context::TyCtxt; use crate::ty::query::config::QueryConfig; @@ -7,6 +6,7 @@ use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; use rustc_data_structures::sharded::Sharded; +use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use std::fmt::Debug; use std::io::Write; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 857aa9c1bcc2e..9b9434539a8e5 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -334,11 +334,7 @@ pub fn from_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, val: Bx::Value, ) -> Bx::Value { - if bx.cx().val_ty(val) == bx.cx().type_i1() { - bx.zext(val, bx.cx().type_i8()) - } else { - val - } + if bx.cx().val_ty(val) == bx.cx().type_i1() { bx.zext(val, bx.cx().type_i8()) } else { val } } pub fn to_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( @@ -887,11 +883,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { // We can re-use either the pre- or the post-thinlto state - if tcx.sess.lto() != Lto::No { - CguReuse::PreLto - } else { - CguReuse::PostLto - } + if tcx.sess.lto() != Lto::No { CguReuse::PreLto } else { CguReuse::PostLto } } else { CguReuse::No } diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 93f8b943224a2..e8a70d58f0cff 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -224,7 +224,10 @@ impl SelfProfilerRef { /// a measureme event, "verbose" generic activities also print a timing entry to /// stdout if the compiler is invoked with -Ztime or -Ztime-passes. #[inline(always)] - pub fn verbose_generic_activity<'a>(&'a self, event_id: &'a str) -> VerboseTimingGuard<'a> { + pub fn verbose_generic_activity<'a>( + &'a self, + event_id: &'static str, + ) -> VerboseTimingGuard<'a> { VerboseTimingGuard::start( event_id, self.print_verbose_generic_activities, @@ -589,8 +592,8 @@ fn get_resident() -> Option { cb: DWORD, ) -> BOOL; } - let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() }; - pmc.cb = mem::size_of_val(&pmc) as DWORD; + let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { std::mem::zeroed() }; + pmc.cb = std::mem::size_of_val(&pmc) as DWORD; match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } { 0 => None, _ => Some(pmc.WorkingSetSize as usize), From 0bbbd5d418f764146afdde3460c170db205ba0fa Mon Sep 17 00:00:00 2001 From: Matthew Healy Date: Thu, 9 Jan 2020 22:51:38 +0100 Subject: [PATCH 0174/1253] Match llvm-skip-rebuild flag --- src/bootstrap/flags.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 813e89eef38ce..1fbdd50a51133 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -38,6 +38,8 @@ pub struct Flags { // // true => deny, false => warn pub deny_warnings: Option, + + pub llvm_skip_rebuild: Option, } pub enum Subcommand { @@ -495,6 +497,9 @@ Arguments: .map(|p| p.into()) .collect::>(), deny_warnings: parse_deny_warnings(&matches), + llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map( + |s| s.parse::().expect("`llvm-skip-rebuild` should be either true or false"), + ), } } } From 7e50b599bfeb75f7be1d5a1fa855e37ec6d0e65d Mon Sep 17 00:00:00 2001 From: Matthew Healy Date: Thu, 9 Jan 2020 23:13:57 +0100 Subject: [PATCH 0175/1253] Prefer llvm-skip-rebuild flag value over config.toml --- src/bootstrap/config.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 944df66431fe8..110c8b844d54c 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -493,9 +493,13 @@ impl Config { config.mandir = install.mandir.clone().map(PathBuf::from); } + // We want the llvm-skip-rebuild flag to take precedence over the + // skip-rebuild config.toml option so we store it separately + // so that we can infer the right value + let mut llvm_skip_rebuild = flags.llvm_skip_rebuild; + // Store off these values as options because if they're not provided // we'll infer default values for them later - let mut llvm_skip_rebuild = None; let mut llvm_assertions = None; let mut debug = None; let mut debug_assertions = None; @@ -517,7 +521,7 @@ impl Config { } set(&mut config.ninja, llvm.ninja); llvm_assertions = llvm.assertions; - llvm_skip_rebuild = llvm.skip_rebuild; + llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild); set(&mut config.llvm_optimize, llvm.optimize); set(&mut config.llvm_thin_lto, llvm.thin_lto); set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); From cd9a73d2ea4ca9452e3471d7e6c04af14eb1c2ed Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 12:52:00 +0000 Subject: [PATCH 0176/1253] make use of pointer::is_null --- src/libpanic_unwind/emcc.rs | 2 +- src/libstd/sys/hermit/os.rs | 9 ++++++--- src/libstd/sys/hermit/thread_local.rs | 4 ++-- src/libstd/sys/sgx/abi/tls.rs | 2 +- src/libstd/sys/unix/os.rs | 10 ++++++---- src/libstd/sys/vxworks/os.rs | 7 +++---- src/libstd/sys/wasi/os.rs | 11 ++++++----- src/libstd/sys/windows/os.rs | 2 +- 8 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 2098404ee1b9d..9d3fe5254f8a9 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -63,7 +63,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box { pub unsafe fn panic(data: Box) -> u32 { let sz = mem::size_of_val(&data); let exception = __cxa_allocate_exception(sz); - if exception == ptr::null_mut() { + if exception.is_null() { return uw::_URC_FATAL_PHASE1_ERROR as u32; } ptr::write(exception as *mut _, data); diff --git a/src/libstd/sys/hermit/os.rs b/src/libstd/sys/hermit/os.rs index 5999fdd4f8d58..78eabf8f81e98 100644 --- a/src/libstd/sys/hermit/os.rs +++ b/src/libstd/sys/hermit/os.rs @@ -6,7 +6,6 @@ use crate::io; use crate::marker::PhantomData; use crate::memchr; use crate::path::{self, PathBuf}; -use crate::ptr; use crate::str; use crate::sync::Mutex; use crate::sys::hermit::abi; @@ -77,13 +76,17 @@ pub fn init_environment(env: *const *const i8) { unsafe { ENV = Some(Mutex::new(HashMap::new())); + if env.is_null() { + return; + } + let mut guard = ENV.as_ref().unwrap().lock().unwrap(); let mut environ = env; - while environ != ptr::null() && *environ != ptr::null() { + while !(*environ).is_null() { if let Some((key, value)) = parse(CStr::from_ptr(*environ).to_bytes()) { guard.insert(key, value); } - environ = environ.offset(1); + environ = environ.add(1); } } diff --git a/src/libstd/sys/hermit/thread_local.rs b/src/libstd/sys/hermit/thread_local.rs index ba967c7676c3f..c6f8adb21623a 100644 --- a/src/libstd/sys/hermit/thread_local.rs +++ b/src/libstd/sys/hermit/thread_local.rs @@ -18,14 +18,14 @@ static KEYS_LOCK: Mutex = Mutex::new(); static mut LOCALS: *mut BTreeMap = ptr::null_mut(); unsafe fn keys() -> &'static mut BTreeMap> { - if KEYS == ptr::null_mut() { + if KEYS.is_null() { KEYS = Box::into_raw(Box::new(BTreeMap::new())); } &mut *KEYS } unsafe fn locals() -> &'static mut BTreeMap { - if LOCALS == ptr::null_mut() { + if LOCALS.is_null() { LOCALS = Box::into_raw(Box::new(BTreeMap::new())); } &mut *LOCALS diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs index 81a766e367d6e..2b0485c4f0363 100644 --- a/src/libstd/sys/sgx/abi/tls.rs +++ b/src/libstd/sys/sgx/abi/tls.rs @@ -70,7 +70,7 @@ impl<'a> Drop for ActiveTls<'a> { any_non_null_dtor = false; for (value, dtor) in TLS_KEY_IN_USE.iter().filter_map(&value_with_destructor) { let value = value.replace(ptr::null_mut()); - if value != ptr::null_mut() { + if !value.is_null() { any_non_null_dtor = true; unsafe { dtor(value) } } diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index b277b3d5899b8..91f7d1524ccef 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -480,11 +480,13 @@ pub fn env() -> Env { let _guard = env_lock(); let mut environ = *environ(); let mut result = Vec::new(); - while environ != ptr::null() && *environ != ptr::null() { - if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { - result.push(key_value); + if !environ.is_null() { + while !(*environ).is_null() { + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } + environ = environ.add(1); } - environ = environ.offset(1); } return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; } diff --git a/src/libstd/sys/vxworks/os.rs b/src/libstd/sys/vxworks/os.rs index d421915449944..1fadf71613561 100644 --- a/src/libstd/sys/vxworks/os.rs +++ b/src/libstd/sys/vxworks/os.rs @@ -7,7 +7,6 @@ use crate::marker::PhantomData; use crate::mem; use crate::memchr; use crate::path::{self, Path, PathBuf}; -use crate::ptr; use crate::slice; use crate::str; use crate::sys::cvt; @@ -226,15 +225,15 @@ pub fn env() -> Env { unsafe { let _guard = env_lock(); let mut environ = *environ(); - if environ == ptr::null() { + if environ.is_null() { panic!("os::env() failure getting env string from OS: {}", io::Error::last_os_error()); } let mut result = Vec::new(); - while *environ != ptr::null() { + while !(*environ).is_null() { if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { result.push(key_value); } - environ = environ.offset(1); + environ = environ.add(1); } return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 3baec6bf09924..8052c0aa8a8d9 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -6,7 +6,6 @@ use crate::io; use crate::marker::PhantomData; use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; -use crate::ptr; use crate::str; use crate::sys::memchr; use crate::sys::{unsupported, Void}; @@ -107,11 +106,13 @@ pub fn env() -> Env { let _guard = env_lock(); let mut environ = libc::environ; let mut result = Vec::new(); - while environ != ptr::null_mut() && *environ != ptr::null_mut() { - if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { - result.push(key_value); + if !environ.is_null() { + while !(*environ).is_null() { + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } + environ = environ.add(1); } - environ = environ.offset(1); } return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; } diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index c5354671c9843..cc4ae40590693 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -43,7 +43,7 @@ pub fn error_string(mut errnum: i32) -> String { ]; module = c::GetModuleHandleW(NTDLL_DLL.as_ptr()); - if module != ptr::null_mut() { + if !module.is_null() { errnum ^= c::FACILITY_NT_BIT as i32; flags = c::FORMAT_MESSAGE_FROM_HMODULE; } From 8ca55641fd80ac51971997f903358fa579209d71 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 13:31:36 +0000 Subject: [PATCH 0177/1253] Clarify suggestion for E0013 --- src/librustc_mir/transform/check_consts/ops.rs | 12 +++++++----- .../ui/consts/const-fn-not-safe-for-const.stderr | 8 ++++++-- .../ui/issues/issue-17718-const-bad-values.stderr | 8 ++++++-- src/test/ui/issues/issue-17718-references.stderr | 12 +++++++++--- src/test/ui/issues/issue-18118-2.rs | 3 +-- src/test/ui/issues/issue-18118-2.stderr | 4 +++- src/test/ui/issues/issue-52060.stderr | 4 +++- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index abef008a8eccb..e418809282750 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -350,16 +350,18 @@ impl NonConstOp for StaticAccess { item.tcx.sess, span, E0013, - "{}s cannot refer to statics, use \ - a constant instead", + "{}s cannot refer to statics", item.const_kind() ); + err.help( + "consider extracting the value of the `static` to a `const`, and referring to that", + ); if item.tcx.sess.teach(&err.get_code().unwrap()) { err.note( - "Static and const variables can refer to other const variables. \ - But a const variable cannot refer to a static variable.", + "`static` and `const` variables can refer to other `const` variables. \ + A `const` variable, however, cannot refer to a `static` variable.", ); - err.help("To fix this, the value can be extracted as a const and then used."); + err.help("To fix this, the value can be extracted to a `const` and then used."); } err.emit(); } diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr index 2d4175ea8eb7d..df793d7dd7ec9 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr +++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr @@ -4,17 +4,21 @@ error[E0015]: calls in constant functions are limited to constant functions, tup LL | random() | ^^^^^^^^ -error[E0013]: constant functions cannot refer to statics, use a constant instead +error[E0013]: constant functions cannot refer to statics --> $DIR/const-fn-not-safe-for-const.rs:20:5 | LL | Y | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0013]: constant functions cannot refer to statics, use a constant instead +error[E0013]: constant functions cannot refer to statics --> $DIR/const-fn-not-safe-for-const.rs:25:6 | LL | &Y | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-17718-const-bad-values.stderr b/src/test/ui/issues/issue-17718-const-bad-values.stderr index 14bf5dc38b47a..e45d8b6c740e0 100644 --- a/src/test/ui/issues/issue-17718-const-bad-values.stderr +++ b/src/test/ui/issues/issue-17718-const-bad-values.stderr @@ -7,17 +7,21 @@ LL | const C1: &'static mut [usize] = &mut []; = note: for more information, see https://github.com/rust-lang/rust/issues/57349 = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-const-bad-values.rs:5:46 | LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-const-bad-values.rs:5:46 | LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0658]: references in constants may only refer to immutable values --> $DIR/issue-17718-const-bad-values.rs:5:41 diff --git a/src/test/ui/issues/issue-17718-references.stderr b/src/test/ui/issues/issue-17718-references.stderr index 27aad9c03cebe..e3c3b369ffb32 100644 --- a/src/test/ui/issues/issue-17718-references.stderr +++ b/src/test/ui/issues/issue-17718-references.stderr @@ -1,20 +1,26 @@ -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-references.rs:9:29 | LL | const T2: &'static usize = &S; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-references.rs:14:19 | LL | const T6: usize = S; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-references.rs:19:33 | LL | const T10: Struct = Struct { a: S }; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-18118-2.rs b/src/test/ui/issues/issue-18118-2.rs index 6d52156b3d2de..f712a2eedb7e9 100644 --- a/src/test/ui/issues/issue-18118-2.rs +++ b/src/test/ui/issues/issue-18118-2.rs @@ -1,7 +1,6 @@ pub fn main() { const z: &'static isize = { static p: isize = 3; - &p - //~^ ERROR constants cannot refer to statics, use a constant instead + &p //~ ERROR constants cannot refer to statics }; } diff --git a/src/test/ui/issues/issue-18118-2.stderr b/src/test/ui/issues/issue-18118-2.stderr index d58822f16eb35..4fc3ca78f961c 100644 --- a/src/test/ui/issues/issue-18118-2.stderr +++ b/src/test/ui/issues/issue-18118-2.stderr @@ -1,8 +1,10 @@ -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-18118-2.rs:4:10 | LL | &p | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that error: aborting due to previous error diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr index c69145c1fe833..502825e9766e3 100644 --- a/src/test/ui/issues/issue-52060.stderr +++ b/src/test/ui/issues/issue-52060.stderr @@ -1,8 +1,10 @@ -error[E0013]: constants cannot refer to statics, use a constant instead +error[E0013]: constants cannot refer to statics --> $DIR/issue-52060.rs:4:26 | LL | static B: [u32; 1] = [0; A.len()]; | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0080]: evaluation of constant value failed --> $DIR/issue-52060.rs:4:26 From 9e90840a6ae4a6f61781bd80adea825d156ddffa Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 26 Dec 2019 19:01:22 +0100 Subject: [PATCH 0178/1253] Simplify NodeHeader by avoiding slices in BTreeMaps with shared roots --- src/liballoc/collections/btree/map.rs | 6 +-- src/liballoc/collections/btree/node.rs | 55 +++--------------------- src/liballoc/collections/btree/search.rs | 18 ++++---- 3 files changed, 19 insertions(+), 60 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 302c2bcd5e4a3..e70f881bc3d7e 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1968,7 +1968,7 @@ where (i, false) => i, }, (_, Unbounded) => 0, - (true, Included(_)) => min_node.keys().len(), + (true, Included(_)) => min_node.len(), (true, Excluded(_)) => 0, }; @@ -1987,9 +1987,9 @@ where } (i, false) => i, }, - (_, Unbounded) => max_node.keys().len(), + (_, Unbounded) => max_node.len(), (true, Included(_)) => 0, - (true, Excluded(_)) => max_node.keys().len(), + (true, Excluded(_)) => max_node.len(), }; if !diverged { diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f40e0b0c30479..f190209503d3e 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -54,10 +54,8 @@ pub const CAPACITY: usize = 2 * B - 1; /// `NodeHeader` because we do not want unnecessary padding between `len` and the keys. /// Crucially, `NodeHeader` can be safely transmuted to different K and V. (This is exploited /// by `as_header`.) -/// See `into_key_slice` for an explanation of K2. K2 cannot be safely transmuted around -/// because the size of `NodeHeader` depends on its alignment! #[repr(C)] -struct NodeHeader { +struct NodeHeader { /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`. /// This either points to an actual node or is null. parent: *const InternalNode, @@ -72,9 +70,6 @@ struct NodeHeader { /// This next to `parent_idx` to encourage the compiler to join `len` and /// `parent_idx` into the same 32-bit word, reducing space overhead. len: u16, - - /// See `into_key_slice`. - keys_start: [K2; 0], } #[repr(C)] struct LeafNode { @@ -128,7 +123,7 @@ unsafe impl Sync for NodeHeader<(), ()> {} // We use just a header in order to save space, since no operation on an empty tree will // ever take a pointer past the first key. static EMPTY_ROOT_NODE: NodeHeader<(), ()> = - NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [] }; + NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 }; /// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden /// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an @@ -390,7 +385,7 @@ impl NodeRef { } /// Borrows a view into the keys stored in the node. - /// Works on all possible nodes, including the shared root. + /// The caller must ensure that the node is not the shared root. pub fn keys(&self) -> &[K] { self.reborrow().into_key_slice() } @@ -528,47 +523,9 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { fn into_key_slice(self) -> &'a [K] { - // We have to be careful here because we might be pointing to the shared root. - // In that case, we must not create an `&LeafNode`. We could just return - // an empty slice whenever the length is 0 (this includes the shared root), - // but we want to avoid that run-time check. - // Instead, we create a slice pointing into the node whenever possible. - // We can sometimes do this even for the shared root, as the slice will be - // empty and `NodeHeader` contains an empty `keys_start` array. - // We cannot *always* do this because: - // - `keys_start` is not correctly typed because we want `NodeHeader`'s size to - // not depend on the alignment of `K` (needed because `as_header` should be safe). - // For this reason, `NodeHeader` has this `K2` parameter (that's usually `()` - // and hence just adds a size-0-align-1 field, not affecting layout). - // If the correctly typed header is more highly aligned than the allocated header, - // we cannot transmute safely. - // - Even if we can transmute, the offset of a correctly typed `keys_start` might - // be different and outside the bounds of the allocated header! - // So we do an alignment check and a size check first, that will be evaluated - // at compile-time, and only do any run-time check in the rare case that - // the compile-time checks signal danger. - if (mem::align_of::>() > mem::align_of::>() - || mem::size_of::>() != mem::size_of::>()) - && self.is_shared_root() - { - &[] - } else { - // If we are a `LeafNode`, we can always transmute to - // `NodeHeader` and `keys_start` always has the same offset - // as the actual `keys`. - // Thanks to the checks above, we know that we can transmute to - // `NodeHeader` and that `keys_start` will be - // in-bounds of some allocation even if this is the shared root! - // (We might be one-past-the-end, but that is allowed by LLVM.) - // Thus we can use `NodeHeader` - // to compute the pointer where the keys start. - // This entire hack will become unnecessary once - // lands, then we can just take a raw - // pointer to the `keys` field of `*const InternalNode`. - let header = self.as_header() as *const _ as *const NodeHeader; - let keys = unsafe { &(*header).keys_start as *const _ as *const K }; - unsafe { slice::from_raw_parts(keys, self.len()) } - } + debug_assert!(!self.is_shared_root()); + // We cannot be the shared root, so `as_leaf` is okay. + unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len()) } } /// The caller must ensure that the node is not the shared root. diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 48cbf67eea254..25e206f4f73db 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -61,16 +61,18 @@ where { // This function is defined over all borrow types (immutable, mutable, owned), // and may be called on the shared root in each case. - // Crucially, we use `keys()` here, i.e., we work with immutable data. - // `keys_mut()` does not support the shared root, so we cannot use it. // Using `keys()` is fine here even if BorrowType is mutable, as all we return // is an index -- not a reference. - for (i, k) in node.keys().iter().enumerate() { - match key.cmp(k.borrow()) { - Ordering::Greater => {} - Ordering::Equal => return (i, true), - Ordering::Less => return (i, false), + let len = node.len(); + // Skip search for empty nodes because `keys()` does not work on shared roots. + if len > 0 { + for (i, k) in node.keys().iter().enumerate() { + match key.cmp(k.borrow()) { + Ordering::Greater => {} + Ordering::Equal => return (i, true), + Ordering::Less => return (i, false), + } } } - (node.keys().len(), false) + (len, false) } From 91e9531ed1a70eab0c4f6a6bce304e2a731f54e7 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Fri, 10 Jan 2020 19:26:40 +0300 Subject: [PATCH 0179/1253] Clarify test timeout evironment variables --- src/libtest/cli.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libtest/cli.rs b/src/libtest/cli.rs index ea6d632f48a59..edff8bea0f3d0 100644 --- a/src/libtest/cli.rs +++ b/src/libtest/cli.rs @@ -125,6 +125,8 @@ fn optgroups() -> getopts::Options { `RUST_TEST_TIME_DOCTEST` environment variables. Expected format of environment variable is `VARIABLE=WARN_TIME,CRITICAL_TIME`. + Durations must be specified in milliseconds, e.g. `500,2000` means that the warn time + is 0.5 seconds, and the critical time is 2 seconds. Not available for --format=terse", "plain|colored", From 137a31d6923f229ffb5ed78772d02ecda3c7c53c Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 18:20:40 +0000 Subject: [PATCH 0180/1253] Inline to make OsStr::is_empty zero cost --- src/libstd/ffi/os_str.rs | 1 + src/libstd/sys_common/os_str_bytes.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 4c308327b83b7..ec2d07f34ca5f 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -615,6 +615,7 @@ impl OsStr { /// assert!(!os_str.is_empty()); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn is_empty(&self) -> bool { self.inner.inner.is_empty() } diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs index eb8a881ec8881..e965ea79aa039 100644 --- a/src/libstd/sys_common/os_str_bytes.rs +++ b/src/libstd/sys_common/os_str_bytes.rs @@ -104,6 +104,7 @@ impl Buf { self.inner.shrink_to(min_capacity) } + #[inline] pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } From 4fadb507f48a0f959518bbf9b7d0969a159d76f1 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Fri, 10 Jan 2020 23:56:00 +0530 Subject: [PATCH 0181/1253] Update E0185.md --- src/librustc_error_codes/error_codes/E0185.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0185.md b/src/librustc_error_codes/error_codes/E0185.md index ac5d8bd766f40..944a93ed14e6c 100644 --- a/src/librustc_error_codes/error_codes/E0185.md +++ b/src/librustc_error_codes/error_codes/E0185.md @@ -19,8 +19,8 @@ impl Foo for Bar { ``` When a type implements a trait's associated function, it has to use the same -signature. So in this case, since `Foo::foo` doesn't take any argument and -doesn't return anything, its implementation on `Bar` should be the same: +signature. So in this case, since `Foo::foo` does not take any argument and +does not return anything, its implementation on `Bar` should be the same: ``` trait Foo { From eca1e8bd9beeaabbc240ad342892f26998ad7f35 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 18:48:15 +0000 Subject: [PATCH 0182/1253] Inline PathBuf::deref to make it zero cost --- src/libstd/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index fbbdc1ddac297..f00ef26930921 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1535,7 +1535,7 @@ impl fmt::Debug for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for PathBuf { type Target = Path; - + #[inline] fn deref(&self) -> &Path { Path::new(&self.inner) } From ea6bb7fe17395545a8f22563ed831ac5d2b4389f Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 18:56:30 +0000 Subject: [PATCH 0183/1253] Inline `AsRef for str` --- src/libstd/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index f00ef26930921..7ea642942dd74 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2655,6 +2655,7 @@ impl AsRef for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for str { + #[inline] fn as_ref(&self) -> &Path { Path::new(self) } From bf1d20c4b60c20a780e8d98882e24b0e48b1a33d Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 19:02:14 +0000 Subject: [PATCH 0184/1253] Inline `impl From for PathBuf` --- src/libstd/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 7ea642942dd74..a09300ffe956f 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1475,6 +1475,7 @@ impl From for PathBuf { /// Converts a `OsString` into a `PathBuf` /// /// This conversion does not allocate or copy memory. + #[inline] fn from(s: OsString) -> PathBuf { PathBuf { inner: s } } From 3250057da983fa4d5bfd0799adaa41cb038f0e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:02:47 -0800 Subject: [PATCH 0185/1253] Fix `next_point` to be unicode aware --- src/librustc_span/source_map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index ec1f9f3a7bdaf..fb5fcf4a8303b 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -710,7 +710,7 @@ impl SourceMap { pub fn next_point(&self, sp: Span) -> Span { let start_of_next_point = sp.hi().0; - let width = self.find_width_of_character_at_span(sp, true); + let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true); // If the width is 1, then the next span should point to the same `lo` and `hi`. However, // in the case of a multibyte character, where the width != 1, the next span should // span multiple bytes to include the whole character. From d558f6a570a782cd1c2e54de790f4f968b0de5f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:03:26 -0800 Subject: [PATCH 0186/1253] Fix invalid bounding box --- src/librustc_errors/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 99a6d6f8ec2d4..e24e8719133a9 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -182,7 +182,7 @@ impl CodeSuggestion { // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); - let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap(); + let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap(); let bounding_span = Span::with_root_ctxt(lo, hi); let lines = cm.span_to_lines(bounding_span).unwrap(); assert!(!lines.lines.is_empty()); From cd5ab974808732a7f1b6923a54cf8a75dff1599e Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 19:06:18 +0000 Subject: [PATCH 0187/1253] inline `impl AsRef for OsString` --- src/libstd/ffi/os_str.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index ec2d07f34ca5f..77da97219b147 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -966,6 +966,7 @@ impl AsRef for OsStr { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for OsString { + #[inline] fn as_ref(&self) -> &OsStr { self } From 76e698fc56473702ce2db81296b45c5fd267485e Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 19:18:17 +0000 Subject: [PATCH 0188/1253] inline `impl AsRef for PathBuf` --- src/libstd/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index a09300ffe956f..a703cb748e06b 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2671,6 +2671,7 @@ impl AsRef for String { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for PathBuf { + #[inline] fn as_ref(&self) -> &Path { self } From b93ef68245807bac97cd17ea9eaa13169380d815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:22:33 -0800 Subject: [PATCH 0189/1253] Change `next_point` when `shrink_to_hi` is more appropriate --- src/librustc_builtin_macros/assert.rs | 2 +- src/librustc_expand/mbe/macro_parser.rs | 2 +- src/librustc_parse/parser/diagnostics.rs | 11 ++++------- src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/item.rs | 4 ++-- src/librustc_parse/parser/mod.rs | 2 +- src/librustc_typeck/check/callee.rs | 5 ++--- src/librustc_typeck/check/mod.rs | 3 +-- 8 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs index 9043db4742bf7..b76b496666e88 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/src/librustc_builtin_macros/assert.rs @@ -106,7 +106,7 @@ fn parse_assert<'a>( let custom_message = if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind { let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal"); - let comma_span = cx.source_map().next_point(parser.prev_span); + let comma_span = parser.prev_span.shrink_to_hi(); err.span_suggestion_short( comma_span, "try adding a comma", diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index c0e34a30c54e9..d0aae300b1c9d 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -696,7 +696,7 @@ pub(super) fn parse( if parser.token.span.is_dummy() { parser.token.span } else { - sess.source_map().next_point(parser.token.span) + parser.token.span.shrink_to_hi() }, ), "missing tokens in macro arguments", diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 9abfbc698c5cf..b9658b33d0fef 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -265,10 +265,7 @@ impl<'a> Parser<'a> { }; ( format!("expected one of {}, found {}", expect, actual), - ( - self.sess.source_map().next_point(self.prev_span), - format!("expected one of {}", short_expect), - ), + (self.prev_span.shrink_to_hi(), format!("expected one of {}", short_expect)), ) } else if expected.is_empty() { ( @@ -278,7 +275,7 @@ impl<'a> Parser<'a> { } else { ( format!("expected {}, found {}", expect, actual), - (self.sess.source_map().next_point(self.prev_span), format!("expected {}", expect)), + (self.prev_span.shrink_to_hi(), format!("expected {}", expect)), ) }; self.last_unexpected_token_span = Some(self.token.span); @@ -809,7 +806,7 @@ impl<'a> Parser<'a> { _ if self.prev_span == DUMMY_SP => (self.token.span, self.token.span), // EOF, don't want to point at the following char, but rather the last token. (token::Eof, None) => (self.prev_span, self.token.span), - _ => (self.sess.source_map().next_point(self.prev_span), self.token.span), + _ => (self.prev_span.shrink_to_hi(), self.token.span), }; let msg = format!( "expected `{}`, found {}", @@ -1132,7 +1129,7 @@ impl<'a> Parser<'a> { err.span_label(sp, "unclosed delimiter"); } err.span_suggestion_short( - self.sess.source_map().next_point(self.prev_span), + self.prev_span.shrink_to_hi(), &format!("{} may belong here", delim.to_string()), delim.to_string(), Applicability::MaybeIncorrect, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 90f15375aec42..f02ea117c0646 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1646,7 +1646,7 @@ impl<'a> Parser<'a> { // | | // | parsed until here as `"y" & X` err.span_suggestion_short( - cm.next_point(arm_start_span), + arm_start_span.shrink_to_hi(), "missing a comma here to end this `match` arm", ",".to_owned(), Applicability::MachineApplicable, diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 4cd3540ea6807..fdc01dc930d96 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1628,7 +1628,7 @@ impl<'a> Parser<'a> { // it's safe to peel off one character only when it has the close delim self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)) } else { - self.sess.source_map().next_point(self.prev_span) + self.prev_span.shrink_to_hi() }; self.struct_span_err( @@ -1644,7 +1644,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) .span_suggestion( - self.sess.source_map().next_point(self.prev_span), + self.prev_span.shrink_to_hi(), "add a semicolon", ';'.to_string(), Applicability::MaybeIncorrect, diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 8d695eda98d04..a1035d320b31c 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -765,7 +765,7 @@ impl<'a> Parser<'a> { break; } Err(mut expect_err) => { - let sp = self.sess.source_map().next_point(self.prev_span); + let sp = self.prev_span.shrink_to_hi(); let token_str = pprust::token_kind_to_string(t); // Attempt to keep parsing if it was a similar separator. diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a1915bc025f79..918542e7da5ff 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -242,7 +242,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) = (parent_node, callee_node) { let start = sp.shrink_to_lo(); - let end = self.tcx.sess.source_map().next_point(callee_span); + let end = callee_span.shrink_to_hi(); err.multipart_suggestion( "if you meant to create this closure and immediately call it, surround the \ closure with parenthesis", @@ -319,9 +319,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span); if call_is_multiline { - let span = self.tcx.sess.source_map().next_point(callee.span); err.span_suggestion( - span, + callee.span.shrink_to_hi(), "try adding a semicolon", ";".to_owned(), Applicability::MaybeIncorrect, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f10edc1a468b4..94c9a704c65df 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4953,9 +4953,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::Block(..) => { - let sp = self.tcx.sess.source_map().next_point(cause_span); err.span_suggestion( - sp, + cause_span.shrink_to_hi(), "try adding a semicolon", ";".to_string(), Applicability::MachineApplicable, From f6e9fd037a7b55f8f4fe78694b77d9788b18dfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:22:57 -0800 Subject: [PATCH 0190/1253] Add ICE regression tests --- .../issue-68091-unicode-ident-after-if.rs | 9 +++++++++ .../issue-68091-unicode-ident-after-if.stderr | 18 ++++++++++++++++++ ...8092-unicode-ident-after-incomplete-expr.rs | 9 +++++++++ ...-unicode-ident-after-incomplete-expr.stderr | 8 ++++++++ 4 files changed, 44 insertions(+) create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.rs create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs new file mode 100644 index 0000000000000..00f90cc73b344 --- /dev/null +++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs @@ -0,0 +1,9 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* {} //~ ERROR missing condition for `if` expression + }; //~| ERROR mismatched types +} + +fn main() { + x!(if); +} diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr new file mode 100644 index 0000000000000..8d1a03ac207e1 --- /dev/null +++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr @@ -0,0 +1,18 @@ +error: missing condition for `if` expression + --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14 + | +LL | $($c)ö* {} + | ^ expected if condition here + +error[E0308]: mismatched types + --> $DIR/issue-68091-unicode-ident-after-if.rs:3:17 + | +LL | $($c)ö* {} + | ^^ expected `bool`, found `()` +... +LL | x!(if); + | ------- in this macro invocation + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs new file mode 100644 index 0000000000000..1a90b4724d49d --- /dev/null +++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs @@ -0,0 +1,9 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression + }; +} + +fn main() { + x!(!); +} diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr new file mode 100644 index 0000000000000..0b9c364f1f1fb --- /dev/null +++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr @@ -0,0 +1,8 @@ +error: macro expansion ends with an incomplete expression: expected expression + --> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:14 + | +LL | $($c)ö* + | ^ expected expression + +error: aborting due to previous error + From 5f3f1a3606a5f13177a1634ba80d6386e5132518 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 19:27:02 +0000 Subject: [PATCH 0191/1253] inline `impl From for Box` --- src/libstd/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 1407fe2771553..b480581e21ba9 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -250,6 +250,7 @@ impl From for Box { /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` + #[inline] fn from(err: String) -> Box { struct StringError(String); @@ -317,6 +318,7 @@ impl<'a> From<&str> for Box { /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` + #[inline] fn from(err: &str) -> Box { From::from(String::from(err)) } From 39c96a0f534366b3970ff0f8cd831be4386961dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 14 Oct 2019 17:20:50 -0700 Subject: [PATCH 0192/1253] Point at the span for the definition of crate foreign ADTs --- .../rmeta/decoder/cstore_impl.rs | 4 ++ src/librustc_resolve/diagnostics.rs | 8 +-- .../deriving-meta-unknown-trait.stderr | 5 ++ .../ui/empty/empty-struct-braces-expr.stderr | 20 ++++++++ .../ui/empty/empty-struct-braces-pat-1.stderr | 5 ++ .../ui/empty/empty-struct-braces-pat-2.stderr | 20 ++++++++ .../ui/empty/empty-struct-braces-pat-3.stderr | 10 ++++ .../ui/empty/empty-struct-tuple-pat.stderr | 5 ++ .../ui/empty/empty-struct-unit-pat.stderr | 30 ++++++++++++ src/test/ui/issues/issue-17546.stderr | 30 ++++++++++-- src/test/ui/issues/issue-7607-1.stderr | 13 ++++- src/test/ui/macros/macro-name-typo.stderr | 14 +++++- .../macros/macro-path-prelude-fail-3.stderr | 5 ++ .../ui/macros/macro-use-wrong-name.stderr | 5 ++ src/test/ui/namespace/namespace-mix.stderr | 10 ++++ .../ui/proc-macro/parent-source-spans.stderr | 15 ++++++ src/test/ui/proc-macro/resolve-error.stderr | 49 ++++++++++++++++--- src/test/ui/resolve/levenshtein.stderr | 15 +++++- .../ui/suggestions/attribute-typos.stderr | 5 ++ 19 files changed, 247 insertions(+), 21 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index eb5754bf99bfb..cb7d031fdfef1 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -479,6 +479,10 @@ impl CStore { self.get_crate_data(cnum).source.clone() } + pub fn get_span_untracked(&self, def_id: DefId, sess: &Session) -> Span { + self.get_crate_data(def_id.krate).get_span(def_id.index, sess) + } + pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize { self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b81e71f0acfd7..6fd45e78f2d95 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Symbol}; @@ -780,8 +780,10 @@ impl<'a> Resolver<'a> { suggestion.candidate.to_string(), Applicability::MaybeIncorrect, ); - let def_span = - suggestion.res.opt_def_id().and_then(|def_id| self.definitions.opt_span(def_id)); + let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { + LOCAL_CRATE => self.definitions.opt_span(def_id), + _ => Some(self.cstore().get_span_untracked(def_id, self.session)), + }); if let Some(span) = def_span { err.span_label( span, diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index 8d0f9e9fc89a8..ab382e9284eb7 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -3,6 +3,11 @@ error: cannot find derive macro `Eqr` in this scope | LL | #[derive(Eqr)] | ^^^ help: a derive macro with a similar name exists: `Eq` + | + ::: $SRC_DIR/libcore/cmp.rs:LL:COL + | +LL | pub macro Eq($item:item) { /* compiler built-in */ } + | ---------------------------------------------------- similarly named derive macro `Eq` defined here error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index f427c1ba0adfb..cccb06d49a6fe 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -9,6 +9,11 @@ LL | let e1 = Empty1; | | | did you mean `Empty1 { /* fields */ }`? | help: a unit struct with a similar name exists: `XEmpty2` + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 + | +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here error[E0423]: expected function, tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-expr.rs:16:14 @@ -21,6 +26,11 @@ LL | let e1 = Empty1(); | | | did you mean `Empty1 { /* fields */ }`? | help: a unit struct with a similar name exists: `XEmpty2` + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 + | +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here error[E0423]: expected value, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:18:14 @@ -48,6 +58,11 @@ LL | let xe1 = XEmpty1; | | | did you mean `XEmpty1 { /* fields */ }`? | help: a unit struct with a similar name exists: `XEmpty2` + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 + | +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-expr.rs:23:15 @@ -57,6 +72,11 @@ LL | let xe1 = XEmpty1(); | | | did you mean `XEmpty1 { /* fields */ }`? | help: a unit struct with a similar name exists: `XEmpty2` + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 + | +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:25:19 diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index 9b5f31157d1bb..0ff21c91b78fd 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -15,6 +15,11 @@ LL | XE::XEmpty3 => () | | | | | help: a unit variant with a similar name exists: `XEmpty4` | did you mean `XE::XEmpty3 { /* fields */ }`? + | + ::: $DIR/auxiliary/empty-struct.rs:7:5 + | +LL | XEmpty4, + | ------- similarly named unit variant `XEmpty4` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr index 0b3c9ae51519e..80c29db8d9b77 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr @@ -9,6 +9,11 @@ LL | Empty1() => () | | | did you mean `Empty1 { /* fields */ }`? | help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:18:9 @@ -18,6 +23,11 @@ LL | XEmpty1() => () | | | did you mean `XEmpty1 { /* fields */ }`? | help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-pat-2.rs:21:9 @@ -30,6 +40,11 @@ LL | Empty1(..) => () | | | did you mean `Empty1 { /* fields */ }`? | help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:24:9 @@ -39,6 +54,11 @@ LL | XEmpty1(..) => () | | | did you mean `XEmpty1 { /* fields */ }`? | help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index 785396c448bb0..05439b39ea39d 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -15,6 +15,11 @@ LL | XE::XEmpty3() => () | | | | | help: a tuple variant with a similar name exists: `XEmpty5` | did you mean `XE::XEmpty3 { /* fields */ }`? + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 + | +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-3.rs:25:9 @@ -33,6 +38,11 @@ LL | XE::XEmpty3(..) => () | | | | | help: a tuple variant with a similar name exists: `XEmpty5` | did you mean `XE::XEmpty3 { /* fields */ }`? + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 + | +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr index cfbb468e5e633..9388ed2665710 100644 --- a/src/test/ui/empty/empty-struct-tuple-pat.stderr +++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr @@ -33,6 +33,11 @@ LL | XE::XEmpty5 => (), | | | | | help: a unit variant with a similar name exists: `XEmpty4` | did you mean `XE::XEmpty5( /* fields */ )`? + | + ::: $DIR/auxiliary/empty-struct.rs:7:5 + | +LL | XEmpty4, + | ------- similarly named unit variant `XEmpty4` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-struct-unit-pat.stderr b/src/test/ui/empty/empty-struct-unit-pat.stderr index fd41a6ed38284..8ee14a3d01d89 100644 --- a/src/test/ui/empty/empty-struct-unit-pat.stderr +++ b/src/test/ui/empty/empty-struct-unit-pat.stderr @@ -3,24 +3,44 @@ error[E0532]: expected tuple struct or tuple variant, found unit struct `Empty2` | LL | Empty2() => () | ^^^^^^ help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found unit struct `XEmpty2` --> $DIR/empty-struct-unit-pat.rs:24:9 | LL | XEmpty2() => () | ^^^^^^^ help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found unit struct `Empty2` --> $DIR/empty-struct-unit-pat.rs:28:9 | LL | Empty2(..) => () | ^^^^^^ help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found unit struct `XEmpty2` --> $DIR/empty-struct-unit-pat.rs:32:9 | LL | XEmpty2(..) => () | ^^^^^^^ help: a tuple struct with a similar name exists: `XEmpty6` + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 + | +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here error[E0532]: expected tuple struct or tuple variant, found unit variant `E::Empty4` --> $DIR/empty-struct-unit-pat.rs:37:9 @@ -35,6 +55,11 @@ LL | XE::XEmpty4() => (), | ^^^^------- | | | help: a tuple variant with a similar name exists: `XEmpty5` + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 + | +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here error[E0532]: expected tuple struct or tuple variant, found unit variant `E::Empty4` --> $DIR/empty-struct-unit-pat.rs:46:9 @@ -49,6 +74,11 @@ LL | XE::XEmpty4(..) => (), | ^^^^------- | | | help: a tuple variant with a similar name exists: `XEmpty5` + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 + | +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr index f3242919e0105..255521a0be90a 100644 --- a/src/test/ui/issues/issue-17546.stderr +++ b/src/test/ui/issues/issue-17546.stderr @@ -1,8 +1,19 @@ error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:12:17 | -LL | fn new() -> NoResult { - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn new() -> NoResult { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | / pub enum Result { +LL | | /// Contains the success value +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), +... | +LL | | Err(#[stable(feature = "rust1", since = "1.0.0")] E), +LL | | } + | |_- similarly named enum `Result` defined here | help: try using the variant's enum | @@ -52,8 +63,19 @@ LL | use std::result::Result; error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:33:15 | -LL | fn newer() -> NoResult { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn newer() -> NoResult { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | / pub enum Result { +LL | | /// Contains the success value +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), +... | +LL | | Err(#[stable(feature = "rust1", since = "1.0.0")] E), +LL | | } + | |_- similarly named enum `Result` defined here | help: try using the variant's enum | diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr index 9320943a82766..40c25b9f78c55 100644 --- a/src/test/ui/issues/issue-7607-1.stderr +++ b/src/test/ui/issues/issue-7607-1.stderr @@ -1,8 +1,17 @@ error[E0412]: cannot find type `Fo` in this scope --> $DIR/issue-7607-1.rs:5:6 | -LL | impl Fo { - | ^^ help: a trait with a similar name exists: `Fn` +LL | impl Fo { + | ^^ help: a trait with a similar name exists: `Fn` + | + ::: $SRC_DIR/libcore/ops/function.rs:LL:COL + | +LL | / pub trait Fn : FnMut { +LL | | /// Performs the call operation. +LL | | #[unstable(feature = "fn_traits", issue = "29625")] +LL | | extern "rust-call" fn call(&self, args: Args) -> Self::Output; +LL | | } + | |_- similarly named trait `Fn` defined here error: aborting due to previous error diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index ce2e1985b38ce..7e5dfe20e9616 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -1,8 +1,18 @@ error: cannot find macro `printlx` in this scope --> $DIR/macro-name-typo.rs:2:5 | -LL | printlx!("oh noes!"); - | ^^^^^^^ help: a macro with a similar name exists: `println` +LL | printlx!("oh noes!"); + | ^^^^^^^ help: a macro with a similar name exists: `println` + | + ::: $SRC_DIR/libstd/macros.rs:LL:COL + | +LL | / macro_rules! println { +LL | | () => ($crate::print!("\n")); +LL | | ($($arg:tt)*) => ({ +LL | | $crate::io::_print($crate::format_args_nl!($($arg)*)); +LL | | }) +LL | | } + | |_- similarly named macro `println` defined here error: aborting due to previous error diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr index ec00760de6c6f..3d72cc82cbdfc 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr @@ -3,6 +3,11 @@ error: cannot find macro `inline` in this scope | LL | inline!(); | ^^^^^^ help: a macro with a similar name exists: `line` + | + ::: $SRC_DIR/libcore/macros.rs:LL:COL + | +LL | macro_rules! line { () => { /* compiler built-in */ } } + | ------------------------------------------------------- similarly named macro `line` defined here 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 8b4e90a5798f1..d76eb69b3c4c9 100644 --- a/src/test/ui/macros/macro-use-wrong-name.stderr +++ b/src/test/ui/macros/macro-use-wrong-name.stderr @@ -3,6 +3,11 @@ error: cannot find macro `macro_two` in this scope | LL | macro_two!(); | ^^^^^^^^^ help: a macro with a similar name exists: `macro_one` + | + ::: $DIR/auxiliary/two_macros.rs:2:1 + | +LL | macro_rules! macro_one { () => ("one") } + | ---------------------------------------- similarly named macro `macro_one` defined here error: aborting due to previous error diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 0484661a2e154..13d727de441cb 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -24,6 +24,11 @@ error[E0423]: expected value, found type alias `xm1::S` | LL | check(xm1::S); | ^^^^^^ + | + ::: $DIR/auxiliary/namespace-mix.rs:3:5 + | +LL | pub struct TS(); + | ---------------- similarly named tuple struct `TS` defined here | = note: can't use a type alias as a constructor help: a tuple struct with a similar name exists @@ -64,6 +69,11 @@ error[E0423]: expected value, found struct variant `xm7::V` | LL | check(xm7::V); | ^^^^^^ did you mean `xm7::V { /* fields */ }`? + | + ::: $DIR/auxiliary/namespace-mix.rs:7:9 + | +LL | TV(), + | ---- similarly named tuple variant `TV` defined here | help: a tuple variant with a similar name exists | diff --git a/src/test/ui/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr index 3e54a71f0e810..2a36ac78d78c1 100644 --- a/src/test/ui/proc-macro/parent-source-spans.stderr +++ b/src/test/ui/proc-macro/parent-source-spans.stderr @@ -132,6 +132,11 @@ LL | parent_source_spans!($($tokens)*); ... LL | one!("hello", "world"); | ----------------------- in this macro invocation + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | --------------------------------------------------- similarly named tuple variant `Ok` defined here error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:28:5 @@ -141,6 +146,11 @@ LL | parent_source_spans!($($tokens)*); ... LL | two!("yay", "rust"); | -------------------- in this macro invocation + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | --------------------------------------------------- similarly named tuple variant `Ok` defined here error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:28:5 @@ -150,6 +160,11 @@ LL | parent_source_spans!($($tokens)*); ... LL | three!("hip", "hop"); | --------------------- in this macro invocation + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | --------------------------------------------------- similarly named tuple variant `Ok` defined here error: aborting due to 21 previous errors diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index f7e00ed77d9b0..4663a8df9daf0 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,8 +1,15 @@ error: cannot find macro `bang_proc_macrp` in this scope --> $DIR/resolve-error.rs:60:5 | -LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` +LL | bang_proc_macrp!(); + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` + | + ::: $DIR/auxiliary/test-macros.rs:15:1 + | +LL | / pub fn empty(_: TokenStream) -> TokenStream { +LL | | TokenStream::new() +LL | | } + | |_- similarly named macro `bang_proc_macro` defined here error: cannot find macro `Dlona` in this scope --> $DIR/resolve-error.rs:57:5 @@ -53,8 +60,15 @@ LL | #[derive(Dlona)] error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | -LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` +LL | #[derive(Dlona)] + | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | + ::: $DIR/auxiliary/derive-clona.rs:11:1 + | +LL | / pub fn derive_clonea(input: TokenStream) -> TokenStream { +LL | | "".parse().unwrap() +LL | | } + | |_- similarly named derive macro `Clona` defined here error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 @@ -67,6 +81,11 @@ error: cannot find derive macro `Dlone` in this scope | LL | #[derive(Dlone)] | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | pub macro Clone($item:item) { /* compiler built-in */ } + | ------------------------------------------------------- similarly named derive macro `Clone` defined here error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 @@ -77,14 +96,28 @@ LL | #[FooWithLongNan] error: cannot find attribute `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:28:3 | -LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` +LL | #[attr_proc_macra] + | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` + | + ::: $DIR/auxiliary/test-macros.rs:20:1 + | +LL | / pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { +LL | | TokenStream::new() +LL | | } + | |_- similarly named attribute macro `attr_proc_macro` defined here error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | -LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` +LL | #[derive(FooWithLongNan)] + | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | + ::: $DIR/auxiliary/derive-foo.rs:11:1 + | +LL | / pub fn derive_foo(input: TokenStream) -> TokenStream { +LL | | "".parse().unwrap() +LL | | } + | |_- similarly named derive macro `FooWithLongName` defined here error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 8d8f3f35211e2..c7497afd0257d 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -16,8 +16,19 @@ LL | type A = Baz; // Misspelled type name. error[E0412]: cannot find type `Opiton` in this scope --> $DIR/levenshtein.rs:12:10 | -LL | type B = Opiton; // Misspelled type name from the prelude. - | ^^^^^^ help: an enum with a similar name exists: `Option` +LL | type B = Opiton; // Misspelled type name from the prelude. + | ^^^^^^ help: an enum with a similar name exists: `Option` + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | / pub enum Option { +LL | | /// No value +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | None, +... | +LL | | Some(#[stable(feature = "rust1", since = "1.0.0")] T), +LL | | } + | |_- similarly named enum `Option` defined here error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:16:14 diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index e40329382fd40..d91b1cc707cb7 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -18,6 +18,11 @@ error: cannot find attribute `tests` in this scope | LL | #[tests] | ^^^^^ help: an attribute macro with a similar name exists: `test` + | + ::: $SRC_DIR/libcore/macros.rs:LL:COL + | +LL | pub macro test($item:item) { /* compiler built-in */ } + | ------------------------------------------------------ similarly named attribute macro `test` defined here error: cannot find attribute `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 From 8eb7ac561eb42b70bc7db3852c502dd63186a119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 28 Oct 2019 14:48:49 -0700 Subject: [PATCH 0193/1253] Use `def_span` to minimize definition span to first line when possible --- src/librustc_resolve/diagnostics.rs | 5 ++- .../deriving-meta-unknown-trait.stderr | 2 +- src/test/ui/issues/issue-17546.stderr | 28 ++++--------- src/test/ui/issues/issue-7607-1.stderr | 12 ++---- src/test/ui/macros/macro-name-typo.stderr | 13 ++---- .../macros/macro-path-prelude-fail-3.stderr | 2 +- .../ui/macros/macro-use-wrong-name.stderr | 2 +- src/test/ui/proc-macro/resolve-error.stderr | 42 ++++++++----------- src/test/ui/resolve/levenshtein.stderr | 14 ++----- .../ui/suggestions/attribute-typos.stderr | 2 +- 10 files changed, 45 insertions(+), 77 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 6fd45e78f2d95..411a72447a4f6 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -782,7 +782,10 @@ impl<'a> Resolver<'a> { ); let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { LOCAL_CRATE => self.definitions.opt_span(def_id), - _ => Some(self.cstore().get_span_untracked(def_id, self.session)), + _ => Some(self.session.source_map().def_span(self.cstore().get_span_untracked( + def_id, + self.session, + ))), }); if let Some(span) = def_span { err.span_label( diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index ab382e9284eb7..666cc69f6e967 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -7,7 +7,7 @@ LL | #[derive(Eqr)] ::: $SRC_DIR/libcore/cmp.rs:LL:COL | LL | pub macro Eq($item:item) { /* compiler built-in */ } - | ---------------------------------------------------- similarly named derive macro `Eq` defined here + | ------------------------ similarly named derive macro `Eq` defined here error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr index 255521a0be90a..5bbe6d3b17176 100644 --- a/src/test/ui/issues/issue-17546.stderr +++ b/src/test/ui/issues/issue-17546.stderr @@ -1,19 +1,13 @@ error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:12:17 | -LL | fn new() -> NoResult { - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn new() -> NoResult { + | ^^^^^^^^^^^^^^^^^^^^^^^^ | ::: $SRC_DIR/libcore/result.rs:LL:COL | -LL | / pub enum Result { -LL | | /// Contains the success value -LL | | #[stable(feature = "rust1", since = "1.0.0")] -LL | | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), -... | -LL | | Err(#[stable(feature = "rust1", since = "1.0.0")] E), -LL | | } - | |_- similarly named enum `Result` defined here +LL | pub enum Result { + | --------------------- similarly named enum `Result` defined here | help: try using the variant's enum | @@ -63,19 +57,13 @@ LL | use std::result::Result; error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:33:15 | -LL | fn newer() -> NoResult { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn newer() -> NoResult { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ::: $SRC_DIR/libcore/result.rs:LL:COL | -LL | / pub enum Result { -LL | | /// Contains the success value -LL | | #[stable(feature = "rust1", since = "1.0.0")] -LL | | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), -... | -LL | | Err(#[stable(feature = "rust1", since = "1.0.0")] E), -LL | | } - | |_- similarly named enum `Result` defined here +LL | pub enum Result { + | --------------------- similarly named enum `Result` defined here | help: try using the variant's enum | diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr index 40c25b9f78c55..472f8e013a922 100644 --- a/src/test/ui/issues/issue-7607-1.stderr +++ b/src/test/ui/issues/issue-7607-1.stderr @@ -1,17 +1,13 @@ error[E0412]: cannot find type `Fo` in this scope --> $DIR/issue-7607-1.rs:5:6 | -LL | impl Fo { - | ^^ help: a trait with a similar name exists: `Fn` +LL | impl Fo { + | ^^ help: a trait with a similar name exists: `Fn` | ::: $SRC_DIR/libcore/ops/function.rs:LL:COL | -LL | / pub trait Fn : FnMut { -LL | | /// Performs the call operation. -LL | | #[unstable(feature = "fn_traits", issue = "29625")] -LL | | extern "rust-call" fn call(&self, args: Args) -> Self::Output; -LL | | } - | |_- similarly named trait `Fn` defined here +LL | pub trait Fn : FnMut { + | -------------------------------- similarly named trait `Fn` defined here error: aborting due to previous error diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index 7e5dfe20e9616..5604341fa34dc 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -1,18 +1,13 @@ error: cannot find macro `printlx` in this scope --> $DIR/macro-name-typo.rs:2:5 | -LL | printlx!("oh noes!"); - | ^^^^^^^ help: a macro with a similar name exists: `println` +LL | printlx!("oh noes!"); + | ^^^^^^^ help: a macro with a similar name exists: `println` | ::: $SRC_DIR/libstd/macros.rs:LL:COL | -LL | / macro_rules! println { -LL | | () => ($crate::print!("\n")); -LL | | ($($arg:tt)*) => ({ -LL | | $crate::io::_print($crate::format_args_nl!($($arg)*)); -LL | | }) -LL | | } - | |_- similarly named macro `println` defined here +LL | macro_rules! println { + | -------------------- similarly named macro `println` defined here error: aborting due to previous error diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr index 3d72cc82cbdfc..e26a914e243ee 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr @@ -7,7 +7,7 @@ LL | inline!(); ::: $SRC_DIR/libcore/macros.rs:LL:COL | LL | macro_rules! line { () => { /* compiler built-in */ } } - | ------------------------------------------------------- similarly named macro `line` defined here + | ----------------- similarly named macro `line` defined here 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 d76eb69b3c4c9..74fb519cc82ff 100644 --- a/src/test/ui/macros/macro-use-wrong-name.stderr +++ b/src/test/ui/macros/macro-use-wrong-name.stderr @@ -7,7 +7,7 @@ LL | macro_two!(); ::: $DIR/auxiliary/two_macros.rs:2:1 | LL | macro_rules! macro_one { () => ("one") } - | ---------------------------------------- similarly named macro `macro_one` defined here + | ---------------------- similarly named macro `macro_one` defined here error: aborting due to previous error diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index 4663a8df9daf0..61868f4203bb0 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,15 +1,13 @@ error: cannot find macro `bang_proc_macrp` in this scope --> $DIR/resolve-error.rs:60:5 | -LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` +LL | bang_proc_macrp!(); + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` | ::: $DIR/auxiliary/test-macros.rs:15:1 | -LL | / pub fn empty(_: TokenStream) -> TokenStream { -LL | | TokenStream::new() -LL | | } - | |_- similarly named macro `bang_proc_macro` defined here +LL | pub fn empty(_: TokenStream) -> TokenStream { + | ------------------------------------------- similarly named macro `bang_proc_macro` defined here error: cannot find macro `Dlona` in this scope --> $DIR/resolve-error.rs:57:5 @@ -60,15 +58,13 @@ LL | #[derive(Dlona)] error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | -LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` +LL | #[derive(Dlona)] + | ^^^^^ help: a derive macro with a similar name exists: `Clona` | ::: $DIR/auxiliary/derive-clona.rs:11:1 | -LL | / pub fn derive_clonea(input: TokenStream) -> TokenStream { -LL | | "".parse().unwrap() -LL | | } - | |_- similarly named derive macro `Clona` defined here +LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { + | ------------------------------------------------------- similarly named derive macro `Clona` defined here error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 @@ -85,7 +81,7 @@ LL | #[derive(Dlone)] ::: $SRC_DIR/libcore/clone.rs:LL:COL | LL | pub macro Clone($item:item) { /* compiler built-in */ } - | ------------------------------------------------------- similarly named derive macro `Clone` defined here + | --------------------------- similarly named derive macro `Clone` defined here error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 @@ -96,28 +92,24 @@ LL | #[FooWithLongNan] error: cannot find attribute `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:28:3 | -LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` +LL | #[attr_proc_macra] + | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` | ::: $DIR/auxiliary/test-macros.rs:20:1 | -LL | / pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { -LL | | TokenStream::new() -LL | | } - | |_- similarly named attribute macro `attr_proc_macro` defined here +LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { + | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | -LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` +LL | #[derive(FooWithLongNan)] + | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` | ::: $DIR/auxiliary/derive-foo.rs:11:1 | -LL | / pub fn derive_foo(input: TokenStream) -> TokenStream { -LL | | "".parse().unwrap() -LL | | } - | |_- similarly named derive macro `FooWithLongName` defined here +LL | pub fn derive_foo(input: TokenStream) -> TokenStream { + | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index c7497afd0257d..a176a19da08a2 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -16,19 +16,13 @@ LL | type A = Baz; // Misspelled type name. error[E0412]: cannot find type `Opiton` in this scope --> $DIR/levenshtein.rs:12:10 | -LL | type B = Opiton; // Misspelled type name from the prelude. - | ^^^^^^ help: an enum with a similar name exists: `Option` +LL | type B = Opiton; // Misspelled type name from the prelude. + | ^^^^^^ help: an enum with a similar name exists: `Option` | ::: $SRC_DIR/libcore/option.rs:LL:COL | -LL | / pub enum Option { -LL | | /// No value -LL | | #[stable(feature = "rust1", since = "1.0.0")] -LL | | None, -... | -LL | | Some(#[stable(feature = "rust1", since = "1.0.0")] T), -LL | | } - | |_- similarly named enum `Option` defined here +LL | pub enum Option { + | ------------------ similarly named enum `Option` defined here error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:16:14 diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index d91b1cc707cb7..952ed26ccc07a 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -22,7 +22,7 @@ LL | #[tests] ::: $SRC_DIR/libcore/macros.rs:LL:COL | LL | pub macro test($item:item) { /* compiler built-in */ } - | ------------------------------------------------------ similarly named attribute macro `test` defined here + | -------------------------- similarly named attribute macro `test` defined here error: cannot find attribute `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 From 6d97718886eadcbce29950db8fc05dc86f7d89d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Jan 2020 12:22:47 -0800 Subject: [PATCH 0194/1253] ./x.py fmt --- src/librustc_resolve/diagnostics.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 411a72447a4f6..e3ae5672d4008 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -782,10 +782,11 @@ impl<'a> Resolver<'a> { ); let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { LOCAL_CRATE => self.definitions.opt_span(def_id), - _ => Some(self.session.source_map().def_span(self.cstore().get_span_untracked( - def_id, - self.session, - ))), + _ => Some( + self.session + .source_map() + .def_span(self.cstore().get_span_untracked(def_id, self.session)), + ), }); if let Some(span) = def_span { err.span_label( From 38a3506c451d097ed19263b3734421b3e5ee5bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Jan 2020 12:59:24 -0800 Subject: [PATCH 0195/1253] Ignore platforms that can't point to std --- .../ui/derives/deriving-meta-unknown-trait.rs | 4 ++ .../deriving-meta-unknown-trait.stderr | 11 +++-- src/test/ui/issues/issue-17546.rs | 4 ++ src/test/ui/issues/issue-17546.stderr | 8 ++-- src/test/ui/issues/issue-7607-1.rs | 4 ++ src/test/ui/issues/issue-7607-1.stderr | 6 +-- src/test/ui/macros/macro-name-typo.rs | 4 ++ src/test/ui/macros/macro-name-typo.stderr | 2 +- .../ui/macros/macro-path-prelude-fail-3.rs | 4 ++ .../macros/macro-path-prelude-fail-3.stderr | 6 +-- src/test/ui/proc-macro/parent-source-spans.rs | 4 ++ .../ui/proc-macro/parent-source-spans.stderr | 42 ++++++++--------- src/test/ui/proc-macro/resolve-error.rs | 4 ++ src/test/ui/proc-macro/resolve-error.stderr | 45 ++++++++++++------- src/test/ui/resolve/levenshtein.rs | 4 ++ src/test/ui/resolve/levenshtein.stderr | 16 +++---- src/test/ui/suggestions/attribute-typos.rs | 4 ++ .../ui/suggestions/attribute-typos.stderr | 12 ++--- 18 files changed, 120 insertions(+), 64 deletions(-) diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.rs b/src/test/ui/derives/deriving-meta-unknown-trait.rs index 6463a7664de93..d1af5b458cc0a 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.rs +++ b/src/test/ui/derives/deriving-meta-unknown-trait.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl #[derive(Eqr)] //~^ ERROR cannot find derive macro `Eqr` in this scope //~| ERROR cannot find derive macro `Eqr` in this scope diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index 666cc69f6e967..ead131323246a 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -1,19 +1,24 @@ error: cannot find derive macro `Eqr` in this scope - --> $DIR/deriving-meta-unknown-trait.rs:1:10 + --> $DIR/deriving-meta-unknown-trait.rs:5:10 | LL | #[derive(Eqr)] | ^^^ help: a derive macro with a similar name exists: `Eq` | ::: $SRC_DIR/libcore/cmp.rs:LL:COL | -LL | pub macro Eq($item:item) { /* compiler built-in */ } +LL | pub macro Eq($item:item) { | ------------------------ similarly named derive macro `Eq` defined here error: cannot find derive macro `Eqr` in this scope - --> $DIR/deriving-meta-unknown-trait.rs:1:10 + --> $DIR/deriving-meta-unknown-trait.rs:5:10 | LL | #[derive(Eqr)] | ^^^ help: a derive macro with a similar name exists: `Eq` + | + ::: $SRC_DIR/libcore/cmp.rs:LL:COL + | +LL | pub macro Eq($item:item) { + | ------------------------ similarly named derive macro `Eq` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17546.rs b/src/test/ui/issues/issue-17546.rs index dbfdad25e5be8..c93a03cdec66a 100644 --- a/src/test/ui/issues/issue-17546.rs +++ b/src/test/ui/issues/issue-17546.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl use foo::MyEnum::Result; use foo::NoResult; // Through a re-export diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr index 5bbe6d3b17176..2d532cdb9d8a9 100644 --- a/src/test/ui/issues/issue-17546.stderr +++ b/src/test/ui/issues/issue-17546.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `NoResult` - --> $DIR/issue-17546.rs:12:17 + --> $DIR/issue-17546.rs:16:17 | LL | fn new() -> NoResult { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | fn new() -> Result { | ^^^^^^ error[E0573]: expected type, found variant `Result` - --> $DIR/issue-17546.rs:22:17 + --> $DIR/issue-17546.rs:26:17 | LL | fn new() -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type @@ -37,7 +37,7 @@ LL | use std::result::Result; and 1 other candidate error[E0573]: expected type, found variant `Result` - --> $DIR/issue-17546.rs:28:13 + --> $DIR/issue-17546.rs:32:13 | LL | fn new() -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type @@ -55,7 +55,7 @@ LL | use std::result::Result; and 1 other candidate error[E0573]: expected type, found variant `NoResult` - --> $DIR/issue-17546.rs:33:15 + --> $DIR/issue-17546.rs:37:15 | LL | fn newer() -> NoResult { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-7607-1.rs b/src/test/ui/issues/issue-7607-1.rs index 5221f2c529bc6..1571cd2bbf683 100644 --- a/src/test/ui/issues/issue-7607-1.rs +++ b/src/test/ui/issues/issue-7607-1.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl struct Foo { x: isize } diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr index 472f8e013a922..94f489e209e32 100644 --- a/src/test/ui/issues/issue-7607-1.stderr +++ b/src/test/ui/issues/issue-7607-1.stderr @@ -1,13 +1,13 @@ error[E0412]: cannot find type `Fo` in this scope - --> $DIR/issue-7607-1.rs:5:6 + --> $DIR/issue-7607-1.rs:9:6 | LL | impl Fo { | ^^ help: a trait with a similar name exists: `Fn` | ::: $SRC_DIR/libcore/ops/function.rs:LL:COL | -LL | pub trait Fn : FnMut { - | -------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here error: aborting due to previous error diff --git a/src/test/ui/macros/macro-name-typo.rs b/src/test/ui/macros/macro-name-typo.rs index 1ddc419d302ac..b2892f3b6c239 100644 --- a/src/test/ui/macros/macro-name-typo.rs +++ b/src/test/ui/macros/macro-name-typo.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl fn main() { printlx!("oh noes!"); //~ ERROR cannot find } diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index 5604341fa34dc..00afbde8932fc 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -1,5 +1,5 @@ error: cannot find macro `printlx` in this scope - --> $DIR/macro-name-typo.rs:2:5 + --> $DIR/macro-name-typo.rs:6:5 | LL | printlx!("oh noes!"); | ^^^^^^^ help: a macro with a similar name exists: `println` diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.rs b/src/test/ui/macros/macro-path-prelude-fail-3.rs index 68eb350a95614..3c3948ca3c361 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.rs +++ b/src/test/ui/macros/macro-path-prelude-fail-3.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl fn main() { inline!(); //~ ERROR cannot find macro `inline` in this scope } diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr index e26a914e243ee..536459067437d 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr @@ -1,12 +1,12 @@ error: cannot find macro `inline` in this scope - --> $DIR/macro-path-prelude-fail-3.rs:2:5 + --> $DIR/macro-path-prelude-fail-3.rs:6:5 | LL | inline!(); | ^^^^^^ help: a macro with a similar name exists: `line` | - ::: $SRC_DIR/libcore/macros.rs:LL:COL + ::: $SRC_DIR/libcore/macros/mod.rs:LL:COL | -LL | macro_rules! line { () => { /* compiler built-in */ } } +LL | macro_rules! line { | ----------------- similarly named macro `line` defined here error: aborting due to previous error diff --git a/src/test/ui/proc-macro/parent-source-spans.rs b/src/test/ui/proc-macro/parent-source-spans.rs index 7b2ffefb05b19..95a3f96951270 100644 --- a/src/test/ui/proc-macro/parent-source-spans.rs +++ b/src/test/ui/proc-macro/parent-source-spans.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl // aux-build:parent-source-spans.rs #![feature(decl_macro, proc_macro_hygiene)] diff --git a/src/test/ui/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr index 2a36ac78d78c1..9f0fefcfe6c03 100644 --- a/src/test/ui/proc-macro/parent-source-spans.stderr +++ b/src/test/ui/proc-macro/parent-source-spans.stderr @@ -1,5 +1,5 @@ error: first final: "hello" - --> $DIR/parent-source-spans.rs:15:12 + --> $DIR/parent-source-spans.rs:19:12 | LL | three!($a, $b); | ^^ @@ -8,7 +8,7 @@ LL | one!("hello", "world"); | ----------------------- in this macro invocation error: second final: "world" - --> $DIR/parent-source-spans.rs:15:16 + --> $DIR/parent-source-spans.rs:19:16 | LL | three!($a, $b); | ^^ @@ -17,7 +17,7 @@ LL | one!("hello", "world"); | ----------------------- in this macro invocation error: first parent: "hello" - --> $DIR/parent-source-spans.rs:9:5 + --> $DIR/parent-source-spans.rs:13:5 | LL | two!($a, $b); | ^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | one!("hello", "world"); | ----------------------- in this macro invocation error: second parent: "world" - --> $DIR/parent-source-spans.rs:9:5 + --> $DIR/parent-source-spans.rs:13:5 | LL | two!($a, $b); | ^^^^^^^^^^^^^ @@ -35,31 +35,31 @@ LL | one!("hello", "world"); | ----------------------- in this macro invocation error: first grandparent: "hello" - --> $DIR/parent-source-spans.rs:35:5 + --> $DIR/parent-source-spans.rs:39:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: second grandparent: "world" - --> $DIR/parent-source-spans.rs:35:5 + --> $DIR/parent-source-spans.rs:39:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: first source: "hello" - --> $DIR/parent-source-spans.rs:35:5 + --> $DIR/parent-source-spans.rs:39:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: second source: "world" - --> $DIR/parent-source-spans.rs:35:5 + --> $DIR/parent-source-spans.rs:39:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: first final: "yay" - --> $DIR/parent-source-spans.rs:15:12 + --> $DIR/parent-source-spans.rs:19:12 | LL | three!($a, $b); | ^^ @@ -68,7 +68,7 @@ LL | two!("yay", "rust"); | -------------------- in this macro invocation error: second final: "rust" - --> $DIR/parent-source-spans.rs:15:16 + --> $DIR/parent-source-spans.rs:19:16 | LL | three!($a, $b); | ^^ @@ -77,55 +77,55 @@ LL | two!("yay", "rust"); | -------------------- in this macro invocation error: first parent: "yay" - --> $DIR/parent-source-spans.rs:41:5 + --> $DIR/parent-source-spans.rs:45:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^^ error: second parent: "rust" - --> $DIR/parent-source-spans.rs:41:5 + --> $DIR/parent-source-spans.rs:45:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^^ error: first source: "yay" - --> $DIR/parent-source-spans.rs:41:5 + --> $DIR/parent-source-spans.rs:45:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^^ error: second source: "rust" - --> $DIR/parent-source-spans.rs:41:5 + --> $DIR/parent-source-spans.rs:45:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^^ error: first final: "hip" - --> $DIR/parent-source-spans.rs:47:12 + --> $DIR/parent-source-spans.rs:51:12 | LL | three!("hip", "hop"); | ^^^^^ error: second final: "hop" - --> $DIR/parent-source-spans.rs:47:19 + --> $DIR/parent-source-spans.rs:51:19 | LL | three!("hip", "hop"); | ^^^^^ error: first source: "hip" - --> $DIR/parent-source-spans.rs:47:12 + --> $DIR/parent-source-spans.rs:51:12 | LL | three!("hip", "hop"); | ^^^^^ error: second source: "hop" - --> $DIR/parent-source-spans.rs:47:19 + --> $DIR/parent-source-spans.rs:51:19 | LL | three!("hip", "hop"); | ^^^^^ error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:28:5 + --> $DIR/parent-source-spans.rs:32:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` @@ -139,7 +139,7 @@ LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), | --------------------------------------------------- similarly named tuple variant `Ok` defined here error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:28:5 + --> $DIR/parent-source-spans.rs:32:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` @@ -153,7 +153,7 @@ LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), | --------------------------------------------------- similarly named tuple variant `Ok` defined here error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:28:5 + --> $DIR/parent-source-spans.rs:32:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs index ad8a5bbb0f9ff..8ff36ff0a26e2 100644 --- a/src/test/ui/proc-macro/resolve-error.rs +++ b/src/test/ui/proc-macro/resolve-error.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl // aux-build:derive-foo.rs // aux-build:derive-clona.rs // aux-build:test-macros.rs diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index 61868f4203bb0..73a6ab1cfb910 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,5 +1,5 @@ error: cannot find macro `bang_proc_macrp` in this scope - --> $DIR/resolve-error.rs:60:5 + --> $DIR/resolve-error.rs:64:5 | LL | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` @@ -10,13 +10,13 @@ LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here error: cannot find macro `Dlona` in this scope - --> $DIR/resolve-error.rs:57:5 + --> $DIR/resolve-error.rs:61:5 | LL | Dlona!(); | ^^^^^ error: cannot find macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:54:5 + --> $DIR/resolve-error.rs:58:5 | LL | / macro_rules! attr_proc_mac { LL | | () => {} @@ -27,7 +27,7 @@ LL | attr_proc_macra!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` error: cannot find macro `FooWithLongNama` in this scope - --> $DIR/resolve-error.rs:51:5 + --> $DIR/resolve-error.rs:55:5 | LL | / macro_rules! FooWithLongNam { LL | | () => {} @@ -38,25 +38,30 @@ LL | FooWithLongNama!(); | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:45:10 + --> $DIR/resolve-error.rs:49:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:45:10 + --> $DIR/resolve-error.rs:49:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:40:10 + --> $DIR/resolve-error.rs:44:10 | LL | #[derive(Dlona)] | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | + ::: $DIR/auxiliary/derive-clona.rs:11:1 + | +LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { + | ------------------------------------------------------- similarly named derive macro `Clona` defined here error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:40:10 + --> $DIR/resolve-error.rs:44:10 | LL | #[derive(Dlona)] | ^^^^^ help: a derive macro with a similar name exists: `Clona` @@ -67,30 +72,35 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:35:10 + --> $DIR/resolve-error.rs:39:10 | LL | #[derive(Dlone)] | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | pub macro Clone($item:item) { + | --------------------------- similarly named derive macro `Clone` defined here error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:35:10 + --> $DIR/resolve-error.rs:39:10 | LL | #[derive(Dlone)] | ^^^^^ help: a derive macro with a similar name exists: `Clone` | ::: $SRC_DIR/libcore/clone.rs:LL:COL | -LL | pub macro Clone($item:item) { /* compiler built-in */ } +LL | pub macro Clone($item:item) { | --------------------------- similarly named derive macro `Clone` defined here error: cannot find attribute `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:32:3 + --> $DIR/resolve-error.rs:36:3 | LL | #[FooWithLongNan] | ^^^^^^^^^^^^^^ error: cannot find attribute `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:28:3 + --> $DIR/resolve-error.rs:32:3 | LL | #[attr_proc_macra] | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` @@ -101,7 +111,7 @@ LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:22:10 + --> $DIR/resolve-error.rs:26:10 | LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` @@ -112,10 +122,15 @@ LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:22:10 + --> $DIR/resolve-error.rs:26:10 | LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | + ::: $DIR/auxiliary/derive-foo.rs:11:1 + | +LL | pub fn derive_foo(input: TokenStream) -> TokenStream { + | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here error: aborting due to 14 previous errors diff --git a/src/test/ui/resolve/levenshtein.rs b/src/test/ui/resolve/levenshtein.rs index a6f4716256881..6a98782a9badf 100644 --- a/src/test/ui/resolve/levenshtein.rs +++ b/src/test/ui/resolve/levenshtein.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl const MAX_ITEM: usize = 10; fn foo_bar() {} diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index a176a19da08a2..a622d6cb34948 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -1,11 +1,11 @@ error[E0412]: cannot find type `esize` in this scope - --> $DIR/levenshtein.rs:5:11 + --> $DIR/levenshtein.rs:9:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. | ^^^^^ help: a builtin type with a similar name exists: `isize` error[E0412]: cannot find type `Baz` in this scope - --> $DIR/levenshtein.rs:10:10 + --> $DIR/levenshtein.rs:14:10 | LL | enum Bar { } | ------------ similarly named enum `Bar` defined here @@ -14,7 +14,7 @@ LL | type A = Baz; // Misspelled type name. | ^^^ help: an enum with a similar name exists: `Bar` error[E0412]: cannot find type `Opiton` in this scope - --> $DIR/levenshtein.rs:12:10 + --> $DIR/levenshtein.rs:16:10 | LL | type B = Opiton; // Misspelled type name from the prelude. | ^^^^^^ help: an enum with a similar name exists: `Option` @@ -25,13 +25,13 @@ LL | pub enum Option { | ------------------ similarly named enum `Option` defined here error[E0412]: cannot find type `Baz` in this scope - --> $DIR/levenshtein.rs:16:14 + --> $DIR/levenshtein.rs:20:14 | LL | type A = Baz; // No suggestion here, Bar is not visible | ^^^ not found in this scope error[E0425]: cannot find value `MAXITEM` in this scope - --> $DIR/levenshtein.rs:24:20 + --> $DIR/levenshtein.rs:28:20 | LL | const MAX_ITEM: usize = 10; | --------------------------- similarly named constant `MAX_ITEM` defined here @@ -40,7 +40,7 @@ LL | let v = [0u32; MAXITEM]; // Misspelled constant name. | ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM` error[E0425]: cannot find function `foobar` in this scope - --> $DIR/levenshtein.rs:26:5 + --> $DIR/levenshtein.rs:30:5 | LL | fn foo_bar() {} | --------------- similarly named function `foo_bar` defined here @@ -49,7 +49,7 @@ LL | foobar(); // Misspelled function name. | ^^^^^^ help: a function with a similar name exists: `foo_bar` error[E0412]: cannot find type `first` in module `m` - --> $DIR/levenshtein.rs:28:15 + --> $DIR/levenshtein.rs:32:15 | LL | pub struct First; | ----------------- similarly named struct `First` defined here @@ -58,7 +58,7 @@ LL | let b: m::first = m::second; // Misspelled item in module. | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` error[E0425]: cannot find value `second` in module `m` - --> $DIR/levenshtein.rs:28:26 + --> $DIR/levenshtein.rs:32:26 | LL | pub struct Second; | ------------------ similarly named unit struct `Second` defined here diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs index 7c8231bbb24f8..e1e3317093a31 100644 --- a/src/test/ui/suggestions/attribute-typos.rs +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -1,3 +1,7 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl #[deprcated] //~ ERROR cannot find attribute `deprcated` in this scope fn foo() {} diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index 952ed26ccc07a..a0943592539af 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler - --> $DIR/attribute-typos.rs:7:3 + --> $DIR/attribute-typos.rs:11:3 | LL | #[rustc_err] | ^^^^^^^^^ @@ -8,24 +8,24 @@ LL | #[rustc_err] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: cannot find attribute `rustc_err` in this scope - --> $DIR/attribute-typos.rs:7:3 + --> $DIR/attribute-typos.rs:11:3 | LL | #[rustc_err] | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error` error: cannot find attribute `tests` in this scope - --> $DIR/attribute-typos.rs:4:3 + --> $DIR/attribute-typos.rs:8:3 | LL | #[tests] | ^^^^^ help: an attribute macro with a similar name exists: `test` | - ::: $SRC_DIR/libcore/macros.rs:LL:COL + ::: $SRC_DIR/libcore/macros/mod.rs:LL:COL | -LL | pub macro test($item:item) { /* compiler built-in */ } +LL | pub macro test($item:item) { | -------------------------- similarly named attribute macro `test` defined here error: cannot find attribute `deprcated` in this scope - --> $DIR/attribute-typos.rs:1:3 + --> $DIR/attribute-typos.rs:5:3 | LL | #[deprcated] | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` From 799efd3615f468c1382c61fe73b137fcffcd0a78 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 22:29:57 +0000 Subject: [PATCH 0196/1253] Fix issue with using `self` module via indirection --- src/librustc_privacy/lib.rs | 3 +++ src/test/ui/issues/issue-68103.rs | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 src/test/ui/issues/issue-68103.rs diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a96d59340237d..70d4841ec244b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -652,6 +652,9 @@ impl EmbargoVisitor<'tcx> { if let Some(item) = module .res .and_then(|res| res.mod_def_id()) + // If the module is `self`, i.e. the current crate, + // there will be no corresponding item. + .filter(|def_id| def_id.index != CRATE_DEF_INDEX || def_id.krate != LOCAL_CRATE) .and_then(|def_id| self.tcx.hir().as_local_hir_id(def_id)) .map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id)) { diff --git a/src/test/ui/issues/issue-68103.rs b/src/test/ui/issues/issue-68103.rs new file mode 100644 index 0000000000000..e775678fc6053 --- /dev/null +++ b/src/test/ui/issues/issue-68103.rs @@ -0,0 +1,6 @@ +// check-pass + +pub extern crate self as name; +pub use name::name as bug; + +fn main() {} From f3ce14479c5297521edfe70c8e4ef7c6d1a83536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 31 Dec 2019 14:01:38 +0100 Subject: [PATCH 0197/1253] Run codegen unit partitioning and assert_symbols_are_distinct in parallel --- src/librustc_mir/monomorphize/partitioning.rs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 8fa41cab19076..0def51a6a33e5 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -104,6 +104,7 @@ use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sync; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::symbol::Symbol; @@ -796,6 +797,8 @@ where I: Iterator>, 'tcx: 'a, { + let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct"); + let mut symbols: Vec<_> = mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect(); @@ -869,18 +872,23 @@ fn collect_and_partition_mono_items( tcx.sess.abort_if_errors(); - assert_symbols_are_distinct(tcx, items.iter()); - - let strategy = if tcx.sess.opts.incremental.is_some() { - PartitioningStrategy::PerModule - } else { - PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) - }; - - let codegen_units = partition(tcx, items.iter().cloned(), strategy, &inlining_map) - .into_iter() - .map(Arc::new) - .collect::>(); + let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || { + sync::join( + || { + let strategy = if tcx.sess.opts.incremental.is_some() { + PartitioningStrategy::PerModule + } else { + PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) + }; + + partition(tcx, items.iter().cloned(), strategy, &inlining_map) + .into_iter() + .map(Arc::new) + .collect::>() + }, + || assert_symbols_are_distinct(tcx, items.iter()), + ) + }); let mono_items: DefIdSet = items .iter() From 4beeadda3c137c8c8d66ba6b1bb3fb0be9b37b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 31 Dec 2019 14:27:20 +0100 Subject: [PATCH 0198/1253] Fix a deadlock --- src/librustc_mir/monomorphize/collector.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 41fbfd22e50af..422a1ccd9b574 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -194,7 +194,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_index::bit_set::GrowableBitSet; - +use smallvec::SmallVec; use std::iter; #[derive(PartialEq)] @@ -227,9 +227,7 @@ impl<'tcx> InliningMap<'tcx> { } } - fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: I) - where - I: Iterator, bool)> + ExactSizeIterator, + fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) { assert!(!self.index.contains_key(&source)); @@ -240,9 +238,9 @@ impl<'tcx> InliningMap<'tcx> { self.targets.reserve(new_items_count); self.inlines.ensure(new_items_count_total); - for (i, (target, inline)) in new_targets.enumerate() { - self.targets.push(target); - if inline { + for (i, (target, inline)) in new_targets.iter().enumerate() { + self.targets.push(*target); + if *inline { self.inlines.insert(i + start_index); } } @@ -403,10 +401,12 @@ fn record_accesses<'tcx>( mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy }; - let accesses = - callees.into_iter().map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))); + let accesses: SmallVec<[_; 128]> = callees + .into_iter() + .map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))) + .collect(); - inlining_map.lock_mut().record_accesses(caller, accesses); + inlining_map.lock_mut().record_accesses(caller, &accesses); } fn check_recursion_limit<'tcx>( From 51a73eb4fbbf2ec74c6a86942780fc2600811540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 31 Dec 2019 14:28:36 +0100 Subject: [PATCH 0199/1253] Avoid a duplicate hash map lookup --- src/librustc_mir/monomorphize/collector.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 422a1ccd9b574..e85e842031dbb 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -227,10 +227,7 @@ impl<'tcx> InliningMap<'tcx> { } } - fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) - { - assert!(!self.index.contains_key(&source)); - + fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) { let start_index = self.targets.len(); let new_items_count = new_targets.len(); let new_items_count_total = new_items_count + self.targets.len(); @@ -246,7 +243,7 @@ impl<'tcx> InliningMap<'tcx> { } let end_index = self.targets.len(); - self.index.insert(source, (start_index, end_index)); + assert!(self.index.insert(source, (start_index, end_index)).is_none()); } // Internally iterate over all items referenced by `source` which will be From 4a647167e64c77c72a074c354543bbe9dacb2d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 11 Jan 2020 00:38:10 +0100 Subject: [PATCH 0200/1253] Add a comment --- src/librustc_mir/monomorphize/collector.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index e85e842031dbb..511a5fbc61795 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -398,6 +398,9 @@ fn record_accesses<'tcx>( mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy }; + // We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock. + // FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec` + // instead to avoid creating this `SmallVec`. let accesses: SmallVec<[_; 128]> = callees .into_iter() .map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))) From 48cad460bc664d110c013b02a21ede7612f1a8e6 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 11 Jan 2020 10:15:54 +0900 Subject: [PATCH 0201/1253] Fix test not to depend on environment --- src/test/ui/macros/issue-68058.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/test/ui/macros/issue-68058.rs b/src/test/ui/macros/issue-68058.rs index 7679f8eaa7945..24da2620c2eaf 100644 --- a/src/test/ui/macros/issue-68058.rs +++ b/src/test/ui/macros/issue-68058.rs @@ -1,15 +1,14 @@ // check-pass -macro_rules! def_target { - ($target: expr) => { - #[target_feature(enable=$target)] - unsafe fn f() { - #[target_feature(enable=$target)] +macro_rules! foo { + ($doc: expr) => { + fn f() { + #[doc = $doc] () } }; } -def_target!("avx2"); +foo!("doc"); fn main() {} From 8f1df30d06072f03407654b1cde11a1a067bdfad Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 10 Jan 2020 16:12:26 -0800 Subject: [PATCH 0202/1253] Only require `allow_internal_unstable` for stable `const fn` --- .../transform/qualify_min_const_fn.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index fcdabb29cd0e2..74b21435eaee4 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -281,8 +281,21 @@ fn check_place( Ok(()) } -/// Returns whether `allow_internal_unstable(..., , ...)` is present. +/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`. fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { + // All features require that the corresponding gate be enabled. + if !tcx.features().enabled(feature_gate) { + return false; + } + + // If this crate is not using stability attributes, or this function is not claiming to be a + // stable `const fn`, that is all that is required. + if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) { + return true; + } + + // However, we cannot allow stable `const fn`s to use unstable features without an explicit + // opt-in via `allow_internal_unstable`. attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic()) .map_or(false, |mut features| features.any(|name| name == feature_gate)) } From 088a1808d22e571dbf83f477d94ea9c78ccc3219 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 Jan 2020 00:19:09 +0000 Subject: [PATCH 0203/1253] Add suggestions when encountering chained comparisons --- src/librustc_parse/parser/diagnostics.rs | 83 +++++++-- src/librustc_parse/parser/expr.rs | 42 ++--- src/test/ui/did_you_mean/issue-40396.rs | 6 +- src/test/ui/did_you_mean/issue-40396.stderr | 22 ++- .../parser/chained-comparison-suggestion.rs | 40 +++++ .../chained-comparison-suggestion.stderr | 159 ++++++++++++++++++ .../require-parens-for-chained-comparison.rs | 12 +- ...quire-parens-for-chained-comparison.stderr | 20 ++- 8 files changed, 335 insertions(+), 49 deletions(-) create mode 100644 src/test/ui/parser/chained-comparison-suggestion.rs create mode 100644 src/test/ui/parser/chained-comparison-suggestion.stderr diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 9abfbc698c5cf..ecbd183b6e929 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_error_codes::*; use rustc_errors::{pluralize, struct_span_err}; use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult}; +use rustc_span::source_map::Spanned; use rustc_span::symbol::kw; use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP}; use syntax::ast::{ @@ -500,6 +501,58 @@ impl<'a> Parser<'a> { } } + /// Check to see if a pair of chained operators looks like an attempt at chained comparison, + /// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or + /// parenthesising the leftmost comparison. + fn attempt_chained_comparison_suggestion( + &mut self, + err: &mut DiagnosticBuilder<'_>, + inner_op: &Expr, + outer_op: &Spanned, + ) { + if let ExprKind::Binary(op, ref l1, ref r1) = inner_op.kind { + match (op.node, &outer_op.node) { + // `x < y < z` and friends. + (BinOpKind::Lt, AssocOp::Less) | (BinOpKind::Lt, AssocOp::LessEqual) | + (BinOpKind::Le, AssocOp::LessEqual) | (BinOpKind::Le, AssocOp::Less) | + // `x > y > z` and friends. + (BinOpKind::Gt, AssocOp::Greater) | (BinOpKind::Gt, AssocOp::GreaterEqual) | + (BinOpKind::Ge, AssocOp::GreaterEqual) | (BinOpKind::Ge, AssocOp::Greater) => { + let expr_to_str = |e: &Expr| { + self.span_to_snippet(e.span) + .unwrap_or_else(|_| pprust::expr_to_string(&e)) + }; + err.span_suggestion( + inner_op.span.to(outer_op.span), + "split the comparison into two...", + format!( + "{} {} {} && {} {}", + expr_to_str(&l1), + op.node.to_string(), + expr_to_str(&r1), + expr_to_str(&r1), + outer_op.node.to_ast_binop().unwrap().to_string(), + ), + Applicability::MaybeIncorrect, + ); + err.span_suggestion( + inner_op.span.to(outer_op.span), + "...or parenthesize one of the comparisons", + format!( + "({} {} {}) {}", + expr_to_str(&l1), + op.node.to_string(), + expr_to_str(&r1), + outer_op.node.to_ast_binop().unwrap().to_string(), + ), + Applicability::MaybeIncorrect, + ); + } + _ => {} + } + } + } + /// Produces an error if comparison operators are chained (RFC #558). /// We only need to check the LHS, not the RHS, because all comparison ops have same /// precedence (see `fn precedence`) and are left-associative (see `fn fixity`). @@ -515,27 +568,31 @@ impl<'a> Parser<'a> { /// / \ /// inner_op r2 /// / \ - /// l1 r1 + /// l1 r1 pub(super) fn check_no_chained_comparison( &mut self, - lhs: &Expr, - outer_op: &AssocOp, + inner_op: &Expr, + outer_op: &Spanned, ) -> PResult<'a, Option>> { debug_assert!( - outer_op.is_comparison(), + outer_op.node.is_comparison(), "check_no_chained_comparison: {:?} is not comparison", - outer_op, + outer_op.node, ); let mk_err_expr = |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new()))); - match lhs.kind { + match inner_op.kind { ExprKind::Binary(op, _, _) if op.node.is_comparison() => { // Respan to include both operators. let op_span = op.span.to(self.prev_span); - let mut err = self - .struct_span_err(op_span, "chained comparison operators require parentheses"); + let mut err = + self.struct_span_err(op_span, "comparison operators cannot be chained"); + + // If it looks like a genuine attempt to chain operators (as opposed to a + // misformatted turbofish, for instance), suggest a correct form. + self.attempt_chained_comparison_suggestion(&mut err, inner_op, outer_op); let suggest = |err: &mut DiagnosticBuilder<'_>| { err.span_suggestion_verbose( @@ -547,12 +604,12 @@ impl<'a> Parser<'a> { }; if op.node == BinOpKind::Lt && - *outer_op == AssocOp::Less || // Include `<` to provide this recommendation - *outer_op == AssocOp::Greater + outer_op.node == AssocOp::Less || // Include `<` to provide this recommendation + outer_op.node == AssocOp::Greater // even in a case like the following: { // Foo>> - if *outer_op == AssocOp::Less { + if outer_op.node == AssocOp::Less { let snapshot = self.clone(); self.bump(); // So far we have parsed `foo Parser<'a> { // FIXME: actually check that the two expressions in the binop are // paths and resynthesize new fn call expression instead of using // `ExprKind::Err` placeholder. - mk_err_expr(self, lhs.span.to(self.prev_span)) + mk_err_expr(self, inner_op.span.to(self.prev_span)) } Err(mut expr_err) => { expr_err.cancel(); @@ -606,7 +663,7 @@ impl<'a> Parser<'a> { // FIXME: actually check that the two expressions in the binop are // paths and resynthesize new fn call expression instead of using // `ExprKind::Err` placeholder. - mk_err_expr(self, lhs.span.to(self.prev_span)) + mk_err_expr(self, inner_op.span.to(self.prev_span)) } } } else { diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 90f15375aec42..3c286d363c9db 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -5,7 +5,7 @@ use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; use rustc_errors::{Applicability, PResult}; -use rustc_span::source_map::{self, Span}; +use rustc_span::source_map::{self, Span, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; use std::mem; use syntax::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, DUMMY_NODE_ID}; @@ -181,17 +181,17 @@ impl<'a> Parser<'a> { }; let cur_op_span = self.token.span; - let restrictions = if op.is_assign_like() { + let restrictions = if op.node.is_assign_like() { self.restrictions & Restrictions::NO_STRUCT_LITERAL } else { self.restrictions }; - let prec = op.precedence(); + let prec = op.node.precedence(); if prec < min_prec { break; } // Check for deprecated `...` syntax - if self.token == token::DotDotDot && op == AssocOp::DotDotEq { + if self.token == token::DotDotDot && op.node == AssocOp::DotDotEq { self.err_dotdotdot_syntax(self.token.span); } @@ -200,11 +200,12 @@ impl<'a> Parser<'a> { } self.bump(); - if op.is_comparison() { + if op.node.is_comparison() { if let Some(expr) = self.check_no_chained_comparison(&lhs, &op)? { return Ok(expr); } } + let op = op.node; // Special cases: if op == AssocOp::As { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; @@ -298,7 +299,7 @@ impl<'a> Parser<'a> { } fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool { - match (self.expr_is_complete(lhs), self.check_assoc_op()) { + match (self.expr_is_complete(lhs), self.check_assoc_op().map(|op| op.node)) { // Semi-statement forms are odd: // See https://github.com/rust-lang/rust/issues/29071 (true, None) => false, @@ -343,19 +344,22 @@ impl<'a> Parser<'a> { /// The method does not advance the current token. /// /// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively. - fn check_assoc_op(&self) -> Option { - match (AssocOp::from_token(&self.token), &self.token.kind) { - (op @ Some(_), _) => op, - (None, token::Ident(sym::and, false)) => { - self.error_bad_logical_op("and", "&&", "conjunction"); - Some(AssocOp::LAnd) - } - (None, token::Ident(sym::or, false)) => { - self.error_bad_logical_op("or", "||", "disjunction"); - Some(AssocOp::LOr) - } - _ => None, - } + fn check_assoc_op(&self) -> Option> { + Some(Spanned { + node: match (AssocOp::from_token(&self.token), &self.token.kind) { + (Some(op), _) => op, + (None, token::Ident(sym::and, false)) => { + self.error_bad_logical_op("and", "&&", "conjunction"); + AssocOp::LAnd + } + (None, token::Ident(sym::or, false)) => { + self.error_bad_logical_op("or", "||", "disjunction"); + AssocOp::LOr + } + _ => return None, + }, + span: self.token.span, + }) } /// Error on `and` and `or` suggesting `&&` and `||` respectively. diff --git a/src/test/ui/did_you_mean/issue-40396.rs b/src/test/ui/did_you_mean/issue-40396.rs index 1893355205433..e4e94bb949237 100644 --- a/src/test/ui/did_you_mean/issue-40396.rs +++ b/src/test/ui/did_you_mean/issue-40396.rs @@ -1,8 +1,8 @@ fn main() { (0..13).collect>(); - //~^ ERROR chained comparison + //~^ ERROR comparison operators cannot be chained Vec::new(); - //~^ ERROR chained comparison + //~^ ERROR comparison operators cannot be chained (0..13).collect(); - //~^ ERROR chained comparison + //~^ ERROR comparison operators cannot be chained } diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr index 749d1093ccab8..f952136a7bfe3 100644 --- a/src/test/ui/did_you_mean/issue-40396.stderr +++ b/src/test/ui/did_you_mean/issue-40396.stderr @@ -1,15 +1,23 @@ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/issue-40396.rs:2:20 | LL | (0..13).collect>(); | ^^^^^ | +help: split the comparison into two... + | +LL | (0..13).collect < Vec && Vec >(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | ((0..13).collect < Vec) >(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `::<...>` instead of `<...>` to specify type arguments | LL | (0..13).collect::>(); | ^^ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/issue-40396.rs:4:8 | LL | Vec::new(); @@ -20,12 +28,20 @@ help: use `::<...>` instead of `<...>` to specify type arguments LL | Vec::::new(); | ^^ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/issue-40396.rs:6:20 | LL | (0..13).collect(); | ^^^^^ | +help: split the comparison into two... + | +LL | (0..13).collect < Vec && Vec (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | ((0..13).collect < Vec) (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `::<...>` instead of `<...>` to specify type arguments | LL | (0..13).collect::(); diff --git a/src/test/ui/parser/chained-comparison-suggestion.rs b/src/test/ui/parser/chained-comparison-suggestion.rs new file mode 100644 index 0000000000000..0431196f1744e --- /dev/null +++ b/src/test/ui/parser/chained-comparison-suggestion.rs @@ -0,0 +1,40 @@ +// Check that we get nice suggestions when attempting a chained comparison. + +fn comp1() { + 1 < 2 <= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp2() { + 1 < 2 < 3; //~ ERROR comparison operators cannot be chained +} + +fn comp3() { + 1 <= 2 < 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp4() { + 1 <= 2 <= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp5() { + 1 > 2 >= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp6() { + 1 > 2 > 3; //~ ERROR comparison operators cannot be chained +} + +fn comp7() { + 1 >= 2 > 3; //~ ERROR comparison operators cannot be chained +} + +fn comp8() { + 1 >= 2 >= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/parser/chained-comparison-suggestion.stderr b/src/test/ui/parser/chained-comparison-suggestion.stderr new file mode 100644 index 0000000000000..5c10a4599dd03 --- /dev/null +++ b/src/test/ui/parser/chained-comparison-suggestion.stderr @@ -0,0 +1,159 @@ +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:4:7 + | +LL | 1 < 2 <= 3; + | ^^^^^^ + | +help: split the comparison into two... + | +LL | 1 < 2 && 2 <= 3; + | ^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 < 2) <= 3; + | ^^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:9:7 + | +LL | 1 < 2 < 3; + | ^^^^^ + | + = help: use `::<...>` instead of `<...>` to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments +help: split the comparison into two... + | +LL | 1 < 2 && 2 < 3; + | ^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 < 2) < 3; + | ^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:13:7 + | +LL | 1 <= 2 < 3; + | ^^^^^^ + | +help: split the comparison into two... + | +LL | 1 <= 2 && 2 < 3; + | ^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 <= 2) < 3; + | ^^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:18:7 + | +LL | 1 <= 2 <= 3; + | ^^^^^^^ + | +help: split the comparison into two... + | +LL | 1 <= 2 && 2 <= 3; + | ^^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 <= 2) <= 3; + | ^^^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:23:7 + | +LL | 1 > 2 >= 3; + | ^^^^^^ + | +help: split the comparison into two... + | +LL | 1 > 2 && 2 >= 3; + | ^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 > 2) >= 3; + | ^^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:28:7 + | +LL | 1 > 2 > 3; + | ^^^^^ + | + = help: use `::<...>` instead of `<...>` to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments +help: split the comparison into two... + | +LL | 1 > 2 && 2 > 3; + | ^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 > 2) > 3; + | ^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:32:7 + | +LL | 1 >= 2 > 3; + | ^^^^^^ + | + = help: use `::<...>` instead of `<...>` to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments +help: split the comparison into two... + | +LL | 1 >= 2 && 2 > 3; + | ^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 >= 2) > 3; + | ^^^^^^^^^^ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:36:7 + | +LL | 1 >= 2 >= 3; + | ^^^^^^^ + | +help: split the comparison into two... + | +LL | 1 >= 2 && 2 >= 3; + | ^^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (1 >= 2) >= 3; + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:4:14 + | +LL | 1 < 2 <= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:13:14 + | +LL | 1 <= 2 < 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:18:15 + | +LL | 1 <= 2 <= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:23:14 + | +LL | 1 > 2 >= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:36:15 + | +LL | 1 >= 2 >= 3; + | ^ expected `bool`, found integer + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs index 9c7a25d589a1f..e27b03dddc5be 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.rs +++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs @@ -3,24 +3,26 @@ struct X; fn main() { false == false == false; - //~^ ERROR chained comparison operators require parentheses + //~^ ERROR comparison operators cannot be chained false == 0 < 2; - //~^ ERROR chained comparison operators require parentheses + //~^ ERROR comparison operators cannot be chained //~| ERROR mismatched types //~| ERROR mismatched types f(); - //~^ ERROR chained comparison operators require parentheses + //~^ ERROR comparison operators cannot be chained //~| HELP use `::<...>` instead of `<...>` to specify type arguments f, Option>>(1, 2); - //~^ ERROR chained comparison operators require parentheses + //~^ ERROR comparison operators cannot be chained + //~| HELP split the comparison into two... + //~| ...or parenthesize one of the comparisons //~| HELP use `::<...>` instead of `<...>` to specify type arguments use std::convert::identity; let _ = identity; - //~^ ERROR chained comparison operators require parentheses + //~^ ERROR comparison operators cannot be chained //~| HELP use `::<...>` instead of `<...>` to specify type arguments //~| HELP or use `(...)` if you meant to specify fn arguments } diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr index bece9a388008c..44edf2de7f8de 100644 --- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr +++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr @@ -1,16 +1,16 @@ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/require-parens-for-chained-comparison.rs:5:11 | LL | false == false == false; | ^^^^^^^^^^^ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/require-parens-for-chained-comparison.rs:8:11 | LL | false == 0 < 2; | ^^^^^^ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/require-parens-for-chained-comparison.rs:13:6 | LL | f(); @@ -21,19 +21,27 @@ help: use `::<...>` instead of `<...>` to specify type arguments LL | f::(); | ^^ -error: chained comparison operators require parentheses +error: comparison operators cannot be chained --> $DIR/require-parens-for-chained-comparison.rs:17:6 | LL | f, Option>>(1, 2); | ^^^^^^^^ | +help: split the comparison into two... + | +LL | f < Result && Result , Option>>(1, 2); + | ^^^^^^^^^^^^^^^^^^^^^^ +help: ...or parenthesize one of the comparisons + | +LL | (f < Result) , Option>>(1, 2); + | ^^^^^^^^^^^^^^ help: use `::<...>` instead of `<...>` to specify type arguments | LL | f::, Option>>(1, 2); | ^^ -error: chained comparison operators require parentheses - --> $DIR/require-parens-for-chained-comparison.rs:22:21 +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:24:21 | LL | let _ = identity; | ^^^^ From 6007641d2101e6489aa6b9a3ba84b6a2b9b04fa5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 11:41:57 +0100 Subject: [PATCH 0204/1253] gating diagnostics -> rustc_session::parse --- Cargo.lock | 1 + src/librustc_session/Cargo.toml | 1 + src/librustc_session/parse.rs | 72 ++++++++++++++++++++++++++-- src/libsyntax/attr/builtin.rs | 3 +- src/libsyntax/feature_gate/check.rs | 73 ++--------------------------- src/libsyntax/lib.rs | 3 +- 6 files changed, 77 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 339389f8569e0..6116ae033875e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,6 +3866,7 @@ dependencies = [ "log", "num_cpus", "rustc_data_structures", + "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_fs_util", diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml index 47c23bc4dcf98..377ea141ed57c 100644 --- a/src/librustc_session/Cargo.toml +++ b/src/librustc_session/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" [dependencies] log = "0.4" +rustc_error_codes = { path = "../librustc_error_codes" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 6cc6a1ec276ca..2a5945d2b0595 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -6,10 +6,10 @@ use crate::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc, Once}; -use rustc_errors::{ - emitter::SilentEmitter, Applicability, ColorConfig, DiagnosticBuilder, Handler, -}; -use rustc_feature::UnstableFeatures; +use rustc_error_codes::E0658; +use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; +use rustc_errors::{error_code, Applicability, DiagnosticBuilder}; +use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{FilePathMapping, SourceMap}; @@ -62,6 +62,70 @@ impl GatedSpans { } } +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum GateStrength { + /// A hard error. (Most feature gates should use this.) + Hard, + /// Only a warning. (Use this only as backwards-compatibility demands.) + Soft, +} + +pub fn feature_err<'a>( + sess: &'a ParseSess, + feature: Symbol, + span: impl Into, + explain: &str, +) -> DiagnosticBuilder<'a> { + feature_err_issue(sess, feature, span, GateIssue::Language, explain) +} + +pub fn feature_err_issue<'a>( + sess: &'a ParseSess, + feature: Symbol, + span: impl Into, + issue: GateIssue, + explain: &str, +) -> DiagnosticBuilder<'a> { + leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) +} + +pub fn leveled_feature_err<'a>( + sess: &'a ParseSess, + feature: Symbol, + span: impl Into, + issue: GateIssue, + explain: &str, + level: GateStrength, +) -> DiagnosticBuilder<'a> { + let diag = &sess.span_diagnostic; + + let mut err = match level { + GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)), + GateStrength::Soft => diag.struct_span_warn(span, explain), + }; + + if let Some(n) = find_feature_issue(feature, issue) { + err.note(&format!( + "for more information, see https://github.com/rust-lang/rust/issues/{}", + n, + )); + } + + // #23973: do not suggest `#![feature(...)]` if we are in beta/stable + if sess.unstable_features.is_nightly_build() { + err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); + } + + // If we're on stable and only emitting a "soft" warning, add a note to + // clarify that the feature isn't "on" (rather than being on but + // warning-worthy). + if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft { + err.help("a nightly build of the compiler is required to enable this feature"); + } + + err +} + /// Info about a parsing session. pub struct ParseSess { pub span_diagnostic: Handler, diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 958e4373cc0ed..70f4f47621a34 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -2,9 +2,8 @@ use super::{mark_used, MetaItemKind}; use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; -use crate::feature_gate::feature_err; use crate::print::pprust; -use crate::sess::ParseSess; +use crate::sess::{feature_err, ParseSess}; use rustc_errors::{struct_span_err, Applicability, Handler}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 4eee4e943c2cd..2b49a296a082a 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -1,22 +1,21 @@ use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; use crate::attr; -use crate::sess::ParseSess; +use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess}; use crate::visit::{self, FnKind, Visitor}; use rustc_data_structures::fx::FxHashMap; use rustc_error_codes::*; -use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Handler}; -use rustc_feature::{find_feature_issue, GateIssue}; +use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; -use rustc_feature::{Feature, Features, State as FeatureState, UnstableFeatures}; +use rustc_feature::{Feature, Features, GateIssue, State as FeatureState, UnstableFeatures}; use rustc_feature::{ ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, }; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{MultiSpan, Span, DUMMY_SP}; +use rustc_span::{Span, DUMMY_SP}; use log::debug; @@ -53,70 +52,6 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: PostExpansionVisitor { parse_sess, features }.visit_attribute(attr) } -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum GateStrength { - /// A hard error. (Most feature gates should use this.) - Hard, - /// Only a warning. (Use this only as backwards-compatibility demands.) - Soft, -} - -pub fn feature_err<'a>( - sess: &'a ParseSess, - feature: Symbol, - span: impl Into, - explain: &str, -) -> DiagnosticBuilder<'a> { - feature_err_issue(sess, feature, span, GateIssue::Language, explain) -} - -pub fn feature_err_issue<'a>( - sess: &'a ParseSess, - feature: Symbol, - span: impl Into, - issue: GateIssue, - explain: &str, -) -> DiagnosticBuilder<'a> { - leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) -} - -fn leveled_feature_err<'a>( - sess: &'a ParseSess, - feature: Symbol, - span: impl Into, - issue: GateIssue, - explain: &str, - level: GateStrength, -) -> DiagnosticBuilder<'a> { - let diag = &sess.span_diagnostic; - - let mut err = match level { - GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)), - GateStrength::Soft => diag.struct_span_warn(span, explain), - }; - - if let Some(n) = find_feature_issue(feature, issue) { - err.note(&format!( - "for more information, see https://github.com/rust-lang/rust/issues/{}", - n, - )); - } - - // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if sess.unstable_features.is_nightly_build() { - err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); - } - - // If we're on stable and only emitting a "soft" warning, add a note to - // clarify that the feature isn't "on" (rather than being on but - // warning-worthy). - if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft { - err.help("a nightly build of the compiler is required to enable this feature"); - } - - err -} - struct PostExpansionVisitor<'a> { parse_sess: &'a ParseSess, features: &'a Features, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7ee4ca4603c9c..ffb0d7e7f9706 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -77,7 +77,8 @@ pub mod entry; pub mod expand; pub mod feature_gate { mod check; - pub use check::{check_attribute, check_crate, feature_err, feature_err_issue, get_features}; + pub use check::{check_attribute, check_crate, get_features}; + pub use rustc_session::parse::{feature_err, feature_err_issue}; } pub mod mut_visit; pub mod ptr; From c944e6aac197ef37d4554fcc416dcff7ec4085c4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 11:55:00 +0100 Subject: [PATCH 0205/1253] document feature_err et. al --- src/librustc_session/parse.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 2a5945d2b0595..b0c6aefc00ca1 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -62,6 +62,8 @@ impl GatedSpans { } } +/// The strenght of a feature gate. +/// Either it is a `Hard` error, or only a `Soft` warning. #[derive(Debug, Copy, Clone, PartialEq)] pub enum GateStrength { /// A hard error. (Most feature gates should use this.) @@ -70,6 +72,20 @@ pub enum GateStrength { Soft, } +/// Construct a diagnostic for a language feature error due to the given `span`. +/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`. +/// +/// Example usage: +/// +/// ```ignore +/// feature_err( +/// parse_sess, +/// sym::stmt_expr_attributes, +/// attr.span, +/// "attributes on expressions are unstable", +/// ) +/// .emit(); +/// ``` pub fn feature_err<'a>( sess: &'a ParseSess, feature: Symbol, @@ -79,6 +95,10 @@ pub fn feature_err<'a>( feature_err_issue(sess, feature, span, GateIssue::Language, explain) } +/// Construct a diagnostic for a feature gate error. +/// +/// This variant allows you to control whether it is a library or language feature. +/// Almost always, you want to use this for a language feature. If so, prefer `feature_err`. pub fn feature_err_issue<'a>( sess: &'a ParseSess, feature: Symbol, @@ -89,6 +109,9 @@ pub fn feature_err_issue<'a>( leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) } +/// Construct a diagnostic for a feature gate error / warning. +/// +/// You should typically just use `feature_err` instead. pub fn leveled_feature_err<'a>( sess: &'a ParseSess, feature: Symbol, From 7c78090690cf78b453cf828babd3dd69eb276779 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 12:33:56 +0100 Subject: [PATCH 0206/1253] get_features -> rustc_parse::config --- src/librustc_parse/config.rs | 183 +++++++++++++++++++++++++++- src/libsyntax/feature_gate/check.rs | 175 +------------------------- src/libsyntax/lib.rs | 2 +- 3 files changed, 182 insertions(+), 178 deletions(-) diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index f2ffd9470ed76..df1e62d04d66d 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -9,15 +9,20 @@ //! [#64197]: https://github.com/rust-lang/rust/issues/64197 use crate::{parse_in, validate_attr}; -use rustc_errors::Applicability; -use rustc_feature::Features; -use rustc_span::edition::Edition; -use rustc_span::symbol::sym; -use rustc_span::Span; +use rustc_data_structures::fx::FxHashMap; +use rustc_error_codes::*; +use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; +use rustc_feature::{Feature, Features, State as FeatureState}; +use rustc_feature::{ + ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, +}; +use rustc_span::edition::{Edition, ALL_EDITIONS}; +use rustc_span::symbol::{sym, Symbol}; +use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Attribute, MetaItem}; use syntax::attr; use syntax::attr::HasAttrs; -use syntax::feature_gate::{feature_err, get_features}; +use syntax::feature_gate::feature_err; use syntax::mut_visit::*; use syntax::ptr::P; use syntax::sess::ParseSess; @@ -31,6 +36,172 @@ pub struct StripUnconfigured<'a> { pub features: Option<&'a Features>, } +fn get_features( + span_handler: &Handler, + krate_attrs: &[ast::Attribute], + crate_edition: Edition, + allow_features: &Option>, +) -> Features { + fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { + let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); + err.span_label(span, "feature has been removed"); + if let Some(reason) = reason { + err.note(reason); + } + err.emit(); + } + + fn active_features_up_to(edition: Edition) -> impl Iterator { + ACTIVE_FEATURES.iter().filter(move |feature| { + if let Some(feature_edition) = feature.edition { + feature_edition <= edition + } else { + false + } + }) + } + + let mut features = Features::default(); + let mut edition_enabled_features = FxHashMap::default(); + + for &edition in ALL_EDITIONS { + if edition <= crate_edition { + // The `crate_edition` implies its respective umbrella feature-gate + // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). + edition_enabled_features.insert(edition.feature_name(), edition); + } + } + + for feature in active_features_up_to(crate_edition) { + feature.set(&mut features, DUMMY_SP); + edition_enabled_features.insert(feature.name, crate_edition); + } + + // Process the edition umbrella feature-gates first, to ensure + // `edition_enabled_features` is completed before it's queried. + for attr in krate_attrs { + if !attr.check_name(sym::feature) { + continue; + } + + let list = match attr.meta_item_list() { + Some(list) => list, + None => continue, + }; + + for mi in list { + if !mi.is_word() { + continue; + } + + let name = mi.name_or_empty(); + + let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied(); + if let Some(edition) = edition { + if edition <= crate_edition { + continue; + } + + for feature in active_features_up_to(edition) { + // FIXME(Manishearth) there is currently no way to set + // lib features by edition + feature.set(&mut features, DUMMY_SP); + edition_enabled_features.insert(feature.name, edition); + } + } + } + } + + for attr in krate_attrs { + if !attr.check_name(sym::feature) { + continue; + } + + let list = match attr.meta_item_list() { + Some(list) => list, + None => continue, + }; + + let bad_input = |span| { + struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input") + }; + + for mi in list { + let name = match mi.ident() { + Some(ident) if mi.is_word() => ident.name, + Some(ident) => { + bad_input(mi.span()) + .span_suggestion( + mi.span(), + "expected just one word", + format!("{}", ident.name), + Applicability::MaybeIncorrect, + ) + .emit(); + continue; + } + None => { + bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit(); + continue; + } + }; + + if let Some(edition) = edition_enabled_features.get(&name) { + let msg = + &format!("the feature `{}` is included in the Rust {} edition", name, edition); + span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit(); + continue; + } + + if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { + // Handled in the separate loop above. + continue; + } + + let removed = REMOVED_FEATURES.iter().find(|f| name == f.name); + let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name); + if let Some(Feature { state, .. }) = removed.or(stable_removed) { + if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } = + state + { + feature_removed(span_handler, mi.span(), *reason); + continue; + } + } + + if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { + let since = Some(Symbol::intern(since)); + features.declared_lang_features.push((name, mi.span(), since)); + continue; + } + + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|&f| name.as_str() == *f).is_none() { + struct_span_err!( + span_handler, + mi.span(), + E0725, + "the feature `{}` is not in the list of allowed features", + name + ) + .emit(); + continue; + } + } + + if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) { + f.set(&mut features, mi.span()); + features.declared_lang_features.push((name, mi.span(), None)); + continue; + } + + features.declared_lib_features.push((name, mi.span())); + } + } + + features +} + // `cfg_attr`-process the crate's attributes and compute the crate's features. pub fn features( mut krate: ast::Crate, diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 2b49a296a082a..46a22f12678ee 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -4,18 +4,13 @@ use crate::attr; use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess}; use crate::visit::{self, FnKind, Visitor}; -use rustc_data_structures::fx::FxHashMap; use rustc_error_codes::*; -use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; +use rustc_errors::{struct_span_err, Handler}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; -use rustc_feature::{Feature, Features, GateIssue, State as FeatureState, UnstableFeatures}; -use rustc_feature::{ - ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, -}; -use rustc_span::edition::{Edition, ALL_EDITIONS}; +use rustc_feature::{Features, GateIssue, UnstableFeatures}; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::symbol::sym; +use rustc_span::Span; use log::debug; @@ -659,168 +654,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } -pub fn get_features( - span_handler: &Handler, - krate_attrs: &[ast::Attribute], - crate_edition: Edition, - allow_features: &Option>, -) -> Features { - fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { - let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); - err.span_label(span, "feature has been removed"); - if let Some(reason) = reason { - err.note(reason); - } - err.emit(); - } - - let mut features = Features::default(); - let mut edition_enabled_features = FxHashMap::default(); - - for &edition in ALL_EDITIONS { - if edition <= crate_edition { - // The `crate_edition` implies its respective umbrella feature-gate - // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). - edition_enabled_features.insert(edition.feature_name(), edition); - } - } - - for feature in active_features_up_to(crate_edition) { - feature.set(&mut features, DUMMY_SP); - edition_enabled_features.insert(feature.name, crate_edition); - } - - // Process the edition umbrella feature-gates first, to ensure - // `edition_enabled_features` is completed before it's queried. - for attr in krate_attrs { - if !attr.check_name(sym::feature) { - continue; - } - - let list = match attr.meta_item_list() { - Some(list) => list, - None => continue, - }; - - for mi in list { - if !mi.is_word() { - continue; - } - - let name = mi.name_or_empty(); - - let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied(); - if let Some(edition) = edition { - if edition <= crate_edition { - continue; - } - - for feature in active_features_up_to(edition) { - // FIXME(Manishearth) there is currently no way to set - // lib features by edition - feature.set(&mut features, DUMMY_SP); - edition_enabled_features.insert(feature.name, edition); - } - } - } - } - - for attr in krate_attrs { - if !attr.check_name(sym::feature) { - continue; - } - - let list = match attr.meta_item_list() { - Some(list) => list, - None => continue, - }; - - let bad_input = |span| { - struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input") - }; - - for mi in list { - let name = match mi.ident() { - Some(ident) if mi.is_word() => ident.name, - Some(ident) => { - bad_input(mi.span()) - .span_suggestion( - mi.span(), - "expected just one word", - format!("{}", ident.name), - Applicability::MaybeIncorrect, - ) - .emit(); - continue; - } - None => { - bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit(); - continue; - } - }; - - if let Some(edition) = edition_enabled_features.get(&name) { - let msg = - &format!("the feature `{}` is included in the Rust {} edition", name, edition); - span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit(); - continue; - } - - if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { - // Handled in the separate loop above. - continue; - } - - let removed = REMOVED_FEATURES.iter().find(|f| name == f.name); - let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name); - if let Some(Feature { state, .. }) = removed.or(stable_removed) { - if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } = - state - { - feature_removed(span_handler, mi.span(), *reason); - continue; - } - } - - if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { - let since = Some(Symbol::intern(since)); - features.declared_lang_features.push((name, mi.span(), since)); - continue; - } - - if let Some(allowed) = allow_features.as_ref() { - if allowed.iter().find(|&f| name.as_str() == *f).is_none() { - struct_span_err!( - span_handler, - mi.span(), - E0725, - "the feature `{}` is not in the list of allowed features", - name - ) - .emit(); - continue; - } - } - - if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) { - f.set(&mut features, mi.span()); - features.declared_lang_features.push((name, mi.span(), None)); - continue; - } - - features.declared_lib_features.push((name, mi.span())); - } - } - - features -} - -fn active_features_up_to(edition: Edition) -> impl Iterator { - ACTIVE_FEATURES.iter().filter(move |feature| { - if let Some(feature_edition) = feature.edition { feature_edition <= edition } else { false } - }) -} - pub fn check_crate( krate: &ast::Crate, parse_sess: &ParseSess, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index ffb0d7e7f9706..d266bf4bde08d 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -77,7 +77,7 @@ pub mod entry; pub mod expand; pub mod feature_gate { mod check; - pub use check::{check_attribute, check_crate, get_features}; + pub use check::{check_attribute, check_crate}; pub use rustc_session::parse::{feature_err, feature_err_issue}; } pub mod mut_visit; From 1af8c10bd42570ccbb112f3741fafbe6cf71ac67 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 12:42:42 +0100 Subject: [PATCH 0207/1253] simplify feature_err imports --- src/librustc/lint/levels.rs | 4 ++-- src/librustc/middle/stability.rs | 2 +- src/librustc_expand/expand.rs | 4 ++-- src/librustc_metadata/native_libs.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_mir/transform/check_consts/ops.rs | 2 +- src/librustc_parse/config.rs | 3 +-- src/librustc_passes/check_const.rs | 2 +- src/librustc_passes/stability.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/coercion.rs | 7 +++---- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 4 ++-- src/librustc_typeck/collect.rs | 6 +++--- src/libsyntax/lib.rs | 1 - 16 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 6ca98b44bf80c..e586ad1836c73 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -13,8 +13,8 @@ use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{sym, Symbol}; use syntax::ast; use syntax::attr; -use syntax::feature_gate; use syntax::print::pprust; +use syntax::sess::feature_err; use rustc_error_codes::*; @@ -223,7 +223,7 @@ impl<'a> LintLevelsBuilder<'a> { // don't have any lint names (`#[level(reason = "foo")]`) if let ast::LitKind::Str(rationale, _) = name_value.kind { if !self.sess.features_untracked().lint_reasons { - feature_gate::feature_err( + feature_err( &self.sess.parse_sess, sym::lint_reasons, item.span, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 93c23e40d2e2b..4874d65b2b0db 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -18,7 +18,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability}; -use syntax::feature_gate::feature_err_issue; +use syntax::sess::feature_err_issue; use std::num::NonZeroU32; diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 8426391a2f389..f20de93bdeb67 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -18,11 +18,11 @@ use rustc_span::{FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path}; use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use syntax::attr::{self, is_builtin_attr, HasAttrs}; -use syntax::feature_gate::{self, feature_err}; +use syntax::feature_gate; use syntax::mut_visit::*; use syntax::print::pprust; use syntax::ptr::P; -use syntax::sess::ParseSess; +use syntax::sess::{feature_err, ParseSess}; use syntax::token; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::util::map_in_place::MapInPlace; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index ae67efb966c96..9426d5e26f5e5 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -1,4 +1,5 @@ use rustc::middle::cstore::{self, NativeLibrary}; +use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashSet; @@ -10,7 +11,6 @@ use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; use syntax::attr; -use syntax::feature_gate::feature_err; crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new() }; diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index ce0c081bc1608..0e9d16cfa56a8 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -6,6 +6,7 @@ use super::{PatCtxt, PatKind, PatternError}; use rustc::hir::map::Map; use rustc::lint; +use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, Ty, TyCtxt}; @@ -19,7 +20,6 @@ use rustc_hir::{HirId, Pat}; use rustc_span::symbol::sym; use rustc_span::{MultiSpan, Span}; use syntax::ast::Mutability; -use syntax::feature_gate::feature_err; use std::slice; diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index abef008a8eccb..e69b580565e53 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -1,12 +1,12 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use rustc::session::config::nightly_options; +use rustc::session::parse::feature_err; use rustc::ty::TyCtxt; use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; -use syntax::feature_gate::feature_err; use super::{ConstKind, Item}; diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index df1e62d04d66d..8467acc759c2b 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -22,10 +22,9 @@ use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Attribute, MetaItem}; use syntax::attr; use syntax::attr::HasAttrs; -use syntax::feature_gate::feature_err; use syntax::mut_visit::*; use syntax::ptr::P; -use syntax::sess::ParseSess; +use syntax::sess::{feature_err, ParseSess}; use syntax::util::map_in_place::MapInPlace; use smallvec::SmallVec; diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index a2944918a4748..39ba2fbc63b43 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -9,6 +9,7 @@ use rustc::hir::map::Map; use rustc::session::config::nightly_options; +use rustc::session::parse::feature_err; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_error_codes::*; @@ -18,7 +19,6 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_span::{sym, Span, Symbol}; use syntax::ast::Mutability; -use syntax::feature_gate::feature_err; use std::fmt; diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 588386e6f8d69..af37d218d68f0 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -5,6 +5,7 @@ use rustc::hir::map::Map; use rustc::lint; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability::{DeprecationEntry, Index}; +use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::query::Providers; @@ -20,7 +21,6 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast::Attribute; use syntax::attr::{self, Stability}; -use syntax::feature_gate::feature_err; use std::cmp::Ordering; use std::mem::replace; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 1103d5b5b7c97..85b5d8ef1cb5d 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -7,6 +7,7 @@ use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy}; use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc::middle::stability; +use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::{lint, span_bug, ty}; use rustc_data_structures::fx::FxHashSet; @@ -23,7 +24,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, Ident, NodeId}; use syntax::attr::{self, StabilityLevel}; -use syntax::feature_gate::feature_err; use syntax::print::pprust; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 851c2f76adab7..c15bcd81443d6 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -10,6 +10,7 @@ use crate::namespace::Namespace; use crate::require_c_abi_if_c_variadic; use crate::util::common::ErrorReported; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; +use rustc::session::parse::feature_err; use rustc::traits; use rustc::traits::astconv_object_safety_violations; use rustc::traits::error_reporting::report_object_safety_error; @@ -30,7 +31,6 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; use smallvec::SmallVec; use syntax::ast; -use syntax::feature_gate::feature_err; use syntax::util::lev_distance::find_best_match_for_name; use std::collections::BTreeSet; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index feab31523f265..1afb703ca1506 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -53,6 +53,7 @@ use crate::check::{FnCtxt, Needs}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; +use rustc::session::parse::feature_err; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -62,6 +63,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::ty::relate::RelateResult; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TypeAndMut}; +use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -70,9 +72,6 @@ use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; -use syntax::feature_gate; - -use rustc_error_codes::*; struct Coerce<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, @@ -627,7 +626,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion { - feature_gate::feature_err( + feature_err( &self.tcx.sess.parse_sess, sym::unsized_tuple_coercion, self.cause.span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 32225cd417f2d..dea1be7641afa 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -99,6 +99,7 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc::infer::{self, InferCtxt, InferOk, InferResult}; use rustc::middle::region; use rustc::mir::interpret::ConstValue; +use rustc::session::parse::feature_err; use rustc::traits::error_reporting::recursive_type_with_infinite_size_error; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::adjustment::{ @@ -130,7 +131,6 @@ use rustc_span::{self, BytePos, MultiSpan, Span}; use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; -use syntax::feature_gate::feature_err; use syntax::util::parser::ExprPrecedence; use rustc_error_codes::*; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index df1eecdcfa8c5..a496a6e12ce1a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -3,6 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par use rustc::infer::opaque_types::may_define_opaque_type; use rustc::middle::lang_items; +use rustc::session::parse::feature_err; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable}; @@ -13,7 +14,6 @@ use rustc_hir::ItemKind; use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast; -use syntax::feature_gate; use rustc_hir as hir; use rustc_hir::itemlikevisit::ParItemLikeVisitor; @@ -821,7 +821,7 @@ fn check_method_receiver<'fcx, 'tcx>( if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) { if receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { // Report error; would have worked with `arbitrary_self_types`. - feature_gate::feature_err( + feature_err( &fcx.tcx.sess.parse_sess, sym::arbitrary_self_types, span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 64e71cc42e0ca..ad750d5ab8341 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -23,6 +23,7 @@ use crate::middle::weak_lang_items; use rustc::hir::map::Map; use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::mir::mono::Linkage; +use rustc::session::parse::feature_err; use rustc::traits; use rustc::ty::query::Providers; use rustc::ty::subst::GenericArgKind; @@ -45,7 +46,6 @@ use rustc_target::spec::abi; use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr}; -use syntax::feature_gate; use rustc_error_codes::*; @@ -1537,7 +1537,7 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { _ => None, }; if let Some(unsupported_type) = err { - feature_gate::feature_err( + feature_err( &tcx.sess.parse_sess, sym::const_compare_raw_pointers, hir_ty.span, @@ -2633,7 +2633,7 @@ fn from_target_feature( None => true, }; if !allowed && id.is_local() { - feature_gate::feature_err( + feature_err( &tcx.sess.parse_sess, feature_gate.unwrap(), item.span(), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index d266bf4bde08d..c03e848b7a420 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -78,7 +78,6 @@ pub mod expand; pub mod feature_gate { mod check; pub use check::{check_attribute, check_crate}; - pub use rustc_session::parse::{feature_err, feature_err_issue}; } pub mod mut_visit; pub mod ptr; From fff5ef68b0d5c314569a71c7fae136196b14a6bc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 12:54:43 +0100 Subject: [PATCH 0208/1253] canonicalize rustc::session import --- Cargo.lock | 1 + src/librustc_passes/Cargo.toml | 1 + src/librustc_passes/ast_validation.rs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6116ae033875e..2522eb85a7cad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3787,6 +3787,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_parse", + "rustc_session", "rustc_span", "rustc_target", "syntax", diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 4adc6dabb9fdb..897581b32b5a1 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -17,6 +17,7 @@ rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } rustc_parse = { path = "../librustc_parse" } +rustc_session = { path = "../librustc_session" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index be58a790fa878..9cd7d9a89fd87 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -7,10 +7,10 @@ // or type checking or some other kind of complex analysis. use rustc::lint; -use rustc::session::Session; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; +use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; From d247ac4c0d64b278d80296a0dab801238fa3c66b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 07:30:38 +0100 Subject: [PATCH 0209/1253] Remove unused derives --- src/librustc/lint/builtin.rs | 2 +- src/librustc/lint/context.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index f5845dcae1288..5dea0dbc8966c 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -516,7 +516,7 @@ declare_lint_pass! { // this could be a closure, but then implementing derive traits // becomes hacky (and it gets allocated) -#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(PartialEq)] pub enum BuiltinLintDiagnostics { Normal, BareTraitObject(Span, /* is_global */ bool), diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index bd561b41c57f5..492d8f1f8a5f7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -66,7 +66,7 @@ pub struct LintStore { /// Lints that are buffered up early on in the `Session` before the /// `LintLevels` is calculated -#[derive(PartialEq, Debug)] +#[derive(PartialEq)] pub struct BufferedEarlyLint { pub lint_id: LintId, pub ast_id: ast::NodeId, From 82eeb8573a7caa0b3dc4aaa8236e83fcff9779d3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 08:54:10 +0100 Subject: [PATCH 0210/1253] prepare for moving BuiltinLintDiagnostics to rustc_session --- src/librustc/lint/builtin.rs | 144 +++++++++++++++++------------------ src/librustc/lint/context.rs | 2 +- 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 5dea0dbc8966c..de4992d8e706e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -514,8 +514,10 @@ declare_lint_pass! { ] } -// this could be a closure, but then implementing derive traits -// becomes hacky (and it gets allocated) +impl LateLintPass<'_, '_> for HardwiredLints {} + +// This could be a closure, but then implementing derive trait +// becomes hacky (and it gets allocated). #[derive(PartialEq)] pub enum BuiltinLintDiagnostics { Normal, @@ -572,86 +574,80 @@ pub fn add_elided_lifetime_in_path_suggestion( ); } -impl BuiltinLintDiagnostics { - pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) { - match self { - BuiltinLintDiagnostics::Normal => (), - BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(ref s) if is_global => { - (format!("dyn ({})", s), Applicability::MachineApplicable) - } - Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), - Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), - }; - db.span_suggestion(span, "use `dyn`", sugg, app); - } - BuiltinLintDiagnostics::AbsPathWithModule(span) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(ref s) => { - // FIXME(Manishearth) ideally the emitting code - // can tell us whether or not this is global - let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; - - (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable) - } - Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), - }; - db.span_suggestion(span, "use `crate`", sugg, app); - } - BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { - db.span_label( - span, - "names from parent modules are not \ - accessible without an explicit import", - ); - } - BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { - db.span_note(span_def, "the macro is defined here"); - } - BuiltinLintDiagnostics::ElidedLifetimesInPaths( +pub fn run_builtin_lint_diagnostics( + this: BuiltinLintDiagnostics, + sess: &Session, + db: &mut DiagnosticBuilder<'_>, +) { + match this { + BuiltinLintDiagnostics::Normal => (), + BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { + let (sugg, app) = match sess.source_map().span_to_snippet(span) { + Ok(s) if is_global => (format!("dyn ({})", s), Applicability::MachineApplicable), + Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), + Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), + }; + db.span_suggestion(span, "use `dyn`", sugg, app); + } + BuiltinLintDiagnostics::AbsPathWithModule(span) => { + let (sugg, app) = match sess.source_map().span_to_snippet(span) { + Ok(ref s) => { + // FIXME(Manishearth) ideally the emitting code + // can tell us whether or not this is global + let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; + + (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable) + } + Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), + }; + db.span_suggestion(span, "use `crate`", sugg, app); + } + BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { + db.span_label( + span, + "names from parent modules are not accessible without an explicit import", + ); + } + BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { + db.span_note(span_def, "the macro is defined here"); + } + BuiltinLintDiagnostics::ElidedLifetimesInPaths( + n, + path_span, + incl_angl_brckt, + insertion_span, + anon_lts, + ) => { + add_elided_lifetime_in_path_suggestion( + sess, + db, n, path_span, incl_angl_brckt, insertion_span, anon_lts, - ) => { - add_elided_lifetime_in_path_suggestion( - sess, - db, - n, - path_span, - incl_angl_brckt, - insertion_span, - anon_lts, + ); + } + BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { + db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); + } + BuiltinLintDiagnostics::UnusedImports(message, replaces) => { + if !replaces.is_empty() { + db.tool_only_multipart_suggestion( + &message, + replaces, + Applicability::MachineApplicable, ); } - BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { - db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); - } - BuiltinLintDiagnostics::UnusedImports(message, replaces) => { - if !replaces.is_empty() { - db.tool_only_multipart_suggestion( - &message, - replaces, - Applicability::MachineApplicable, - ); - } - } - BuiltinLintDiagnostics::RedundantImport(spans, ident) => { - for (span, is_imported) in spans { - let introduced = if is_imported { "imported" } else { "defined" }; - db.span_label( - span, - format!("the item `{}` is already {} here", ident, introduced), - ); - } - } - BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(db, suggestion, span) + } + BuiltinLintDiagnostics::RedundantImport(spans, ident) => { + for (span, is_imported) in spans { + let introduced = if is_imported { "imported" } else { "defined" }; + db.span_label(span, format!("the item `{}` is already {} here", ident, introduced)); } } + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { + stability::deprecation_suggestion(db, suggestion, span) + } } } - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {} diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 492d8f1f8a5f7..90575f71ff573 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -495,7 +495,7 @@ pub trait LintContext: Sized { diagnostic: BuiltinLintDiagnostics, ) { let mut db = self.lookup(lint, span, msg); - diagnostic.run(self.sess(), &mut db); + super::builtin::run_builtin_lint_diagnostics(diagnostic, self.sess(), &mut db); db.emit(); } From 7dbccf5b556ece8e69355ee99d6f9bdcfbd71bbf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 09:40:16 +0100 Subject: [PATCH 0211/1253] buffered lint infra -> rustc_session --- Cargo.lock | 1 + src/librustc/lint/builtin.rs | 19 +----- src/librustc/lint/context.rs | 15 +---- src/librustc/lint/mod.rs | 59 +------------------ src/librustc/middle/stability.rs | 4 +- src/librustc_ast_lowering/lib.rs | 6 +- src/librustc_ast_lowering/path.rs | 7 ++- src/librustc_interface/Cargo.toml | 1 + src/librustc_interface/passes.rs | 5 +- src/librustc_interface/util.rs | 12 ++-- src/librustc_lint/early.rs | 8 +-- src/librustc_passes/ast_validation.rs | 9 +-- src/librustc_resolve/check_unused.rs | 3 +- src/librustc_resolve/imports.rs | 4 +- src/librustc_resolve/lib.rs | 26 +++++---- src/librustc_session/lint.rs | 83 +++++++++++++++++++++++++-- src/librustc_session/parse.rs | 11 ++-- 17 files changed, 136 insertions(+), 137 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2522eb85a7cad..5b9db97975001 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3630,6 +3630,7 @@ dependencies = [ "rustc_plugin_impl", "rustc_privacy", "rustc_resolve", + "rustc_session", "rustc_span", "rustc_target", "rustc_traits", diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de4992d8e706e..548b3e27ac69f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -9,10 +9,9 @@ use crate::middle::stability; use crate::session::Session; use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_session::declare_lint; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::edition::Edition; use rustc_span::source_map::Span; -use rustc_span::symbol::Symbol; -use syntax::ast; use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; declare_lint! { @@ -516,22 +515,6 @@ declare_lint_pass! { impl LateLintPass<'_, '_> for HardwiredLints {} -// This could be a closure, but then implementing derive trait -// becomes hacky (and it gets allocated). -#[derive(PartialEq)] -pub enum BuiltinLintDiagnostics { - Normal, - BareTraitObject(Span, /* is_global */ bool), - AbsPathWithModule(Span), - ProcMacroDeriveResolutionFallback(Span), - MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), - ElidedLifetimesInPaths(usize, Span, bool, Span, String), - UnknownCrateTypes(Span, String, String), - UnusedImports(String, Vec<(Span, String)>), - RedundantImport(Vec<(Span, bool)>, ast::Ident), - DeprecatedMacro(Option, Span), -} - pub fn add_elided_lifetime_in_path_suggestion( sess: &Session, db: &mut DiagnosticBuilder<'_>, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 90575f71ff573..759ab3749d2a7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -17,10 +17,8 @@ use self::TargetLint::*; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use crate::middle::privacy::AccessLevels; use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; @@ -31,6 +29,8 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -64,17 +64,6 @@ pub struct LintStore { lint_groups: FxHashMap<&'static str, LintGroup>, } -/// Lints that are buffered up early on in the `Session` before the -/// `LintLevels` is calculated -#[derive(PartialEq)] -pub struct BufferedEarlyLint { - pub lint_id: LintId, - pub ast_id: ast::NodeId, - pub span: MultiSpan, - pub msg: String, - pub diagnostic: BuiltinLintDiagnostics, -} - /// The target of the `by_name` map, which accounts for renaming/deprecation. enum TargetLint { /// A direct lint target diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index a8c1f9a664f18..e59e8ce1c0a76 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,12 +21,10 @@ pub use self::Level::*; pub use self::LintSource::*; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::ty::TyCtxt; use rustc_data_structures::sync; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; -use rustc_session::node_id::NodeMap; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; @@ -35,10 +33,10 @@ use rustc_span::Span; use syntax::ast; pub use crate::lint::context::{ - BufferedEarlyLint, CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore, + CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore, }; -pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; +pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; /// Declares a static `LintArray` and return it as an expression. #[macro_export] @@ -373,59 +371,6 @@ mod levels; pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder}; -#[derive(Default)] -pub struct LintBuffer { - pub map: NodeMap>, -} - -impl LintBuffer { - pub fn add_lint( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: MultiSpan, - msg: &str, - diagnostic: BuiltinLintDiagnostics, - ) { - let early_lint = BufferedEarlyLint { - lint_id: LintId::of(lint), - ast_id: id, - span: sp, - msg: msg.to_string(), - diagnostic, - }; - let arr = self.map.entry(id).or_default(); - if !arr.contains(&early_lint) { - arr.push(early_lint); - } - } - - pub fn take(&mut self, id: ast::NodeId) -> Vec { - self.map.remove(&id).unwrap_or_default() - } - - pub fn buffer_lint>( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: S, - msg: &str, - ) { - self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) - } - - pub fn buffer_lint_with_diagnostic>( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: S, - msg: &str, - diagnostic: BuiltinLintDiagnostics, - ) { - self.add_lint(lint, id, sp.into(), msg, diagnostic) - } -} - pub fn struct_lint_level<'a>( sess: &'a Session, lint: &'static Lint, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 4874d65b2b0db..17e84c24881c1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,7 +3,6 @@ pub use self::StabilityLevel::*; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::{self, in_derive_expansion, Lint}; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; @@ -14,6 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_hir::{self, HirId}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; @@ -195,7 +195,7 @@ pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String } pub fn early_report_deprecation( - lint_buffer: &'a mut lint::LintBuffer, + lint_buffer: &'a mut LintBuffer, message: &str, suggestion: Option, lint: &'static Lint, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 527aa6796bc22..77cb9ee35fff7 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -37,7 +37,6 @@ use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; -use rustc::lint; use rustc::lint::builtin; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; @@ -52,6 +51,7 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::IndexVec; use rustc_session::config::nightly_options; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::NodeMap; use rustc_session::Session; use rustc_span::hygiene::ExpnId; @@ -198,7 +198,7 @@ pub trait Resolver { ns: Namespace, ) -> (ast::Path, Res); - fn lint_buffer(&mut self) -> &mut lint::LintBuffer; + fn lint_buffer(&mut self) -> &mut LintBuffer; fn next_node_id(&mut self) -> NodeId; } @@ -2617,7 +2617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id, span, "trait objects without an explicit `dyn` are deprecated", - builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global), + BuiltinLintDiagnostics::BareTraitObject(span, is_global), ) } } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 9b504704ae06c..b50295ebaae55 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -1,7 +1,7 @@ use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode}; use super::{GenericArgsCtor, ParenthesizedGenericArgs}; -use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS}; +use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS; use rustc::span_bug; use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability}; @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::def_id::DefId; use rustc_hir::GenericArg; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::Span; use syntax::ast::{self, *}; @@ -304,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { E0726, "implicit elided lifetime not allowed here" ); - crate::lint::builtin::add_elided_lifetime_in_path_suggestion( + rustc::lint::builtin::add_elided_lifetime_in_path_suggestion( &self.sess, &mut err, expected_lifetimes, @@ -321,7 +322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { CRATE_NODE_ID, path_span, "hidden lifetime parameters in types are deprecated", - builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths( + BuiltinLintDiagnostics::ElidedLifetimesInPaths( expected_lifetimes, path_span, incl_angl_brckt, diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index be60b75bc47eb..9bd19fb38e771 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" } rustc_builtin_macros = { path = "../librustc_builtin_macros" } rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } +rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a7e174f04553c..e8210bfacd3bd 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -37,7 +37,6 @@ use rustc_span::symbol::Symbol; use rustc_span::FileName; use rustc_traits; use rustc_typeck as typeck; -use syntax::early_buffered_lints::BufferedEarlyLint; use syntax::mut_visit::MutVisitor; use syntax::util::node_count::NodeCounter; use syntax::{self, ast, visit}; @@ -411,8 +410,8 @@ fn configure_and_expand_inner<'a>( // Add all buffered lints from the `ParseSess` to the `Session`. sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { info!("{} parse sess buffered_lints", buffered_lints.len()); - for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) { - resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg); + for early_lint in buffered_lints.drain(..) { + resolver.lint_buffer().add_early_lint(early_lint); } }); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 8e381a27b414f..2fafd3af7a5ff 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,8 +1,5 @@ use log::info; use rustc::lint; -use rustc::session::config::{ErrorOutputType, Input, OutputFilenames}; -use rustc::session::CrateDisambiguator; -use rustc::session::{self, config, early_error, filesearch, DiagnosticOutput, Session}; use rustc::ty; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::fingerprint::Fingerprint; @@ -14,6 +11,11 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::registry::Registry; use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_resolve::{self, Resolver}; +use rustc_session as session; +use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::CrateDisambiguator; +use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session}; use rustc_span::edition::Edition; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap}; use rustc_span::symbol::{sym, Symbol}; @@ -420,7 +422,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat CrateDisambiguator::from(hasher.finish::()) } -pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut lint::LintBuffer) { +pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut LintBuffer) { // Unconditionally collect crate types from attributes to make them used for a in attrs.iter() { if a.check_name(sym::crate_type) { @@ -442,7 +444,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut ast::CRATE_NODE_ID, span, "invalid `crate_type` value", - lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes( + BuiltinLintDiagnostics::UnknownCrateTypes( span, "did you mean".to_string(), format!("\"{}\"", candidate), diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 67c0c98b20380..9a90171985158 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -16,15 +16,15 @@ use rustc::lint::{EarlyContext, LintStore}; use rustc::lint::{EarlyLintPass, EarlyLintPassObject}; -use rustc::lint::{LintBuffer, LintContext, LintPass}; -use rustc::session::Session; - +use rustc::lint::{LintContext, LintPass}; +use rustc_session::lint::LintBuffer; +use rustc_session::Session; use rustc_span::Span; -use std::slice; use syntax::ast; use syntax::visit as ast_visit; use log::debug; +use std::slice; macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 9cd7d9a89fd87..bc8d8a414c44d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -6,10 +6,11 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. -use rustc::lint; +use rustc::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; +use rustc_session::lint::LintBuffer; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; @@ -65,7 +66,7 @@ struct AstValidator<'a> { /// certain positions. is_assoc_ty_bound_banned: bool, - lint_buffer: &'a mut lint::LintBuffer, + lint_buffer: &'a mut LintBuffer, } impl<'a> AstValidator<'a> { @@ -992,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { Self::check_decl_no_pat(&sig.decl, |span, mut_ident| { if mut_ident { self.lint_buffer.buffer_lint( - lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY, + PATTERNS_IN_FNS_WITHOUT_BODY, ti.id, span, "patterns aren't allowed in methods without bodies", @@ -1021,7 +1022,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffer) -> bool { +pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool { let mut validator = AstValidator { session, has_proc_macro_decls: false, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index d6f365fce7929..4a6df92d82260 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -29,6 +29,7 @@ use crate::Resolver; use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::node_id::NodeMap; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use syntax::ast; @@ -317,7 +318,7 @@ impl Resolver<'_> { unused.use_tree_id, ms, &msg, - lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), + BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), ); } } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 813e6ac96911e..ecd51b1ee0519 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -12,9 +12,9 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; use rustc::hir::exports::Export; -use rustc::lint::builtin::BuiltinLintDiagnostics; use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS}; -use rustc::session::DiagnosticMessageId; +use rustc_session::DiagnosticMessageId; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc::ty; use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e6be9f6d328c0..8e4630cf7d696 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -24,7 +24,6 @@ use rustc::hir::exports::ExportMap; use rustc::hir::map::{DefKey, Definitions}; use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; -use rustc::session::Session; use rustc::span_bug; use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, ResolverOutputs}; @@ -39,7 +38,9 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE} use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::{GlobMap, TraitMap}; use rustc_metadata::creader::{CStore, CrateLoader}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::{NodeMap, NodeSet}; +use rustc_session::Session; use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; @@ -960,7 +961,7 @@ pub struct Resolver<'a> { /// when visiting the correspondent variants. variant_vis: DefIdMap, - lint_buffer: lint::LintBuffer, + lint_buffer: LintBuffer, next_node_id: NodeId, } @@ -1082,7 +1083,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> { &mut self.definitions } - fn lint_buffer(&mut self) -> &mut lint::LintBuffer { + fn lint_buffer(&mut self) -> &mut LintBuffer { &mut self.lint_buffer } @@ -1241,7 +1242,7 @@ impl<'a> Resolver<'a> { .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) .collect(), variant_vis: Default::default(), - lint_buffer: lint::LintBuffer::default(), + lint_buffer: LintBuffer::default(), next_node_id: NodeId::from_u32(1), } } @@ -1256,7 +1257,7 @@ impl<'a> Resolver<'a> { self.next_node_id } - pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer { + pub fn lint_buffer(&mut self) -> &mut LintBuffer { &mut self.lint_buffer } @@ -1713,10 +1714,10 @@ impl<'a> Resolver<'a> { if let Some(node_id) = poisoned { self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - node_id, ident.span, + node_id, + ident.span, &format!("cannot find {} `{}` in this scope", ns.descr(), ident), - lint::builtin::BuiltinLintDiagnostics:: - ProcMacroDeriveResolutionFallback(ident.span), + BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span), ); } return Some(LexicalScopeBinding::Item(binding)); @@ -2267,7 +2268,7 @@ impl<'a> Resolver<'a> { } } - let diag = lint::builtin::BuiltinLintDiagnostics::AbsPathWithModule(diag_span); + let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span); self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, diag_id, @@ -2562,9 +2563,10 @@ impl<'a> Resolver<'a> { cannot be referred to by absolute paths"; self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - CRATE_NODE_ID, span_use, msg, - lint::builtin::BuiltinLintDiagnostics:: - MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), + CRATE_NODE_ID, + span_use, + msg, + BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), ); } diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 0cce7e848fd60..24e42928f638a 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -1,8 +1,8 @@ pub use self::Level::*; -use crate::node_id::NodeId; +use crate::node_id::{NodeId, NodeMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_span::edition::Edition; -use rustc_span::{sym, MultiSpan, Symbol}; +use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol}; /// Setting for how to handle a lint. #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] @@ -174,7 +174,25 @@ impl ToStableHashKey for LintId { } } -/// Stores buffered lint info which can later be passed to `librustc`. +// This could be a closure, but then implementing derive trait +// becomes hacky (and it gets allocated). +#[derive(PartialEq)] +pub enum BuiltinLintDiagnostics { + Normal, + BareTraitObject(Span, /* is_global */ bool), + AbsPathWithModule(Span), + ProcMacroDeriveResolutionFallback(Span), + MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), + ElidedLifetimesInPaths(usize, Span, bool, Span, String), + UnknownCrateTypes(Span, String, String), + UnusedImports(String, Vec<(Span, String)>), + RedundantImport(Vec<(Span, bool)>, Ident), + DeprecatedMacro(Option, Span), +} + +/// Lints that are buffered up early on in the `Session` before the +/// `LintLevels` is calculated. These are later passed to `librustc`. +#[derive(PartialEq)] pub struct BufferedEarlyLint { /// The span of code that we are linting on. pub span: MultiSpan, @@ -183,10 +201,65 @@ pub struct BufferedEarlyLint { pub msg: String, /// The `NodeId` of the AST node that generated the lint. - pub id: NodeId, + pub node_id: NodeId, /// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`. - pub lint_id: &'static Lint, + pub lint_id: LintId, + + /// Customization of the `DiagnosticBuilder<'_>` for the lint. + pub diagnostic: BuiltinLintDiagnostics, +} + +#[derive(Default)] +pub struct LintBuffer { + pub map: NodeMap>, +} + +impl LintBuffer { + pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) { + let arr = self.map.entry(early_lint.node_id).or_default(); + if !arr.contains(&early_lint) { + arr.push(early_lint); + } + } + + pub fn add_lint( + &mut self, + lint: &'static Lint, + node_id: NodeId, + span: MultiSpan, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { + let lint_id = LintId::of(lint); + let msg = msg.to_string(); + self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic }); + } + + pub fn take(&mut self, id: NodeId) -> Vec { + self.map.remove(&id).unwrap_or_default() + } + + pub fn buffer_lint( + &mut self, + lint: &'static Lint, + id: NodeId, + sp: impl Into, + msg: &str, + ) { + self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) + } + + pub fn buffer_lint_with_diagnostic( + &mut self, + lint: &'static Lint, + id: NodeId, + sp: impl Into, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { + self.add_lint(lint, id, sp.into(), msg, diagnostic) + } } /// Declares a static item of type `&'static Lint`. diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index b0c6aefc00ca1..0e342939ff1af 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -1,7 +1,7 @@ //! Contains `ParseSess` which holds state living beyond what one `Parser` might. //! It also serves as an input to the parser itself. -use crate::lint::BufferedEarlyLint; +use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId}; use crate::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -210,17 +210,18 @@ impl ParseSess { pub fn buffer_lint( &self, - lint_id: &'static crate::lint::Lint, + lint: &'static Lint, span: impl Into, - id: NodeId, + node_id: NodeId, msg: &str, ) { self.buffered_lints.with_lock(|buffered_lints| { buffered_lints.push(BufferedEarlyLint { span: span.into(), - id, + node_id, msg: msg.into(), - lint_id, + lint_id: LintId::of(lint), + diagnostic: BuiltinLintDiagnostics::Normal, }); }); } From 45f27643db6e25d4377d1b7050e55c07a02a0cec Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 10:07:26 +0100 Subject: [PATCH 0212/1253] prepare moving HardwiredLints to rustc_session --- src/librustc/lint/builtin.rs | 131 +---------------------- src/librustc/lint/context.rs | 125 ++++++++++++++++++++- src/librustc/lint/internal.rs | 6 +- src/librustc/lint/mod.rs | 45 ++------ src/librustc_ast_lowering/path.rs | 2 +- src/librustc_lint/array_into_iter.rs | 3 +- src/librustc_lint/builtin.rs | 9 +- src/librustc_lint/late.rs | 6 +- src/librustc_lint/lib.rs | 3 +- src/librustc_lint/non_ascii_idents.rs | 2 +- src/librustc_lint/nonstandard_style.rs | 4 +- src/librustc_lint/redundant_semicolon.rs | 2 +- src/librustc_lint/types.rs | 6 +- src/librustc_lint/unused.rs | 4 +- src/librustc_session/lint.rs | 38 +++++++ 15 files changed, 187 insertions(+), 199 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 548b3e27ac69f..9783bc36ea542 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,14 +4,9 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass}; -use crate::middle::stability; -use crate::session::Session; -use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; -use rustc_session::declare_lint; -use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_session::lint::FutureIncompatibleInfo; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; -use rustc_span::source_map::Span; use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; declare_lint! { @@ -512,125 +507,3 @@ declare_lint_pass! { SOFT_UNSTABLE, ] } - -impl LateLintPass<'_, '_> for HardwiredLints {} - -pub fn add_elided_lifetime_in_path_suggestion( - sess: &Session, - db: &mut DiagnosticBuilder<'_>, - n: usize, - path_span: Span, - incl_angl_brckt: bool, - insertion_span: Span, - anon_lts: String, -) { - let (replace_span, suggestion) = if incl_angl_brckt { - (insertion_span, anon_lts) - } else { - // When possible, prefer a suggestion that replaces the whole - // `Path` expression with `Path<'_, T>`, rather than inserting `'_, ` - // at a point (which makes for an ugly/confusing label) - if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) { - // But our spans can get out of whack due to macros; if the place we think - // we want to insert `'_` isn't even within the path expression's span, we - // should bail out of making any suggestion rather than panicking on a - // subtract-with-overflow or string-slice-out-out-bounds (!) - // FIXME: can we do better? - if insertion_span.lo().0 < path_span.lo().0 { - return; - } - let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize; - if insertion_index > snippet.len() { - return; - } - let (before, after) = snippet.split_at(insertion_index); - (path_span, format!("{}{}{}", before, anon_lts, after)) - } else { - (insertion_span, anon_lts) - } - }; - db.span_suggestion( - replace_span, - &format!("indicate the anonymous lifetime{}", pluralize!(n)), - suggestion, - Applicability::MachineApplicable, - ); -} - -pub fn run_builtin_lint_diagnostics( - this: BuiltinLintDiagnostics, - sess: &Session, - db: &mut DiagnosticBuilder<'_>, -) { - match this { - BuiltinLintDiagnostics::Normal => (), - BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(s) if is_global => (format!("dyn ({})", s), Applicability::MachineApplicable), - Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), - Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), - }; - db.span_suggestion(span, "use `dyn`", sugg, app); - } - BuiltinLintDiagnostics::AbsPathWithModule(span) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(ref s) => { - // FIXME(Manishearth) ideally the emitting code - // can tell us whether or not this is global - let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; - - (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable) - } - Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), - }; - db.span_suggestion(span, "use `crate`", sugg, app); - } - BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { - db.span_label( - span, - "names from parent modules are not accessible without an explicit import", - ); - } - BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { - db.span_note(span_def, "the macro is defined here"); - } - BuiltinLintDiagnostics::ElidedLifetimesInPaths( - n, - path_span, - incl_angl_brckt, - insertion_span, - anon_lts, - ) => { - add_elided_lifetime_in_path_suggestion( - sess, - db, - n, - path_span, - incl_angl_brckt, - insertion_span, - anon_lts, - ); - } - BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { - db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); - } - BuiltinLintDiagnostics::UnusedImports(message, replaces) => { - if !replaces.is_empty() { - db.tool_only_multipart_suggestion( - &message, - replaces, - Applicability::MachineApplicable, - ); - } - } - BuiltinLintDiagnostics::RedundantImport(spans, ident) => { - for (span, is_imported) in spans { - let introduced = if is_imported { "imported" } else { "defined" }; - db.span_label(span, format!("the item `{}` is already {} here", ident, introduced)); - } - } - BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(db, suggestion, span) - } - } -} diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 759ab3749d2a7..3f18f4dbd1fe7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -20,13 +20,14 @@ use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; use crate::middle::privacy::AccessLevels; +use crate::middle::stability; use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; use rustc_error_codes::*; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_session::lint::BuiltinLintDiagnostics; @@ -466,6 +467,48 @@ impl LintPassObject for EarlyLintPassObject {} impl LintPassObject for LateLintPassObject {} +pub fn add_elided_lifetime_in_path_suggestion( + sess: &Session, + db: &mut DiagnosticBuilder<'_>, + n: usize, + path_span: Span, + incl_angl_brckt: bool, + insertion_span: Span, + anon_lts: String, +) { + let (replace_span, suggestion) = if incl_angl_brckt { + (insertion_span, anon_lts) + } else { + // When possible, prefer a suggestion that replaces the whole + // `Path` expression with `Path<'_, T>`, rather than inserting `'_, ` + // at a point (which makes for an ugly/confusing label) + if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) { + // But our spans can get out of whack due to macros; if the place we think + // we want to insert `'_` isn't even within the path expression's span, we + // should bail out of making any suggestion rather than panicking on a + // subtract-with-overflow or string-slice-out-out-bounds (!) + // FIXME: can we do better? + if insertion_span.lo().0 < path_span.lo().0 { + return; + } + let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize; + if insertion_index > snippet.len() { + return; + } + let (before, after) = snippet.split_at(insertion_index); + (path_span, format!("{}{}{}", before, anon_lts, after)) + } else { + (insertion_span, anon_lts) + } + }; + db.span_suggestion( + replace_span, + &format!("indicate the anonymous lifetime{}", pluralize!(n)), + suggestion, + Applicability::MachineApplicable, + ); +} + pub trait LintContext: Sized { type PassObject: LintPassObject; @@ -484,7 +527,85 @@ pub trait LintContext: Sized { diagnostic: BuiltinLintDiagnostics, ) { let mut db = self.lookup(lint, span, msg); - super::builtin::run_builtin_lint_diagnostics(diagnostic, self.sess(), &mut db); + + let sess = self.sess(); + match diagnostic { + BuiltinLintDiagnostics::Normal => (), + BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { + let (sugg, app) = match sess.source_map().span_to_snippet(span) { + Ok(s) if is_global => { + (format!("dyn ({})", s), Applicability::MachineApplicable) + } + Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), + Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), + }; + db.span_suggestion(span, "use `dyn`", sugg, app); + } + BuiltinLintDiagnostics::AbsPathWithModule(span) => { + let (sugg, app) = match sess.source_map().span_to_snippet(span) { + Ok(ref s) => { + // FIXME(Manishearth) ideally the emitting code + // can tell us whether or not this is global + let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; + + (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable) + } + Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), + }; + db.span_suggestion(span, "use `crate`", sugg, app); + } + BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { + db.span_label( + span, + "names from parent modules are not accessible without an explicit import", + ); + } + BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { + db.span_note(span_def, "the macro is defined here"); + } + BuiltinLintDiagnostics::ElidedLifetimesInPaths( + n, + path_span, + incl_angl_brckt, + insertion_span, + anon_lts, + ) => { + add_elided_lifetime_in_path_suggestion( + sess, + &mut db, + n, + path_span, + incl_angl_brckt, + insertion_span, + anon_lts, + ); + } + BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { + db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); + } + BuiltinLintDiagnostics::UnusedImports(message, replaces) => { + if !replaces.is_empty() { + db.tool_only_multipart_suggestion( + &message, + replaces, + Applicability::MachineApplicable, + ); + } + } + BuiltinLintDiagnostics::RedundantImport(spans, ident) => { + for (span, is_imported) in spans { + let introduced = if is_imported { "imported" } else { "defined" }; + db.span_label( + span, + format!("the item `{}` is already {} here", ident, introduced), + ); + } + } + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { + stability::deprecation_suggestion(&mut db, suggestion, span) + } + } + db.emit(); } diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 7b99b4af4f9ab..30679226b9b71 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -1,13 +1,11 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::lint::{ - EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass, -}; +use crate::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; -use rustc_session::declare_tool_lint; +use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::{sym, Symbol}; use syntax::ast::{Ident, Item, ItemKind}; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index e59e8ce1c0a76..1aa4a43a2f2e3 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,6 +21,7 @@ pub use self::Level::*; pub use self::LintSource::*; +use crate::lint::builtin::HardwiredLints; use crate::ty::TyCtxt; use rustc_data_structures::sync; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; @@ -33,48 +34,12 @@ use rustc_span::Span; use syntax::ast; pub use crate::lint::context::{ - CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore, + add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext, + LintContext, LintStore, }; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; - -/// Declares a static `LintArray` and return it as an expression. -#[macro_export] -macro_rules! lint_array { - ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) }; - ($( $lint:expr ),*) => {{ - vec![$($lint),*] - }} -} - -pub type LintArray = Vec<&'static Lint>; - -pub trait LintPass { - fn name(&self) -> &'static str; -} - -/// Implements `LintPass for $name` with the given list of `Lint` statics. -#[macro_export] -macro_rules! impl_lint_pass { - ($name:ident => [$($lint:expr),* $(,)?]) => { - impl LintPass for $name { - fn name(&self) -> &'static str { stringify!($name) } - } - impl $name { - pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) } - } - }; -} - -/// Declares a type named `$name` which implements `LintPass`. -/// To the right of `=>` a comma separated list of `Lint` statics is given. -#[macro_export] -macro_rules! declare_lint_pass { - ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => { - $(#[$m])* #[derive(Copy, Clone)] pub struct $name; - $crate::impl_lint_pass!($name => [$($lint),*]); - }; -} +pub use rustc_session::lint::{LintArray, LintPass}; #[macro_export] macro_rules! late_lint_methods { @@ -166,6 +131,8 @@ macro_rules! declare_late_lint_pass { late_lint_methods!(declare_late_lint_pass, [], ['tcx]); +impl LateLintPass<'_, '_> for HardwiredLints {} + #[macro_export] macro_rules! expand_combined_late_lint_pass_method { ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index b50295ebaae55..65347d379bd6a 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -305,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { E0726, "implicit elided lifetime not allowed here" ); - rustc::lint::builtin::add_elided_lifetime_in_path_suggestion( + rustc::lint::add_elided_lifetime_in_path_suggestion( &self.sess, &mut err, expected_lifetimes, diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index d8ddf7435b458..19d1052d1b243 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -1,5 +1,4 @@ -use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass}; -use rustc::lint::FutureIncompatibleInfo; +use rustc::lint::{FutureIncompatibleInfo, LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc_errors::Applicability; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 25f6361e0507d..befeb84e57c9c 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -21,13 +21,8 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. -use std::fmt::Write; - -use lint::{EarlyContext, EarlyLintPass, LateLintPass, LintPass}; -use lint::{LateContext, LintArray, LintContext}; use rustc::hir::map::Map; -use rustc::lint; -use rustc::lint::FutureIncompatibleInfo; +use rustc::lint::{self, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -39,6 +34,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{GenericParamKind, PatKind}; use rustc_hir::{HirIdSet, Node}; +use rustc_session::lint::FutureIncompatibleInfo; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Symbol}; @@ -52,6 +48,7 @@ use syntax::visit::FnKind; use crate::nonstandard_style::{method_context, MethodLateContext}; use log::debug; +use std::fmt::Write; // hardwired lints from librustc pub use lint::builtin::*; diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index 07c3b95d69972..d8e0274cf43b9 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -16,7 +16,6 @@ use rustc::hir::map::Map; use rustc::lint::LateContext; -use rustc::lint::LintPass; use rustc::lint::{LateLintPass, LateLintPassObject}; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; @@ -24,12 +23,13 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit as hir_visit; use rustc_hir::intravisit::Visitor; +use rustc_session::lint::LintPass; use rustc_span::Span; -use std::slice; use syntax::ast; +use syntax::walk_list; use log::debug; -use syntax::walk_list; +use std::slice; macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e272c3af46824..e708ded603b25 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -38,11 +38,12 @@ use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, }; -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_session::lint::{LintArray, LintPass}; use rustc_span::Span; use syntax::ast; diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index f30d0bcbdd53f..522aeb6b14420 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -1,4 +1,4 @@ -use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; use syntax::ast; declare_lint! { diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 7e5ad0976989e..f75bb9ba32c3d 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,6 +1,4 @@ -use lint::{EarlyContext, LateContext, LintArray, LintContext}; -use lint::{EarlyLintPass, LateLintPass, LintPass}; -use rustc::lint; +use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index 9fc147f2a0c5a..dc18f15fe40cb 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,4 +1,4 @@ -use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_errors::Applicability; use syntax::ast::{ExprKind, Stmt, StmtKind}; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f128e25f35bf2..ab6841c0c09bc 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -1,9 +1,6 @@ #![allow(non_snake_case)] -use crate::hir::def_id::DefId; -use lint::{LateContext, LintArray, LintContext}; -use lint::{LateLintPass, LintPass}; -use rustc::lint; +use rustc::lint::{LateContext, LateLintPass, LintContext}; use rustc::mir::interpret::{sign_extend, truncate}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; @@ -11,6 +8,7 @@ use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_hir::{is_range_literal, ExprKind, Node}; use rustc_index::vec::Idx; use rustc_span::source_map; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index d57f565d919be..da8a23f041e58 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,7 +1,5 @@ -use lint::{EarlyContext, LateContext, LintArray, LintContext}; -use lint::{EarlyLintPass, LateLintPass, LintPass}; -use rustc::lint; use rustc::lint::builtin::UNUSED_ATTRIBUTES; +use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty::adjustment; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashMap; diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 24e42928f638a..40d40ce72114d 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -326,3 +326,41 @@ macro_rules! declare_tool_lint { }; ); } + +/// Declares a static `LintArray` and return it as an expression. +#[macro_export] +macro_rules! lint_array { + ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) }; + ($( $lint:expr ),*) => {{ + vec![$($lint),*] + }} +} + +pub type LintArray = Vec<&'static Lint>; + +pub trait LintPass { + fn name(&self) -> &'static str; +} + +/// Implements `LintPass for $name` with the given list of `Lint` statics. +#[macro_export] +macro_rules! impl_lint_pass { + ($name:ident => [$($lint:expr),* $(,)?]) => { + impl $crate::lint::LintPass for $name { + fn name(&self) -> &'static str { stringify!($name) } + } + impl $name { + pub fn get_lints() -> $crate::lint::LintArray { $crate::lint_array!($($lint),*) } + } + }; +} + +/// Declares a type named `$name` which implements `LintPass`. +/// To the right of `=>` a comma separated list of `Lint` statics is given. +#[macro_export] +macro_rules! declare_lint_pass { + ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => { + $(#[$m])* #[derive(Copy, Clone)] pub struct $name; + $crate::impl_lint_pass!($name => [$($lint),*]); + }; +} From 2b44a6c8f4053cf5f8acf026ffdbc329709e5c3d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 10:35:40 +0100 Subject: [PATCH 0213/1253] move {rustc -> rustc_session}::lint::builtin --- src/librustc/lint/mod.rs | 2 +- src/librustc_session/lint.rs | 2 ++ .../lint/builtin.rs | 27 ++++++++++++++++--- src/libsyntax/early_buffered_lints.rs | 26 ++---------------- 4 files changed, 29 insertions(+), 28 deletions(-) rename src/{librustc => librustc_session}/lint/builtin.rs (95%) diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 1aa4a43a2f2e3..4f35ef673efa1 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -38,6 +38,7 @@ pub use crate::lint::context::{ LintContext, LintStore, }; +pub use rustc_session::lint::builtin; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; pub use rustc_session::lint::{LintArray, LintPass}; @@ -331,7 +332,6 @@ pub enum LintSource { pub type LevelSource = (Level, LintSource); -pub mod builtin; mod context; pub mod internal; mod levels; diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 40d40ce72114d..2ba3932c7d97e 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -4,6 +4,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHas use rustc_span::edition::Edition; use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol}; +pub mod builtin; + /// Setting for how to handle a lint. #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] pub enum Level { diff --git a/src/librustc/lint/builtin.rs b/src/librustc_session/lint/builtin.rs similarity index 95% rename from src/librustc/lint/builtin.rs rename to src/librustc_session/lint/builtin.rs index 9783bc36ea542..3e8503ef661f0 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -4,10 +4,31 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use rustc_session::lint::FutureIncompatibleInfo; -use rustc_session::{declare_lint, declare_lint_pass}; +use crate::lint::FutureIncompatibleInfo; +use crate::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; -use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; + +declare_lint! { + pub ILL_FORMED_ATTRIBUTE_INPUT, + Deny, + "ill-formed attribute inputs that were previously accepted and used in practice", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #57571 ", + edition: None, + }; +} + +declare_lint! { + pub META_VARIABLE_MISUSE, + Allow, + "possible meta-variable misuse at macro definition" +} + +declare_lint! { + pub INCOMPLETE_INCLUDE, + Deny, + "trailing content in included file" +} declare_lint! { pub EXCEEDING_BITSHIFTS, diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index 7724107888ad0..8df4eb6c9ace4 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -3,28 +3,6 @@ //! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat //! redundant. Later, these types can be converted to types for use by the rest of the compiler. -use rustc_session::declare_lint; +pub use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +pub use rustc_session::lint::builtin::{INCOMPLETE_INCLUDE, META_VARIABLE_MISUSE}; pub use rustc_session::lint::BufferedEarlyLint; -use rustc_session::lint::FutureIncompatibleInfo; - -declare_lint! { - pub ILL_FORMED_ATTRIBUTE_INPUT, - Deny, - "ill-formed attribute inputs that were previously accepted and used in practice", - @future_incompatible = FutureIncompatibleInfo { - reference: "issue #57571 ", - edition: None, - }; -} - -declare_lint! { - pub META_VARIABLE_MISUSE, - Allow, - "possible meta-variable misuse at macro definition" -} - -declare_lint! { - pub INCOMPLETE_INCLUDE, - Deny, - "trailing content in included file" -} From f361b71a7dd5516e40fe77f22d28b9ed6d76e7bf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 10:47:20 +0100 Subject: [PATCH 0214/1253] nix syntax::early_buffered_lints --- Cargo.lock | 3 +++ src/librustc/lint/mod.rs | 2 +- src/librustc_builtin_macros/Cargo.toml | 1 + src/librustc_builtin_macros/source_util.rs | 4 ++-- src/librustc_expand/Cargo.toml | 1 + src/librustc_expand/mbe/macro_check.rs | 8 ++++---- src/librustc_parse/Cargo.toml | 1 + src/librustc_parse/validate_attr.rs | 4 ++-- src/libsyntax/early_buffered_lints.rs | 8 -------- src/libsyntax/lib.rs | 2 -- 10 files changed, 15 insertions(+), 19 deletions(-) delete mode 100644 src/libsyntax/early_buffered_lints.rs diff --git a/Cargo.lock b/Cargo.lock index 5b9db97975001..b8086c83b8dd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3386,6 +3386,7 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_parse", + "rustc_session", "rustc_span", "rustc_target", "smallvec 1.0.0", @@ -3544,6 +3545,7 @@ dependencies = [ "rustc_feature", "rustc_lexer", "rustc_parse", + "rustc_session", "rustc_span", "serialize", "smallvec 1.0.0", @@ -3769,6 +3771,7 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_lexer", + "rustc_session", "rustc_span", "smallvec 1.0.0", "syntax", diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 4f35ef673efa1..4afeb14494850 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,11 +21,11 @@ pub use self::Level::*; pub use self::LintSource::*; -use crate::lint::builtin::HardwiredLints; use crate::ty::TyCtxt; use rustc_data_structures::sync; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; +use rustc_session::lint::builtin::HardwiredLints; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index ca57068fb9a33..f291eaf93580b 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -17,6 +17,7 @@ rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_parse = { path = "../librustc_parse" } rustc_target = { path = "../librustc_target" } +rustc_session = { path = "../librustc_session" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } rustc_expand = { path = "../librustc_expand" } diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs index 19a766de1f47f..dc85a92d272c4 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/src/librustc_builtin_macros/source_util.rs @@ -1,15 +1,15 @@ use rustc_expand::base::{self, *}; use rustc_expand::panictry; use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership}; +use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_span::symbol::Symbol; +use rustc_span::{self, Pos, Span}; use syntax::ast; -use syntax::early_buffered_lints::INCOMPLETE_INCLUDE; use syntax::print::pprust; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::TokenStream; -use rustc_span::{self, Pos, Span}; use smallvec::SmallVec; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index c23846063c1dc..2aa1f93378a40 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -19,5 +19,6 @@ rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } rustc_parse = { path = "../librustc_parse" } +rustc_session = { path = "../librustc_session" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } diff --git a/src/librustc_expand/mbe/macro_check.rs b/src/librustc_expand/mbe/macro_check.rs index 992764ab6a41d..47865b2fb9fc3 100644 --- a/src/librustc_expand/mbe/macro_check.rs +++ b/src/librustc_expand/mbe/macro_check.rs @@ -106,14 +106,14 @@ //! bound. use crate::mbe::{KleeneToken, TokenTree}; +use rustc_data_structures::fx::FxHashMap; +use rustc_session::lint::builtin::META_VARIABLE_MISUSE; +use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym}; +use rustc_span::{symbol::Ident, MultiSpan, Span}; use syntax::ast::NodeId; -use syntax::early_buffered_lints::META_VARIABLE_MISUSE; -use syntax::sess::ParseSess; use syntax::token::{DelimToken, Token, TokenKind}; -use rustc_data_structures::fx::FxHashMap; -use rustc_span::{symbol::Ident, MultiSpan, Span}; use smallvec::SmallVec; /// Stack represented as linked list. diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index d41d89902efcd..aa159c55ff284 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -18,6 +18,7 @@ rustc_lexer = { path = "../librustc_lexer" } rustc_errors = { path = "../librustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } syntax = { path = "../libsyntax" } unicode-normalization = "0.1.11" diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs index f089361220777..84562fbb46ff2 100644 --- a/src/librustc_parse/validate_attr.rs +++ b/src/librustc_parse/validate_attr.rs @@ -4,10 +4,10 @@ use crate::parse_in; use rustc_errors::{Applicability, PResult}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; +use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +use rustc_session::parse::ParseSess; use rustc_span::{sym, Symbol}; use syntax::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; -use syntax::early_buffered_lints::ILL_FORMED_ATTRIBUTE_INPUT; -use syntax::sess::ParseSess; use syntax::tokenstream::DelimSpan; pub fn check_meta(sess: &ParseSess, attr: &Attribute) { diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs deleted file mode 100644 index 8df4eb6c9ace4..0000000000000 --- a/src/libsyntax/early_buffered_lints.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Allows the buffering of lints for later. -//! -//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat -//! redundant. Later, these types can be converted to types for use by the rest of the compiler. - -pub use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; -pub use rustc_session::lint::builtin::{INCOMPLETE_INCLUDE, META_VARIABLE_MISUSE}; -pub use rustc_session::lint::BufferedEarlyLint; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c03e848b7a420..75c647f2daa16 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -93,8 +93,6 @@ pub mod print { pub mod pprust; } -pub mod early_buffered_lints; - use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// Requirements for a `StableHashingContext` to be used in this crate. From ed69fbbc44b6e6ba5c41905835deaaae53e6f867 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 10:58:44 +0100 Subject: [PATCH 0215/1253] ast_validation -> new crate rustc_ast_passes --- Cargo.lock | 14 ++++++++++++++ src/librustc_ast_passes/Cargo.toml | 18 ++++++++++++++++++ .../ast_validation.rs | 4 ++-- src/librustc_ast_passes/lib.rs | 7 +++++++ src/librustc_interface/Cargo.toml | 1 + src/librustc_interface/passes.rs | 4 ++-- src/librustc_passes/lib.rs | 1 - 7 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/librustc_ast_passes/Cargo.toml rename src/{librustc_passes => librustc_ast_passes}/ast_validation.rs (99%) create mode 100644 src/librustc_ast_passes/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b8086c83b8dd3..385863abf678a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3374,6 +3374,19 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_ast_passes" +version = "0.0.0" +dependencies = [ + "rustc_data_structures", + "rustc_error_codes", + "rustc_errors", + "rustc_parse", + "rustc_session", + "rustc_span", + "syntax", +] + [[package]] name = "rustc_builtin_macros" version = "0.0.0" @@ -3615,6 +3628,7 @@ dependencies = [ "rustc", "rustc-rayon", "rustc_ast_lowering", + "rustc_ast_passes", "rustc_builtin_macros", "rustc_codegen_llvm", "rustc_codegen_ssa", diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml new file mode 100644 index 0000000000000..f658618fe8ac0 --- /dev/null +++ b/src/librustc_ast_passes/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_passes" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_ast_passes" +path = "lib.rs" + +[dependencies] +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_errors = { path = "../librustc_errors", package = "rustc_errors" } +rustc_error_codes = { path = "../librustc_error_codes" } +rustc_parse = { path = "../librustc_parse" } +rustc_session = { path = "../librustc_session" } +rustc_span = { path = "../librustc_span" } +syntax = { path = "../libsyntax" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs similarity index 99% rename from src/librustc_passes/ast_validation.rs rename to src/librustc_ast_passes/ast_validation.rs index bc8d8a414c44d..c915b7ba21692 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -6,10 +6,10 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. -use rustc::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; +use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_session::lint::LintBuffer; use rustc_session::Session; use rustc_span::source_map::Spanned; @@ -907,7 +907,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } - Some(Constness::Const) => bug!("Parser should reject bare `const` on bounds"), + Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"), None => {} } } diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs new file mode 100644 index 0000000000000..8011478ed2fee --- /dev/null +++ b/src/librustc_ast_passes/lib.rs @@ -0,0 +1,7 @@ +//! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax` +//! parsed by `rustc_parse` and then lowered, after the passes in this crate, +//! by `rustc_ast_lowering`. + +#![feature(slice_patterns)] + +pub mod ast_validation; diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 9bd19fb38e771..eb0551c606548 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -22,6 +22,7 @@ rustc_span = { path = "../librustc_span" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } rustc_ast_lowering = { path = "../librustc_ast_lowering" } +rustc_ast_passes = { path = "../librustc_ast_passes" } rustc_incremental = { path = "../librustc_incremental" } rustc_traits = { path = "../librustc_traits" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index e8210bfacd3bd..27bed31b9d673 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -29,7 +29,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_incremental; use rustc_mir as mir; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; -use rustc_passes::{self, ast_validation, hir_stats, layout_test}; +use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; @@ -344,7 +344,7 @@ fn configure_and_expand_inner<'a>( } let has_proc_macro_decls = sess.time("AST_validation", || { - ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer()) + rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer()) }); let crate_types = sess.crate_types.borrow(); diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index f128d3891d7b8..65eb07b989d83 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -17,7 +17,6 @@ extern crate log; use rustc::ty::query::Providers; -pub mod ast_validation; mod check_const; pub mod dead; mod diagnostic_items; From 6cbcb830221a5525f333da95c93bd8622da00765 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 11:11:39 +0100 Subject: [PATCH 0216/1253] {syntax -> rustc_ast_passes}::feature_gate --- Cargo.lock | 3 +++ src/librustc_ast_passes/Cargo.toml | 2 ++ .../check.rs => librustc_ast_passes/feature_gate.rs} | 11 +++++------ src/librustc_ast_passes/lib.rs | 1 + src/librustc_expand/Cargo.toml | 1 + src/librustc_expand/expand.rs | 3 +-- src/librustc_interface/passes.rs | 2 +- src/libsyntax/lib.rs | 4 ---- 8 files changed, 14 insertions(+), 13 deletions(-) rename src/{libsyntax/feature_gate/check.rs => librustc_ast_passes/feature_gate.rs} (98%) diff --git a/Cargo.lock b/Cargo.lock index 385863abf678a..772470d90c573 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3378,9 +3378,11 @@ dependencies = [ name = "rustc_ast_passes" version = "0.0.0" dependencies = [ + "log", "rustc_data_structures", "rustc_error_codes", "rustc_errors", + "rustc_feature", "rustc_parse", "rustc_session", "rustc_span", @@ -3553,6 +3555,7 @@ name = "rustc_expand" version = "0.0.0" dependencies = [ "log", + "rustc_ast_passes", "rustc_data_structures", "rustc_errors", "rustc_feature", diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index f658618fe8ac0..dced4a0d15b0c 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -9,9 +9,11 @@ name = "rustc_ast_passes" path = "lib.rs" [dependencies] +log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } +rustc_feature = { path = "../librustc_feature" } rustc_parse = { path = "../librustc_parse" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } diff --git a/src/libsyntax/feature_gate/check.rs b/src/librustc_ast_passes/feature_gate.rs similarity index 98% rename from src/libsyntax/feature_gate/check.rs rename to src/librustc_ast_passes/feature_gate.rs index 46a22f12678ee..1e396d6fe8e47 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -1,9 +1,3 @@ -use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; -use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; -use crate::attr; -use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess}; -use crate::visit::{self, FnKind, Visitor}; - use rustc_error_codes::*; use rustc_errors::{struct_span_err, Handler}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; @@ -11,6 +5,11 @@ use rustc_feature::{Features, GateIssue, UnstableFeatures}; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; +use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; +use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; +use syntax::attr; +use syntax::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess}; +use syntax::visit::{self, FnKind, Visitor}; use log::debug; diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index 8011478ed2fee..f8771471e0002 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -5,3 +5,4 @@ #![feature(slice_patterns)] pub mod ast_validation; +pub mod feature_gate; diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index 2aa1f93378a40..d04dd079be75d 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -14,6 +14,7 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" rustc_span = { path = "../librustc_span" } +rustc_ast_passes = { path = "../librustc_ast_passes" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index f20de93bdeb67..3254d0c913da3 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -18,7 +18,6 @@ use rustc_span::{FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path}; use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use syntax::attr::{self, is_builtin_attr, HasAttrs}; -use syntax::feature_gate; use syntax::mut_visit::*; use syntax::print::pprust; use syntax::ptr::P; @@ -1062,7 +1061,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn check_attributes(&mut self, attrs: &[ast::Attribute]) { let features = self.cx.ecfg.features.unwrap(); for attr in attrs.iter() { - feature_gate::check_attribute(attr, self.cx.parse_sess, features); + rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.parse_sess, features); validate_attr::check_meta(self.cx.parse_sess, attr); // macros are expanded before any lint passes so this warning has to be hardcoded diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 27bed31b9d673..951fc63fe953c 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -399,7 +399,7 @@ fn configure_and_expand_inner<'a>( // Needs to go *after* expansion to be able to check the results of macro expansion. sess.time("complete_gated_feature_checking", || { - syntax::feature_gate::check_crate( + rustc_ast_passes::feature_gate::check_crate( &krate, &sess.parse_sess, &sess.features_untracked(), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 75c647f2daa16..fcefe3d2a02e4 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -75,10 +75,6 @@ pub mod ast; pub mod attr; pub mod entry; pub mod expand; -pub mod feature_gate { - mod check; - pub use check::{check_attribute, check_crate}; -} pub mod mut_visit; pub mod ptr; pub mod show_span; From ae213db0f5d9a513cae9624b1a341f516bb8e1e9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 11:21:26 +0100 Subject: [PATCH 0217/1253] {syntax -> rustc_ast_passes}::show_span --- src/librustc_ast_passes/lib.rs | 1 + src/{libsyntax => librustc_ast_passes}/show_span.rs | 6 +++--- src/librustc_interface/passes.rs | 2 +- src/libsyntax/lib.rs | 1 - 4 files changed, 5 insertions(+), 5 deletions(-) rename src/{libsyntax => librustc_ast_passes}/show_span.rs (96%) diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index f8771471e0002..eadbc485296e8 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -6,3 +6,4 @@ pub mod ast_validation; pub mod feature_gate; +pub mod show_span; diff --git a/src/libsyntax/show_span.rs b/src/librustc_ast_passes/show_span.rs similarity index 96% rename from src/libsyntax/show_span.rs rename to src/librustc_ast_passes/show_span.rs index b70e2ce0d3eb7..4596e8ff53dde 100644 --- a/src/libsyntax/show_span.rs +++ b/src/librustc_ast_passes/show_span.rs @@ -5,9 +5,9 @@ use std::str::FromStr; -use crate::ast; -use crate::visit; -use crate::visit::Visitor; +use syntax::ast; +use syntax::visit; +use syntax::visit::Visitor; enum Mode { Expression, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 951fc63fe953c..6322cc4b9a321 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -70,7 +70,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { } if let Some(ref s) = sess.opts.debugging_opts.show_span { - syntax::show_span::run(sess.diagnostic(), s, &krate); + rustc_ast_passes::show_span::run(sess.diagnostic(), s, &krate); } if sess.opts.debugging_opts.hir_stats { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index fcefe3d2a02e4..a96fee0cf8f16 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -77,7 +77,6 @@ pub mod entry; pub mod expand; pub mod mut_visit; pub mod ptr; -pub mod show_span; pub use rustc_session::parse as sess; pub mod token; pub mod tokenstream; From 7d6548a14a240d57561df9faaf75c31422137caa Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 12:02:45 +0100 Subject: [PATCH 0218/1253] rustc_passes: remove unused rustc_parse dep --- Cargo.lock | 1 - src/librustc_passes/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 772470d90c573..e96bf84e95b6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3807,7 +3807,6 @@ dependencies = [ "rustc_feature", "rustc_hir", "rustc_index", - "rustc_parse", "rustc_session", "rustc_span", "rustc_target", diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 897581b32b5a1..639d8639c4bb2 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -16,7 +16,6 @@ rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } -rustc_parse = { path = "../librustc_parse" } rustc_session = { path = "../librustc_session" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } From b4809d0818121480b96904fcb441cade7a735f18 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 13:05:49 +0100 Subject: [PATCH 0219/1253] appease rustfmt --- src/librustc_resolve/imports.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index ecd51b1ee0519..8fe17e89444cd 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -13,8 +13,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin use rustc::hir::exports::Export; use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS}; -use rustc_session::DiagnosticMessageId; -use rustc_session::lint::BuiltinLintDiagnostics; use rustc::ty; use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; @@ -22,6 +20,8 @@ use rustc_data_structures::ptr_key::PtrKey; use rustc_errors::{pluralize, struct_span_err, Applicability}; use rustc_hir::def::{self, PartialRes}; use rustc_hir::def_id::DefId; +use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_session::DiagnosticMessageId; use rustc_span::hygiene::ExpnId; use rustc_span::symbol::kw; use rustc_span::{MultiSpan, Span}; From d0d1c60f1e3eb8f8a871dbe7517461fc828ad22f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 13:30:12 +0100 Subject: [PATCH 0220/1253] pacify tidy by nixing added docs :( --- src/librustc_session/parse.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 0e342939ff1af..946e77d35595e 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -74,18 +74,6 @@ pub enum GateStrength { /// Construct a diagnostic for a language feature error due to the given `span`. /// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`. -/// -/// Example usage: -/// -/// ```ignore -/// feature_err( -/// parse_sess, -/// sym::stmt_expr_attributes, -/// attr.span, -/// "attributes on expressions are unstable", -/// ) -/// .emit(); -/// ``` pub fn feature_err<'a>( sess: &'a ParseSess, feature: Symbol, From 682f500c8f5d54197d8974b5c4371306e2faecc8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 8 Jan 2020 22:54:08 +0100 Subject: [PATCH 0221/1253] fix fallout in ui-fulldeps --- .../internal-lints/lint_pass_impl_without_macro.rs | 5 ++--- .../internal-lints/lint_pass_impl_without_macro.stderr | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index 7ce2a1dd9a62d..8d9cbe45fc696 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,9 +6,8 @@ extern crate rustc; extern crate rustc_session; -use rustc::lint::{LintArray, LintPass}; -use rustc::{declare_lint_pass, impl_lint_pass}; -use rustc_session::declare_lint; +use rustc_session::lint::{LintArray, LintPass}; +use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { pub TEST_LINT, diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index ad8670c6c83c8..39ac0019aac23 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -1,5 +1,5 @@ error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:21:6 + --> $DIR/lint_pass_impl_without_macro.rs:20:6 | LL | impl LintPass for Foo { | ^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)] = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:31:14 + --> $DIR/lint_pass_impl_without_macro.rs:30:14 | LL | impl LintPass for Custom { | ^^^^^^^^ From 09b5c854de112120a6cf4298eb9c96549995b1b0 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 10 Jan 2020 17:40:57 -0800 Subject: [PATCH 0222/1253] Remove unnecessary `const_fn` feature gates This flag opts out of the min-const-fn checks entirely, which is usually not what we want. The few cases where the flag is still necessary have been annotated. --- src/libcore/lib.rs | 1 - src/libcore/tests/lib.rs | 1 - src/libproc_macro/lib.rs | 1 - src/librustc/lib.rs | 1 - src/librustc_hir/lib.rs | 2 +- src/librustc_mir/lib.rs | 1 - src/librustc_span/lib.rs | 1 - src/librustdoc/lib.rs | 1 - src/libsyntax/lib.rs | 2 +- .../consts/const-mut-refs/const_mut_refs.rs | 1 - .../exhaustive-c-like-enum-match.rs | 1 - ...eature-gate-const-if-match.if_match.stderr | 2 +- .../feature-gate-const-if-match.rs | 1 - .../feature-gate-const-if-match.stock.stderr | 50 +++++++++---------- .../consts/control-flow/short-circuit-let.rs | 1 - .../control-flow/single_variant_match_ice.rs | 2 +- 16 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 6f1d69821f56c..6c4956663841c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -70,7 +70,6 @@ #![feature(bound_cloned)] #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] -#![feature(const_fn)] #![feature(const_if_match)] #![feature(const_panic)] #![feature(const_fn_union)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 39f6133f2a689..1b9c7e35f416d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -31,7 +31,6 @@ #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(int_error_matching)] -#![feature(const_fn)] #![feature(array_value_iter)] #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 0b74a104da44b..c51db695a5b15 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -21,7 +21,6 @@ #![feature(nll)] #![feature(staged_api)] #![feature(allow_internal_unstable)] -#![feature(const_fn)] #![feature(decl_macro)] #![feature(extern_types)] #![feature(in_band_lifetimes)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index cf424ffe7b293..3c0160a04527e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -31,7 +31,6 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(const_fn)] #![feature(const_transmute)] #![feature(core_intrinsics)] #![feature(drain_filter)] diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs index 66494d0fa736c..f54fa291bd6e8 100644 --- a/src/librustc_hir/lib.rs +++ b/src/librustc_hir/lib.rs @@ -3,7 +3,7 @@ //! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html #![feature(crate_visibility_modifier)] -#![feature(const_fn)] +#![feature(const_fn)] // For the unsizing cast on `&[]` #![feature(in_band_lifetimes)] #![feature(specialization)] #![recursion_limit = "256"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 36c6568029d5f..d2565bf9c63d4 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -13,7 +13,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(box_syntax)] #![feature(crate_visibility_modifier)] #![feature(core_intrinsics)] -#![feature(const_fn)] #![feature(decl_macro)] #![feature(drain_filter)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 8cca59df33846..1dc7fc5aa3ad1 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(const_fn)] #![feature(crate_visibility_modifier)] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 91150899877fe..22fcbde43663f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -12,7 +12,6 @@ #![feature(test)] #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] -#![feature(const_fn)] #![feature(drain_filter)] #![feature(never_type)] #![feature(unicode_internals)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b197eab739427..d67a7ba3413f5 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -7,7 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] #![feature(bool_to_option)] #![feature(box_syntax)] -#![feature(const_fn)] +#![feature(const_fn)] // For the `transmute` in `P::new` #![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] diff --git a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs index 33abfec02a87a..99006a20b1bcb 100644 --- a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs +++ b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs @@ -1,7 +1,6 @@ // run-pass #![feature(const_mut_refs)] -#![feature(const_fn)] struct Foo { x: usize diff --git a/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs b/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs index 7887fd12e5764..6bbbdd972a26c 100644 --- a/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs +++ b/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs @@ -3,7 +3,6 @@ // check-pass #![feature(const_if_match)] -#![feature(const_fn)] enum E { A, diff --git a/src/test/ui/consts/control-flow/feature-gate-const-if-match.if_match.stderr b/src/test/ui/consts/control-flow/feature-gate-const-if-match.if_match.stderr index 95096723b3c95..21e3f2af15ad6 100644 --- a/src/test/ui/consts/control-flow/feature-gate-const-if-match.if_match.stderr +++ b/src/test/ui/consts/control-flow/feature-gate-const-if-match.if_match.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/feature-gate-const-if-match.rs:109:1 + --> $DIR/feature-gate-const-if-match.rs:108:1 | LL | / fn main() { LL | | let _ = [0; { diff --git a/src/test/ui/consts/control-flow/feature-gate-const-if-match.rs b/src/test/ui/consts/control-flow/feature-gate-const-if-match.rs index e4b65257531fd..00576d50ac66b 100644 --- a/src/test/ui/consts/control-flow/feature-gate-const-if-match.rs +++ b/src/test/ui/consts/control-flow/feature-gate-const-if-match.rs @@ -6,7 +6,6 @@ #![feature(rustc_attrs)] #![cfg_attr(if_match, feature(const_if_match))] -#![feature(const_fn)] const _: i32 = if true { //[stock]~ ERROR `if` is not allowed in a `const` 5 diff --git a/src/test/ui/consts/control-flow/feature-gate-const-if-match.stock.stderr b/src/test/ui/consts/control-flow/feature-gate-const-if-match.stock.stderr index e846ee4ab6a41..d3c6a51923ffb 100644 --- a/src/test/ui/consts/control-flow/feature-gate-const-if-match.stock.stderr +++ b/src/test/ui/consts/control-flow/feature-gate-const-if-match.stock.stderr @@ -1,5 +1,5 @@ error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:11:16 + --> $DIR/feature-gate-const-if-match.rs:10:16 | LL | const _: i32 = if true { | ________________^ @@ -13,7 +13,7 @@ LL | | }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:17:16 + --> $DIR/feature-gate-const-if-match.rs:16:16 | LL | const _: i32 = if let Some(true) = Some(false) { | ________________^ @@ -27,7 +27,7 @@ LL | | }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:23:16 + --> $DIR/feature-gate-const-if-match.rs:22:16 | LL | const _: i32 = match 1 { | ________________^ @@ -41,7 +41,7 @@ LL | | }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `static` - --> $DIR/feature-gate-const-if-match.rs:30:13 + --> $DIR/feature-gate-const-if-match.rs:29:13 | LL | let x = if true { 0 } else { 1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | let x = if true { 0 } else { 1 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `static` - --> $DIR/feature-gate-const-if-match.rs:32:13 + --> $DIR/feature-gate-const-if-match.rs:31:13 | LL | let x = match x { 0 => 1, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | let x = match x { 0 => 1, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `static` - --> $DIR/feature-gate-const-if-match.rs:34:5 + --> $DIR/feature-gate-const-if-match.rs:33:5 | LL | if let Some(x) = Some(x) { x } else { 1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `static mut` - --> $DIR/feature-gate-const-if-match.rs:39:13 + --> $DIR/feature-gate-const-if-match.rs:38:13 | LL | let x = if true { 0 } else { 1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | let x = if true { 0 } else { 1 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `static mut` - --> $DIR/feature-gate-const-if-match.rs:41:13 + --> $DIR/feature-gate-const-if-match.rs:40:13 | LL | let x = match x { 0 => 1, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | let x = match x { 0 => 1, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `static mut` - --> $DIR/feature-gate-const-if-match.rs:43:5 + --> $DIR/feature-gate-const-if-match.rs:42:5 | LL | if let Some(x) = Some(x) { x } else { 1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:48:5 + --> $DIR/feature-gate-const-if-match.rs:47:5 | LL | if true { 5 } else { 6 } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | if true { 5 } else { 6 } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:52:5 + --> $DIR/feature-gate-const-if-match.rs:51:5 | LL | / if let Some(true) = a { LL | | 0 @@ -117,7 +117,7 @@ LL | | } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:60:5 + --> $DIR/feature-gate-const-if-match.rs:59:5 | LL | / match i { LL | | i if i > 10 => i, @@ -130,7 +130,7 @@ LL | | } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:91:17 + --> $DIR/feature-gate-const-if-match.rs:90:17 | LL | let x = if y { 0 } else { 1 }; | ^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | let x = if y { 0 } else { 1 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:93:17 + --> $DIR/feature-gate-const-if-match.rs:92:17 | LL | let x = match x { 0 => 1, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | let x = match x { 0 => 1, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const fn` - --> $DIR/feature-gate-const-if-match.rs:95:9 + --> $DIR/feature-gate-const-if-match.rs:94:9 | LL | if let Some(x) = Some(x) { x } else { 1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:111:17 + --> $DIR/feature-gate-const-if-match.rs:110:17 | LL | let x = if false { 0 } else { 1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let x = if false { 0 } else { 1 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:113:17 + --> $DIR/feature-gate-const-if-match.rs:112:17 | LL | let x = match x { 0 => 1, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | let x = match x { 0 => 1, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:115:9 + --> $DIR/feature-gate-const-if-match.rs:114:9 | LL | if let Some(x) = Some(x) { x } else { 1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -184,7 +184,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 } = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:68:21 + --> $DIR/feature-gate-const-if-match.rs:67:21 | LL | const IF: i32 = if true { 5 } else { 6 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | const IF: i32 = if true { 5 } else { 6 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:71:25 + --> $DIR/feature-gate-const-if-match.rs:70:25 | LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -202,7 +202,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:74:24 + --> $DIR/feature-gate-const-if-match.rs:73:24 | LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:79:21 + --> $DIR/feature-gate-const-if-match.rs:78:21 | LL | const IF: i32 = if true { 5 } else { 6 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | const IF: i32 = if true { 5 } else { 6 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `if` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:82:25 + --> $DIR/feature-gate-const-if-match.rs:81:25 | LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: `match` is not allowed in a `const` - --> $DIR/feature-gate-const-if-match.rs:85:24 + --> $DIR/feature-gate-const-if-match.rs:84:24 | LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -238,7 +238,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0019]: constant contains unimplemented expression type - --> $DIR/feature-gate-const-if-match.rs:115:21 + --> $DIR/feature-gate-const-if-match.rs:114:21 | LL | if let Some(x) = Some(x) { x } else { 1 } | ^ diff --git a/src/test/ui/consts/control-flow/short-circuit-let.rs b/src/test/ui/consts/control-flow/short-circuit-let.rs index 4b20a2124c356..8cee2a54f56d3 100644 --- a/src/test/ui/consts/control-flow/short-circuit-let.rs +++ b/src/test/ui/consts/control-flow/short-circuit-let.rs @@ -4,7 +4,6 @@ #![feature(const_if_match)] #![feature(const_panic)] -#![feature(const_fn)] const X: i32 = { let mut x = 0; diff --git a/src/test/ui/consts/control-flow/single_variant_match_ice.rs b/src/test/ui/consts/control-flow/single_variant_match_ice.rs index bb0fce66c4d89..823605ff034f1 100644 --- a/src/test/ui/consts/control-flow/single_variant_match_ice.rs +++ b/src/test/ui/consts/control-flow/single_variant_match_ice.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(const_if_match, const_fn)] +#![feature(const_if_match)] enum Foo { Prob, From 1d418a11913888585d04a322178db28d01300840 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 10 Jan 2020 18:48:52 -0800 Subject: [PATCH 0223/1253] Test that stable `const fn` requires `allow_internal_unstable` --- src/test/ui/internal/internal-unstable-const.rs | 10 ++++++++++ src/test/ui/internal/internal-unstable-const.stderr | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/internal/internal-unstable-const.rs create mode 100644 src/test/ui/internal/internal-unstable-const.stderr diff --git a/src/test/ui/internal/internal-unstable-const.rs b/src/test/ui/internal/internal-unstable-const.rs new file mode 100644 index 0000000000000..ce306c845175a --- /dev/null +++ b/src/test/ui/internal/internal-unstable-const.rs @@ -0,0 +1,10 @@ +#![feature(staged_api)] +#![feature(const_if_match)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +const fn foo() -> i32 { + if true { 4 } else { 5 } //~ loops and conditional expressions are not stable in const fn +} + +fn main() {} diff --git a/src/test/ui/internal/internal-unstable-const.stderr b/src/test/ui/internal/internal-unstable-const.stderr new file mode 100644 index 0000000000000..58bbe798b00b6 --- /dev/null +++ b/src/test/ui/internal/internal-unstable-const.stderr @@ -0,0 +1,12 @@ +error[E0723]: loops and conditional expressions are not stable in const fn + --> $DIR/internal-unstable-const.rs:7:5 + | +LL | if true { 4 } else { 5 } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0723`. From 7ba25acd7a4a119fcfdb6beb58d3958647236b30 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jan 2020 10:34:35 +0000 Subject: [PATCH 0224/1253] Revert "Rollup merge of #67727 - Dylan-DPC:stabilise/remove_item, r=alexcrichton" This reverts commit 4ed415b5478c74094c2859abfddb959588cd6bb1, reversing changes made to 3cce950743e8aa74a4378dfdefbbc80223a00865. --- src/liballoc/tests/lib.rs | 1 + src/liballoc/vec.rs | 3 ++- src/librustc/lib.rs | 1 + src/librustdoc/lib.rs | 1 + src/tools/compiletest/src/main.rs | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 3fdee8bbfdf10..c1ae67a1a339f 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -11,6 +11,7 @@ #![feature(associated_type_bounds)] #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] +#![feature(vec_remove_item)] use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index f5f8d88829f5f..e9cbf627846b5 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1696,13 +1696,14 @@ impl Vec { /// # Examples /// /// ``` + /// # #![feature(vec_remove_item)] /// let mut vec = vec![1, 2, 3, 1]; /// /// vec.remove_item(&1); /// /// assert_eq!(vec, vec![2, 3, 1]); /// ``` - #[stable(feature = "vec_remove_item", since = "1.42.0")] + #[unstable(feature = "vec_remove_item", reason = "recently added", issue = "40062")] pub fn remove_item(&mut self, item: &V) -> Option where T: PartialEq, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index cf424ffe7b293..97e59e65d71ae 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -50,6 +50,7 @@ #![feature(thread_local)] #![feature(trace_macros)] #![feature(trusted_len)] +#![feature(vec_remove_item)] #![feature(stmt_expr_attributes)] #![feature(integer_atomics)] #![feature(test)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b15dae452ff05..aa5549dda1f9f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -10,6 +10,7 @@ #![feature(nll)] #![feature(set_stdio)] #![feature(test)] +#![feature(vec_remove_item)] #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] #![feature(const_fn)] diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 0642823404aed..efa9d05f16c38 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,4 +1,5 @@ #![crate_name = "compiletest"] +#![feature(vec_remove_item)] #![deny(warnings)] // The `test` crate is the only unstable feature // allowed here, just to share similar code. From a5f42397be001b771945b23b2742b8bc9f9151b2 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 6 Jan 2020 12:59:46 +0000 Subject: [PATCH 0225/1253] Rename Result::as_deref_ok to as_deref --- src/libcore/result.rs | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index aa57c7788c60c..c657ce33f60ad 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1136,7 +1136,7 @@ impl Result { /// /// Leaves the original `Result` in-place, creating a new one containing a reference to the /// `Ok` type's `Deref::Target` type. - pub fn as_deref_ok(&self) -> Result<&T::Target, &E> { + pub fn as_deref(&self) -> Result<&T::Target, &E> { self.as_ref().map(|t| t.deref()) } } @@ -1152,24 +1152,13 @@ impl Result { } } -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -impl Result { - /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E::Target>`. - /// - /// Leaves the original `Result` in-place, creating a new one containing a reference to both - /// the `Ok` and `Err` types' `Deref::Target` types. - pub fn as_deref(&self) -> Result<&T::Target, &E::Target> { - self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) - } -} - #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { /// Converts from `Result` (or `&mut Result`) to `Result<&mut T::Target, &mut E>`. /// /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to /// the `Ok` type's `Deref::Target` type. - pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> { + pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> { self.as_mut().map(|t| t.deref_mut()) } } @@ -1185,18 +1174,6 @@ impl Result { } } -#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] -impl Result { - /// Converts from `Result` (or `&mut Result`) to - /// `Result<&mut T::Target, &mut E::Target>`. - /// - /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to - /// both the `Ok` and `Err` types' `Deref::Target` types. - pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> { - self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut()) - } -} - impl Result, E> { /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. /// From c2c2d3b32bcdffaba36a3b67915f3f2267553595 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Tue, 7 Jan 2020 06:57:08 +0000 Subject: [PATCH 0226/1253] Update test after renaming Result::as_deref --- src/libcore/tests/result.rs | 85 ++++++------------- .../result-as_deref_err.stderr | 2 +- .../result-as_deref_mut_err.stderr | 2 +- .../result-as_deref_mut_ok.rs | 6 -- .../result-as_deref_mut_ok.stderr | 12 --- .../result-as_deref_ok.rs | 6 -- .../result-as_deref_ok.stderr | 12 --- 7 files changed, 29 insertions(+), 96 deletions(-) delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 254d4539eaccf..c835313aae703 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -236,31 +236,17 @@ fn test_try() { #[test] fn test_result_as_deref() { - // &Result::Ok(T).as_deref_ok() -> + // &Result::Ok(T).as_deref() -> // Result<&T::Deref::Target, &E>::Ok(&*T) let ref_ok = &Result::Ok::<&i32, u8>(&42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.as_deref_ok(), expected_result); - - let ref_ok = &Result::Ok::(String::from("a result")); - let expected_result = Result::Ok::<&str, &u32>("a result"); - assert_eq!(ref_ok.as_deref_ok(), expected_result); - - let ref_ok = &Result::Ok::, u32>(vec![1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); - assert_eq!(ref_ok.as_deref_ok(), expected_result); - - // &Result::Ok(T).as_deref() -> - // Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T) - let ref_ok = &Result::Ok::<&i32, &u8>(&42); - let expected_result = Result::Ok::<&i32, &u8>(&42); assert_eq!(ref_ok.as_deref(), expected_result); - let ref_ok = &Result::Ok::(String::from("a result")); + let ref_ok = &Result::Ok::(String::from("a result")); let expected_result = Result::Ok::<&str, &u32>("a result"); assert_eq!(ref_ok.as_deref(), expected_result); - let ref_ok = &Result::Ok::, &u32>(vec![1, 2, 3, 4, 5]); + let ref_ok = &Result::Ok::, u32>(vec![1, 2, 3, 4, 5]); let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); assert_eq!(ref_ok.as_deref(), expected_result); @@ -281,19 +267,21 @@ fn test_result_as_deref() { // &Result::Err(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Err(&*E) let ref_err = &Result::Err::<&u8, &i32>(&41); - let expected_result = Result::Err::<&u8, &i32>(&41); + let expected_result = Result::Err::<&u8, &&i32>(&&41); assert_eq!(ref_err.as_deref(), expected_result); - let ref_err = &Result::Err::<&u32, String>(String::from("an error")); - let expected_result = Result::Err::<&u32, &str>("an error"); + let s = String::from("an error"); + let ref_err = &Result::Err::<&u32, String>(s.clone()); + let expected_result = Result::Err::<&u32, &String>(&s); assert_eq!(ref_err.as_deref(), expected_result); - let ref_err = &Result::Err::<&u32, Vec>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); + let v = vec![5, 4, 3, 2, 1]; + let ref_err = &Result::Err::<&u32, Vec>(v.clone()); + let expected_result = Result::Err::<&u32, &Vec>(&v); assert_eq!(ref_err.as_deref(), expected_result); // The following cases test calling `as_deref_*` with the wrong variant (i.e. - // `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`. + // `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`. // While uncommon, these cases are supported to ensure that an `as_deref_*` // call can still be made even when one of the Result types does not implement // `Deref` (for example, std::io::Error). @@ -312,56 +300,38 @@ fn test_result_as_deref() { let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]); assert_eq!(ref_ok.as_deref_err(), expected_result); - // &Result::Err(E).as_deref_ok() -> + // &Result::Err(E).as_deref() -> // Result<&T::Deref::Target, &E>::Err(&E) let ref_err = &Result::Err::<&u8, i32>(41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.as_deref_ok(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, &str>("an error"); let expected_result = Result::Err::<&u32, &&str>(&"an error"); - assert_eq!(ref_err.as_deref_ok(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]); let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]); - assert_eq!(ref_err.as_deref_ok(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); } #[test] fn test_result_as_deref_mut() { - // &mut Result::Ok(T).as_deref_mut_ok() -> + // &mut Result::Ok(T).as_deref_mut() -> // Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T) let mut val = 42; let mut expected_val = 42; let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val); let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); - assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); - - let mut expected_string = String::from("a result"); - let mut_ok = &mut Result::Ok::(expected_string.clone()); - let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); - assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); - - let mut expected_vec = vec![1, 2, 3, 4, 5]; - let mut_ok = &mut Result::Ok::, u32>(expected_vec.clone()); - let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); - assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); - - // &mut Result::Ok(T).as_deref_mut() -> - // Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T) - let mut val = 42; - let mut expected_val = 42; - let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val); - let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); assert_eq!(mut_ok.as_deref_mut(), expected_result); let mut expected_string = String::from("a result"); - let mut_ok = &mut Result::Ok::(expected_string.clone()); + let mut_ok = &mut Result::Ok::(expected_string.clone()); let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); assert_eq!(mut_ok.as_deref_mut(), expected_result); let mut expected_vec = vec![1, 2, 3, 4, 5]; - let mut_ok = &mut Result::Ok::, &mut u32>(expected_vec.clone()); + let mut_ok = &mut Result::Ok::, u32>(expected_vec.clone()); let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); assert_eq!(mut_ok.as_deref_mut(), expected_result); @@ -386,23 +356,22 @@ fn test_result_as_deref_mut() { // &mut Result::Err(T).as_deref_mut_err() -> // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) let mut val = 41; - let mut expected_val = 41; - let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val); - let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + let mut_err = &mut Result::Err::<&mut u8, i32>(val); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val); assert_eq!(mut_err.as_deref_mut(), expected_result); let mut expected_string = String::from("an error"); let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone()); - let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str()); + let expected_result = Result::Err::<&mut u32, &mut String>(&mut expected_string); assert_eq!(mut_err.as_deref_mut(), expected_result); let mut expected_vec = vec![5, 4, 3, 2, 1]; let mut_err = &mut Result::Err::<&mut u32, Vec>(expected_vec.clone()); - let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); + let expected_result = Result::Err::<&mut u32, &mut Vec>(&mut expected_vec); assert_eq!(mut_err.as_deref_mut(), expected_result); // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e. - // `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`. + // `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`. // While uncommon, these cases are supported to ensure that an `as_deref_mut_*` // call can still be made even when one of the Result types does not implement // `Deref` (for example, std::io::Error). @@ -426,22 +395,22 @@ fn test_result_as_deref_mut() { let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr); assert_eq!(mut_ok.as_deref_mut_err(), expected_result); - // &mut Result::Err(E).as_deref_mut_ok() -> + // &mut Result::Err(E).as_deref_mut() -> // Result<&mut T::Deref::Target, &mut E>::Err(&mut E) let mut expected_val = 41; let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone()); let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); - assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + assert_eq!(mut_err.as_deref_mut(), expected_result); let string = String::from("an error"); let expected_string = string.clone(); let mut ref_str = expected_string.as_ref(); let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str()); let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str); - assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + assert_eq!(mut_err.as_deref_mut(), expected_result); let mut expected_arr = [5, 4, 3, 2, 1]; let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone()); let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr); - assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + assert_eq!(mut_err.as_deref_mut(), expected_result); } diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr index 48a662e98b547..1d98361c46198 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr @@ -2,7 +2,7 @@ error[E0599]: no method named `as_deref_err` found for enum `std::result::Result --> $DIR/result-as_deref_err.rs:4:28 | LL | let _result = &Err(41).as_deref_err(); - | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_ok` + | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut` | = note: the method `as_deref_err` exists but the following trait bounds were not satisfied: `{integer} : std::ops::Deref` diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr index 8a5c2f4006051..950a050ea9f81 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr @@ -2,7 +2,7 @@ error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Re --> $DIR/result-as_deref_mut_err.rs:4:32 | LL | let _result = &mut Err(41).as_deref_mut_err(); - | ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_ok` + | ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut` | = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied: `{integer} : std::ops::DerefMut` diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs deleted file mode 100644 index 54b695a0865f1..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &mut Ok(42).as_deref_mut_ok(); -//~^ ERROR no method named `as_deref_mut_ok` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr deleted file mode 100644 index af8d657999cb0..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `as_deref_mut_ok` found for enum `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-as_deref_mut_ok.rs:4:31 - | -LL | let _result = &mut Ok(42).as_deref_mut_ok(); - | ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_err` - | - = note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::DerefMut` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs deleted file mode 100644 index ebb0500e8190f..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Ok(42).as_deref_ok(); -//~^ ERROR no method named `as_deref_ok` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr deleted file mode 100644 index 145e610d52c7c..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `as_deref_ok` found for enum `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-as_deref_ok.rs:4:27 - | -LL | let _result = &Ok(42).as_deref_ok(); - | ^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err` - | - = note: the method `as_deref_ok` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. From fc30825c8b22d93419a087fcec1817108d9b694b Mon Sep 17 00:00:00 2001 From: ecstatic-morse Date: Fri, 10 Jan 2020 19:29:16 -0800 Subject: [PATCH 0227/1253] Expand comment Co-Authored-By: Mazdak Farrokhzad --- src/librustc_mir/transform/qualify_min_const_fn.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 74b21435eaee4..c2c1625001d0f 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -283,7 +283,8 @@ fn check_place( /// Returns `true` if the given feature gate is allowed within the function with the given `DefId`. fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { - // All features require that the corresponding gate be enabled. + // All features require that the corresponding gate be enabled, + // even if the function has `#[allow_internal_unstable(the_gate)]`. if !tcx.features().enabled(feature_gate) { return false; } From 451c97ba53412f6b1b740a5e6783da954e7c7be9 Mon Sep 17 00:00:00 2001 From: msizanoen1 Date: Fri, 10 Jan 2020 12:23:42 +0700 Subject: [PATCH 0228/1253] Distribution CI for RISC-V GNU/Linux --- src/ci/docker/dist-various-1/Dockerfile | 29 + .../dist-various-1/build-riscv-toolchain.sh | 27 + src/ci/docker/dist-various-1/crosstool-ng.sh | 13 + .../riscv64-unknown-linux-gnu.config | 908 ++++++++++++++++++ 4 files changed, 977 insertions(+) create mode 100755 src/ci/docker/dist-various-1/build-riscv-toolchain.sh create mode 100755 src/ci/docker/dist-various-1/crosstool-ng.sh create mode 100644 src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 6bbf092878311..546e73e33d7f3 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -2,11 +2,24 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ + automake \ + bison \ + bzip2 \ + flex \ + help2man \ + libtool-bin \ + texinfo \ + unzip \ + wget \ + xz-utils \ + libncurses-dev \ + gawk \ make \ file \ curl \ ca-certificates \ python2.7 \ + python3 \ git \ cmake \ sudo \ @@ -35,6 +48,18 @@ RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa && \ apt-get update && \ apt-get install -y --no-install-recommends gcc-arm-embedded +COPY scripts/rustbuild-setup.sh dist-various-1/build-riscv-toolchain.sh dist-various-1/riscv64-unknown-linux-gnu.config dist-various-1/crosstool-ng.sh /build/ +RUN ./crosstool-ng.sh + +# Crosstool-ng will refuse to build as root +RUN sh ./rustbuild-setup.sh +USER rustbuild + +RUN ./build-riscv-toolchain.sh + +USER root +ENV PATH=/x-tools/riscv64-unknown-linux-gnu/bin:$PATH + COPY dist-various-1/build-rumprun.sh /build RUN ./build-rumprun.sh @@ -129,6 +154,7 @@ ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64gc-unknown-none-elf +ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-gnu ENV TARGETS=$TARGETS,armebv7r-none-eabi ENV TARGETS=$TARGETS,armebv7r-none-eabihf ENV TARGETS=$TARGETS,armv7r-none-eabi @@ -147,6 +173,9 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ + CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ + AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ + CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \ CC_riscv32i_unknown_none_elf=false \ CC_riscv32imc_unknown_none_elf=false \ CC_riscv32imac_unknown_none_elf=false \ diff --git a/src/ci/docker/dist-various-1/build-riscv-toolchain.sh b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh new file mode 100755 index 0000000000000..9cb5700b3b6fb --- /dev/null +++ b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir -p /tmp/build-riscv +cp riscv64-unknown-linux-gnu.config /tmp/build-riscv/.config +cd /tmp/build-riscv +hide_output ct-ng build +cd .. +rm -rf build-riscv diff --git a/src/ci/docker/dist-various-1/crosstool-ng.sh b/src/ci/docker/dist-various-1/crosstool-ng.sh new file mode 100755 index 0000000000000..b01fdd0bf65e7 --- /dev/null +++ b/src/ci/docker/dist-various-1/crosstool-ng.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -ex + +# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz +url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz" +curl -Lf $url | tar xzf - +cd crosstool-ng-crosstool-ng-1.24.0 +./bootstrap +./configure --prefix=/usr/local +make -j$(nproc) +make install +cd .. +rm -rf crosstool-ng-crosstool-ng-1.24.0 diff --git a/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config new file mode 100644 index 0000000000000..dd06065b19740 --- /dev/null +++ b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config @@ -0,0 +1,908 @@ +# +# Automatically generated file; DO NOT EDIT. +# crosstool-NG Configuration +# +CT_CONFIGURE_has_static_link=y +CT_CONFIGURE_has_cxx11=y +CT_CONFIGURE_has_wget=y +CT_CONFIGURE_has_curl=y +CT_CONFIGURE_has_make_3_81_or_newer=y +CT_CONFIGURE_has_make_4_0_or_newer=y +CT_CONFIGURE_has_libtool_2_4_or_newer=y +CT_CONFIGURE_has_libtoolize_2_4_or_newer=y +CT_CONFIGURE_has_autoconf_2_65_or_newer=y +CT_CONFIGURE_has_autoreconf_2_65_or_newer=y +CT_CONFIGURE_has_automake_1_15_or_newer=y +CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y +CT_CONFIGURE_has_python_3_4_or_newer=y +CT_CONFIGURE_has_bison_2_7_or_newer=y +CT_CONFIGURE_has_python=y +CT_CONFIGURE_has_dtc=y +CT_CONFIGURE_has_svn=y +CT_CONFIGURE_has_git=y +CT_CONFIGURE_has_md5sum=y +CT_CONFIGURE_has_sha1sum=y +CT_CONFIGURE_has_sha256sum=y +CT_CONFIGURE_has_sha512sum=y +CT_CONFIGURE_has_install_with_strip_program=y +CT_CONFIG_VERSION_CURRENT="3" +CT_CONFIG_VERSION="3" +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +CT_EXPERIMENTAL=y +# CT_ALLOW_BUILD_AS_ROOT is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="${HOME}/src" +CT_SAVE_TARBALLS=y +# CT_TARBALLS_BUILDROOT_LAYOUT is not set +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_LICENSES=y +CT_PREFIX_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +CT_DOWNLOAD_AGENT_WGET=y +# CT_DOWNLOAD_AGENT_CURL is not set +# CT_DOWNLOAD_AGENT_NONE is not set +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" +# CT_ONLY_DOWNLOAD is not set +# CT_USE_MIRROR is not set +CT_VERIFY_DOWNLOAD_DIGEST=y +CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y +# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set +CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" +# CT_VERIFY_DOWNLOAD_SIGNATURE is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERRIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +CT_PATCH_BUNDLED=y +# CT_PATCH_LOCAL is not set +# CT_PATCH_BUNDLED_LOCAL is not set +# CT_PATCH_LOCAL_BUNDLED is not set +# CT_PATCH_NONE is not set +CT_PATCH_ORDER="bundled" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +# CT_LOG_INFO is not set +# CT_LOG_EXTRA is not set +CT_LOG_ALL=y +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="ALL" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +# CT_ARCH_ALPHA is not set +# CT_ARCH_ARC is not set +# CT_ARCH_ARM is not set +# CT_ARCH_AVR is not set +# CT_ARCH_M68K is not set +# CT_ARCH_MICROBLAZE is not set +# CT_ARCH_MIPS is not set +# CT_ARCH_MOXIE is not set +# CT_ARCH_MSP430 is not set +# CT_ARCH_NIOS2 is not set +# CT_ARCH_POWERPC is not set +CT_ARCH_RISCV=y +# CT_ARCH_S390 is not set +# CT_ARCH_SH is not set +# CT_ARCH_SPARC is not set +# CT_ARCH_X86 is not set +# CT_ARCH_XTENSA is not set +CT_ARCH="riscv" +CT_ARCH_CHOICE_KSYM="RISCV" +CT_ARCH_TUNE="" +CT_ARCH_RISCV_SHOW=y + +# +# Options for riscv +# +CT_ARCH_RISCV_PKG_KSYM="" +CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" +CT_ARCH_SUFFIX="" +# CT_OMIT_TARGET_VENDOR is not set + +# +# Generic target options +# +# CT_MULTILIB is not set +# CT_DEMULTILIB is not set +CT_ARCH_SUPPORTS_BOTH_MMU=y +CT_ARCH_USE_MMU=y +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_BITNESS=64 +# CT_ARCH_32 is not set +CT_ARCH_64=y + +# +# Target optimisations +# +CT_ARCH_SUPPORTS_WITH_ARCH=y +CT_ARCH_SUPPORTS_WITH_ABI=y +CT_ARCH_SUPPORTS_WITH_TUNE=y +CT_ARCH_ARCH="rv64gc" +CT_ARCH_ABI="" +CT_TARGET_CFLAGS="" +CT_TARGET_LDFLAGS="" + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +CT_WANTS_STATIC_LINK_CXX=y +# CT_STATIC_TOOLCHAIN is not set +CT_SHOW_CT_VERSION=y +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +# CT_NATIVE is not set +CT_CROSS=y +# CT_CROSS_NATIVE is not set +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +# CT_KERNEL_BARE_METAL is not set +CT_KERNEL_LINUX=y +CT_KERNEL="linux" +CT_KERNEL_CHOICE_KSYM="LINUX" +CT_KERNEL_LINUX_SHOW=y + +# +# Options for linux +# +CT_KERNEL_LINUX_PKG_KSYM="LINUX" +CT_LINUX_DIR_NAME="linux" +CT_LINUX_PKG_NAME="linux" +CT_LINUX_SRC_RELEASE=y +# CT_LINUX_SRC_DEVEL is not set +# CT_LINUX_SRC_CUSTOM is not set +CT_LINUX_PATCH_GLOBAL=y +# CT_LINUX_PATCH_BUNDLED is not set +# CT_LINUX_PATCH_LOCAL is not set +# CT_LINUX_PATCH_BUNDLED_LOCAL is not set +# CT_LINUX_PATCH_LOCAL_BUNDLED is not set +# CT_LINUX_PATCH_NONE is not set +CT_LINUX_PATCH_ORDER="global" +CT_LINUX_V_4_20=y +# CT_LINUX_V_4_19 is not set +# CT_LINUX_V_4_18 is not set +# CT_LINUX_V_4_17 is not set +# CT_LINUX_V_4_16 is not set +# CT_LINUX_V_4_15 is not set +# CT_LINUX_V_4_14 is not set +# CT_LINUX_V_4_13 is not set +# CT_LINUX_V_4_12 is not set +# CT_LINUX_V_4_11 is not set +# CT_LINUX_V_4_10 is not set +# CT_LINUX_V_4_9 is not set +# CT_LINUX_V_4_4 is not set +# CT_LINUX_V_4_1 is not set +# CT_LINUX_V_3_16 is not set +# CT_LINUX_V_3_13 is not set +# CT_LINUX_V_3_12 is not set +# CT_LINUX_V_3_10 is not set +# CT_LINUX_V_3_4 is not set +# CT_LINUX_V_3_2 is not set +# CT_LINUX_NO_VERSIONS is not set +CT_LINUX_VERSION="4.20.8" +CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" +CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" +CT_LINUX_later_than_4_8=y +CT_LINUX_4_8_or_later=y +CT_LINUX_later_than_3_7=y +CT_LINUX_3_7_or_later=y +CT_LINUX_later_than_3_2=y +CT_LINUX_3_2_or_later=y +CT_LINUX_REQUIRE_3_2_or_later=y +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y +CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS_BINUTILS=y +CT_BINUTILS="binutils" +CT_BINUTILS_CHOICE_KSYM="BINUTILS" +CT_BINUTILS_BINUTILS_SHOW=y + +# +# Options for binutils +# +CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" +CT_BINUTILS_DIR_NAME="binutils" +CT_BINUTILS_USE_GNU=y +CT_BINUTILS_USE="BINUTILS" +CT_BINUTILS_PKG_NAME="binutils" +CT_BINUTILS_SRC_RELEASE=y +# CT_BINUTILS_SRC_DEVEL is not set +# CT_BINUTILS_SRC_CUSTOM is not set +CT_BINUTILS_PATCH_GLOBAL=y +# CT_BINUTILS_PATCH_BUNDLED is not set +# CT_BINUTILS_PATCH_LOCAL is not set +# CT_BINUTILS_PATCH_BUNDLED_LOCAL is not set +# CT_BINUTILS_PATCH_LOCAL_BUNDLED is not set +# CT_BINUTILS_PATCH_NONE is not set +CT_BINUTILS_PATCH_ORDER="global" +CT_BINUTILS_V_2_32=y +# CT_BINUTILS_V_2_31 is not set +# CT_BINUTILS_V_2_30 is not set +# CT_BINUTILS_V_2_29 is not set +# CT_BINUTILS_V_2_28 is not set +# CT_BINUTILS_V_2_27 is not set +# CT_BINUTILS_V_2_26 is not set +# CT_BINUTILS_NO_VERSIONS is not set +CT_BINUTILS_VERSION="2.32" +CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" +CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" +CT_BINUTILS_later_than_2_30=y +CT_BINUTILS_2_30_or_later=y +CT_BINUTILS_later_than_2_27=y +CT_BINUTILS_2_27_or_later=y +CT_BINUTILS_later_than_2_25=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_REQUIRE_2_25_or_later=y +CT_BINUTILS_later_than_2_23=y +CT_BINUTILS_2_23_or_later=y + +# +# GNU binutils +# +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y +CT_BINUTILS_LINKER_LD=y +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_RELRO=m +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set +CT_ALL_BINUTILS_CHOICES="BINUTILS" + +# +# C-library +# +CT_LIBC_GLIBC=y +# CT_LIBC_MUSL is not set +# CT_LIBC_UCLIBC is not set +CT_LIBC="glibc" +CT_LIBC_CHOICE_KSYM="GLIBC" +CT_THREADS="nptl" +CT_LIBC_GLIBC_SHOW=y + +# +# Options for glibc +# +CT_LIBC_GLIBC_PKG_KSYM="GLIBC" +CT_GLIBC_DIR_NAME="glibc" +CT_GLIBC_USE_GNU=y +CT_GLIBC_USE="GLIBC" +CT_GLIBC_PKG_NAME="glibc" +CT_GLIBC_SRC_RELEASE=y +# CT_GLIBC_SRC_DEVEL is not set +# CT_GLIBC_SRC_CUSTOM is not set +CT_GLIBC_PATCH_GLOBAL=y +# CT_GLIBC_PATCH_BUNDLED is not set +# CT_GLIBC_PATCH_LOCAL is not set +# CT_GLIBC_PATCH_BUNDLED_LOCAL is not set +# CT_GLIBC_PATCH_LOCAL_BUNDLED is not set +# CT_GLIBC_PATCH_NONE is not set +CT_GLIBC_PATCH_ORDER="global" +CT_GLIBC_V_2_29=y +# CT_GLIBC_NO_VERSIONS is not set +CT_GLIBC_VERSION="2.29" +CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" +CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" +CT_GLIBC_2_29_or_later=y +CT_GLIBC_2_29_or_older=y +CT_GLIBC_REQUIRE_2_29_or_later=y +CT_GLIBC_later_than_2_27=y +CT_GLIBC_2_27_or_later=y +CT_GLIBC_later_than_2_26=y +CT_GLIBC_2_26_or_later=y +CT_GLIBC_later_than_2_25=y +CT_GLIBC_2_25_or_later=y +CT_GLIBC_later_than_2_24=y +CT_GLIBC_2_24_or_later=y +CT_GLIBC_later_than_2_23=y +CT_GLIBC_2_23_or_later=y +CT_GLIBC_later_than_2_20=y +CT_GLIBC_2_20_or_later=y +CT_GLIBC_later_than_2_17=y +CT_GLIBC_2_17_or_later=y +CT_GLIBC_later_than_2_14=y +CT_GLIBC_2_14_or_later=y +CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y +CT_GLIBC_DEP_BINUTILS=y +CT_GLIBC_DEP_GCC=y +CT_GLIBC_DEP_PYTHON=y +CT_GLIBC_BUILD_SSP=y +CT_GLIBC_HAS_LIBIDN_ADDON=y +# CT_GLIBC_USE_LIBIDN_ADDON is not set +CT_GLIBC_NO_SPARC_V8=y +CT_GLIBC_HAS_OBSOLETE_RPC=y +CT_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_GLIBC_CONFIGPARMS="" +CT_GLIBC_EXTRA_CFLAGS="" +CT_GLIBC_ENABLE_OBSOLETE_RPC=y +# CT_GLIBC_ENABLE_FORTIFIED_BUILD is not set +# CT_GLIBC_DISABLE_VERSIONING is not set +CT_GLIBC_OLDEST_ABI="" +CT_GLIBC_FORCE_UNWIND=y +# CT_GLIBC_LOCALES is not set +CT_GLIBC_KERNEL_VERSION_NONE=y +# CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set +# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_GLIBC_MIN_KERNEL="" +CT_GLIBC_SSP_DEFAULT=y +# CT_GLIBC_SSP_NO is not set +# CT_GLIBC_SSP_YES is not set +# CT_GLIBC_SSP_ALL is not set +# CT_GLIBC_SSP_STRONG is not set +# CT_GLIBC_ENABLE_WERROR is not set +CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +# CT_CREATE_LDSO_CONF is not set +CT_LIBC_XLDD=y + +# +# C compiler +# +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y +CT_CC_GCC=y +CT_CC="gcc" +CT_CC_CHOICE_KSYM="GCC" +CT_CC_GCC_SHOW=y + +# +# Options for gcc +# +CT_CC_GCC_PKG_KSYM="GCC" +CT_GCC_DIR_NAME="gcc" +CT_GCC_USE_GNU=y +# CT_GCC_USE_LINARO is not set +CT_GCC_USE="GCC" +CT_GCC_PKG_NAME="gcc" +CT_GCC_SRC_RELEASE=y +# CT_GCC_SRC_DEVEL is not set +# CT_GCC_SRC_CUSTOM is not set +CT_GCC_PATCH_GLOBAL=y +# CT_GCC_PATCH_BUNDLED is not set +# CT_GCC_PATCH_LOCAL is not set +# CT_GCC_PATCH_BUNDLED_LOCAL is not set +# CT_GCC_PATCH_LOCAL_BUNDLED is not set +# CT_GCC_PATCH_NONE is not set +CT_GCC_PATCH_ORDER="global" +CT_GCC_V_8=y +# CT_GCC_V_7 is not set +# CT_GCC_NO_VERSIONS is not set +CT_GCC_VERSION="8.3.0" +CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" +CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_GCC_SIGNATURE_FORMAT="" +CT_GCC_later_than_7=y +CT_GCC_7_or_later=y +CT_GCC_REQUIRE_7_or_later=y +CT_GCC_later_than_6=y +CT_GCC_6_or_later=y +CT_GCC_later_than_5=y +CT_GCC_5_or_later=y +CT_GCC_REQUIRE_5_or_later=y +CT_GCC_later_than_4_9=y +CT_GCC_4_9_or_later=y +CT_GCC_REQUIRE_4_9_or_later=y +CT_GCC_later_than_4_8=y +CT_GCC_4_8_or_later=y +CT_CC_GCC_HAS_LIBMPX=y +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set +CT_CC_GCC_CONFIG_TLS=m + +# +# Optimisation features +# +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_USE_LTO=y + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_ALL_CC_CHOICES="GCC" + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_FORTRAN is not set +# CT_CC_LANG_ADA is not set +# CT_CC_LANG_OBJC is not set +# CT_CC_LANG_OBJCXX is not set +# CT_CC_LANG_GOLANG is not set +CT_CC_LANG_OTHERS="" + +# +# Debug facilities +# +# CT_DEBUG_DUMA is not set +CT_DEBUG_GDB=y +CT_DEBUG_GDB_PKG_KSYM="GDB" +CT_GDB_DIR_NAME="gdb" +CT_GDB_USE_GNU=y +CT_GDB_USE="GDB" +CT_GDB_PKG_NAME="gdb" +CT_GDB_SRC_RELEASE=y +# CT_GDB_SRC_DEVEL is not set +# CT_GDB_SRC_CUSTOM is not set +CT_GDB_PATCH_GLOBAL=y +# CT_GDB_PATCH_BUNDLED is not set +# CT_GDB_PATCH_LOCAL is not set +# CT_GDB_PATCH_BUNDLED_LOCAL is not set +# CT_GDB_PATCH_LOCAL_BUNDLED is not set +# CT_GDB_PATCH_NONE is not set +CT_GDB_PATCH_ORDER="global" +CT_GDB_V_8_2=y +# CT_GDB_V_8_1 is not set +# CT_GDB_V_8_0 is not set +# CT_GDB_NO_VERSIONS is not set +CT_GDB_VERSION="8.2.1" +CT_GDB_MIRRORS="$(CT_Mirrors GNU gdb) $(CT_Mirrors sourceware gdb/releases)" +CT_GDB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GDB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GDB_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_GDB_SIGNATURE_FORMAT="" +CT_GDB_later_than_8_0=y +CT_GDB_8_0_or_later=y +CT_GDB_REQUIRE_8_0_or_later=y +CT_GDB_later_than_7_12=y +CT_GDB_7_12_or_later=y +CT_GDB_later_than_7_2=y +CT_GDB_7_2_or_later=y +CT_GDB_later_than_7_0=y +CT_GDB_7_0_or_later=y +CT_GDB_CROSS=y +# CT_GDB_CROSS_STATIC is not set +# CT_GDB_CROSS_SIM is not set +# CT_GDB_CROSS_PYTHON is not set +CT_GDB_CROSS_EXTRA_CONFIG_ARRAY="" +# CT_GDB_NATIVE is not set +# CT_GDB_GDBSERVER is not set +CT_GDB_HAS_PKGVERSION_BUGURL=y +CT_GDB_HAS_PYTHON=y +CT_GDB_INSTALL_GDBINIT=y +CT_GDB_HAS_IPA_LIB=y +# CT_DEBUG_LTRACE is not set +# CT_DEBUG_STRACE is not set +CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" + +# +# Companion libraries +# +# CT_COMPLIBS_CHECK is not set +# CT_COMP_LIBS_CLOOG is not set +CT_COMP_LIBS_EXPAT=y +CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" +CT_EXPAT_DIR_NAME="expat" +CT_EXPAT_PKG_NAME="expat" +CT_EXPAT_SRC_RELEASE=y +# CT_EXPAT_SRC_DEVEL is not set +# CT_EXPAT_SRC_CUSTOM is not set +CT_EXPAT_PATCH_GLOBAL=y +# CT_EXPAT_PATCH_BUNDLED is not set +# CT_EXPAT_PATCH_LOCAL is not set +# CT_EXPAT_PATCH_BUNDLED_LOCAL is not set +# CT_EXPAT_PATCH_LOCAL_BUNDLED is not set +# CT_EXPAT_PATCH_NONE is not set +CT_EXPAT_PATCH_ORDER="global" +CT_EXPAT_V_2_2=y +# CT_EXPAT_NO_VERSIONS is not set +CT_EXPAT_VERSION="2.2.6" +CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" +CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" +CT_EXPAT_SIGNATURE_FORMAT="" +CT_COMP_LIBS_GETTEXT=y +CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" +CT_GETTEXT_DIR_NAME="gettext" +CT_GETTEXT_PKG_NAME="gettext" +CT_GETTEXT_SRC_RELEASE=y +# CT_GETTEXT_SRC_DEVEL is not set +# CT_GETTEXT_SRC_CUSTOM is not set +CT_GETTEXT_PATCH_GLOBAL=y +# CT_GETTEXT_PATCH_BUNDLED is not set +# CT_GETTEXT_PATCH_LOCAL is not set +# CT_GETTEXT_PATCH_BUNDLED_LOCAL is not set +# CT_GETTEXT_PATCH_LOCAL_BUNDLED is not set +# CT_GETTEXT_PATCH_NONE is not set +CT_GETTEXT_PATCH_ORDER="global" +CT_GETTEXT_V_0_19_8_1=y +# CT_GETTEXT_NO_VERSIONS is not set +CT_GETTEXT_VERSION="0.19.8.1" +CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" +CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" +CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_GMP=y +CT_COMP_LIBS_GMP_PKG_KSYM="GMP" +CT_GMP_DIR_NAME="gmp" +CT_GMP_PKG_NAME="gmp" +CT_GMP_SRC_RELEASE=y +# CT_GMP_SRC_DEVEL is not set +# CT_GMP_SRC_CUSTOM is not set +CT_GMP_PATCH_GLOBAL=y +# CT_GMP_PATCH_BUNDLED is not set +# CT_GMP_PATCH_LOCAL is not set +# CT_GMP_PATCH_BUNDLED_LOCAL is not set +# CT_GMP_PATCH_LOCAL_BUNDLED is not set +# CT_GMP_PATCH_NONE is not set +CT_GMP_PATCH_ORDER="global" +CT_GMP_V_6_1=y +# CT_GMP_NO_VERSIONS is not set +CT_GMP_VERSION="6.1.2" +CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" +CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" +CT_GMP_SIGNATURE_FORMAT="packed/.sig" +CT_GMP_later_than_5_1_0=y +CT_GMP_5_1_0_or_later=y +CT_GMP_later_than_5_0_0=y +CT_GMP_5_0_0_or_later=y +CT_GMP_REQUIRE_5_0_0_or_later=y +CT_COMP_LIBS_ISL=y +CT_COMP_LIBS_ISL_PKG_KSYM="ISL" +CT_ISL_DIR_NAME="isl" +CT_ISL_PKG_NAME="isl" +CT_ISL_SRC_RELEASE=y +# CT_ISL_SRC_DEVEL is not set +# CT_ISL_SRC_CUSTOM is not set +CT_ISL_PATCH_GLOBAL=y +# CT_ISL_PATCH_BUNDLED is not set +# CT_ISL_PATCH_LOCAL is not set +# CT_ISL_PATCH_BUNDLED_LOCAL is not set +# CT_ISL_PATCH_LOCAL_BUNDLED is not set +# CT_ISL_PATCH_NONE is not set +CT_ISL_PATCH_ORDER="global" +CT_ISL_V_0_20=y +# CT_ISL_V_0_19 is not set +# CT_ISL_V_0_18 is not set +# CT_ISL_V_0_17 is not set +# CT_ISL_V_0_16 is not set +# CT_ISL_V_0_15 is not set +# CT_ISL_NO_VERSIONS is not set +CT_ISL_VERSION="0.20" +CT_ISL_MIRRORS="http://isl.gforge.inria.fr" +CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_ISL_SIGNATURE_FORMAT="" +CT_ISL_later_than_0_18=y +CT_ISL_0_18_or_later=y +CT_ISL_later_than_0_15=y +CT_ISL_0_15_or_later=y +CT_ISL_REQUIRE_0_15_or_later=y +CT_ISL_later_than_0_14=y +CT_ISL_0_14_or_later=y +CT_ISL_REQUIRE_0_14_or_later=y +CT_ISL_later_than_0_13=y +CT_ISL_0_13_or_later=y +CT_ISL_later_than_0_12=y +CT_ISL_0_12_or_later=y +CT_ISL_REQUIRE_0_12_or_later=y +# CT_COMP_LIBS_LIBELF is not set +CT_COMP_LIBS_LIBICONV=y +CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" +CT_LIBICONV_DIR_NAME="libiconv" +CT_LIBICONV_PKG_NAME="libiconv" +CT_LIBICONV_SRC_RELEASE=y +# CT_LIBICONV_SRC_DEVEL is not set +# CT_LIBICONV_SRC_CUSTOM is not set +CT_LIBICONV_PATCH_GLOBAL=y +# CT_LIBICONV_PATCH_BUNDLED is not set +# CT_LIBICONV_PATCH_LOCAL is not set +# CT_LIBICONV_PATCH_BUNDLED_LOCAL is not set +# CT_LIBICONV_PATCH_LOCAL_BUNDLED is not set +# CT_LIBICONV_PATCH_NONE is not set +CT_LIBICONV_PATCH_ORDER="global" +CT_LIBICONV_V_1_15=y +# CT_LIBICONV_NO_VERSIONS is not set +CT_LIBICONV_VERSION="1.15" +CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" +CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" +CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_MPC=y +CT_COMP_LIBS_MPC_PKG_KSYM="MPC" +CT_MPC_DIR_NAME="mpc" +CT_MPC_PKG_NAME="mpc" +CT_MPC_SRC_RELEASE=y +# CT_MPC_SRC_DEVEL is not set +# CT_MPC_SRC_CUSTOM is not set +CT_MPC_PATCH_GLOBAL=y +# CT_MPC_PATCH_BUNDLED is not set +# CT_MPC_PATCH_LOCAL is not set +# CT_MPC_PATCH_BUNDLED_LOCAL is not set +# CT_MPC_PATCH_LOCAL_BUNDLED is not set +# CT_MPC_PATCH_NONE is not set +CT_MPC_PATCH_ORDER="global" +CT_MPC_V_1_1=y +# CT_MPC_V_1_0 is not set +# CT_MPC_NO_VERSIONS is not set +CT_MPC_VERSION="1.1.0" +CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" +CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_FORMATS=".tar.gz" +CT_MPC_SIGNATURE_FORMAT="packed/.sig" +CT_MPC_1_1_0_or_later=y +CT_MPC_1_1_0_or_older=y +CT_COMP_LIBS_MPFR=y +CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" +CT_MPFR_DIR_NAME="mpfr" +CT_MPFR_PKG_NAME="mpfr" +CT_MPFR_SRC_RELEASE=y +# CT_MPFR_SRC_DEVEL is not set +# CT_MPFR_SRC_CUSTOM is not set +CT_MPFR_PATCH_GLOBAL=y +# CT_MPFR_PATCH_BUNDLED is not set +# CT_MPFR_PATCH_LOCAL is not set +# CT_MPFR_PATCH_BUNDLED_LOCAL is not set +# CT_MPFR_PATCH_LOCAL_BUNDLED is not set +# CT_MPFR_PATCH_NONE is not set +CT_MPFR_PATCH_ORDER="global" +CT_MPFR_V_4_0=y +# CT_MPFR_V_3_1 is not set +# CT_MPFR_NO_VERSIONS is not set +CT_MPFR_VERSION="4.0.2" +CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" +CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" +CT_MPFR_SIGNATURE_FORMAT="packed/.asc" +CT_MPFR_later_than_4_0_0=y +CT_MPFR_4_0_0_or_later=y +CT_MPFR_later_than_3_0_0=y +CT_MPFR_3_0_0_or_later=y +CT_MPFR_REQUIRE_3_0_0_or_later=y +CT_COMP_LIBS_NCURSES=y +CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" +CT_NCURSES_DIR_NAME="ncurses" +CT_NCURSES_PKG_NAME="ncurses" +CT_NCURSES_SRC_RELEASE=y +# CT_NCURSES_SRC_DEVEL is not set +# CT_NCURSES_SRC_CUSTOM is not set +CT_NCURSES_PATCH_GLOBAL=y +# CT_NCURSES_PATCH_BUNDLED is not set +# CT_NCURSES_PATCH_LOCAL is not set +# CT_NCURSES_PATCH_BUNDLED_LOCAL is not set +# CT_NCURSES_PATCH_LOCAL_BUNDLED is not set +# CT_NCURSES_PATCH_NONE is not set +CT_NCURSES_PATCH_ORDER="global" +CT_NCURSES_V_6_1=y +# CT_NCURSES_V_6_0 is not set +# CT_NCURSES_NO_VERSIONS is not set +CT_NCURSES_VERSION="6.1" +CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" +CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" +CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" +# CT_NCURSES_NEW_ABI is not set +CT_NCURSES_HOST_CONFIG_ARGS="" +CT_NCURSES_HOST_DISABLE_DB=y +CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" +CT_NCURSES_TARGET_CONFIG_ARGS="" +# CT_NCURSES_TARGET_DISABLE_DB is not set +CT_NCURSES_TARGET_FALLBACKS="" +CT_COMP_LIBS_ZLIB=y +CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" +CT_ZLIB_DIR_NAME="zlib" +CT_ZLIB_PKG_NAME="zlib" +CT_ZLIB_SRC_RELEASE=y +# CT_ZLIB_SRC_DEVEL is not set +# CT_ZLIB_SRC_CUSTOM is not set +CT_ZLIB_PATCH_GLOBAL=y +# CT_ZLIB_PATCH_BUNDLED is not set +# CT_ZLIB_PATCH_LOCAL is not set +# CT_ZLIB_PATCH_BUNDLED_LOCAL is not set +# CT_ZLIB_PATCH_LOCAL_BUNDLED is not set +# CT_ZLIB_PATCH_NONE is not set +CT_ZLIB_PATCH_ORDER="global" +CT_ZLIB_V_1_2_11=y +# CT_ZLIB_NO_VERSIONS is not set +CT_ZLIB_VERSION="1.2.11" +CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" +CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" +CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_MPC_NEEDED=y +CT_EXPAT_NEEDED=y +CT_NCURSES_NEEDED=y +CT_ZLIB_NEEDED=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_MPC=y +CT_EXPAT=y +CT_NCURSES=y +CT_ZLIB=y + +# +# Companion tools +# +# CT_COMP_TOOLS_FOR_HOST is not set +# CT_COMP_TOOLS_AUTOCONF is not set +# CT_COMP_TOOLS_AUTOMAKE is not set +# CT_COMP_TOOLS_BISON is not set +# CT_COMP_TOOLS_DTC is not set +# CT_COMP_TOOLS_LIBTOOL is not set +# CT_COMP_TOOLS_M4 is not set +# CT_COMP_TOOLS_MAKE is not set +CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" + +# +# Test suite +# +# CT_TEST_SUITE_GCC is not set From 3a2af3242c7009247e99e9bc087b1c0b72913d0f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 Jan 2020 10:58:44 +0100 Subject: [PATCH 0229/1253] canonicalize some lint imports --- src/librustc/hir/check_attr.rs | 2 +- src/librustc/lint/context.rs | 4 ++-- src/librustc/lint/levels.rs | 6 +++--- src/librustc/middle/stability.rs | 4 ++-- src/librustc/query/mod.rs | 2 +- src/librustc/traits/object_safety.rs | 7 +++--- src/librustc/traits/specialize/mod.rs | 4 ++-- src/librustc/ty/context.rs | 31 ++++++++++++++------------- src/librustc/ty/query/mod.rs | 2 +- src/librustc_ast_passes/Cargo.toml | 2 +- 10 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index c6a996f84f461..5a99e7965538b 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -5,7 +5,6 @@ //! item. use crate::hir::map::Map; -use crate::lint::builtin::UNUSED_ATTRIBUTES; use crate::ty::query::Providers; use crate::ty::TyCtxt; @@ -16,6 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::DUMMY_HIR_ID; use rustc_hir::{self, HirId, Item, ItemKind, TraitItem, TraitItemKind}; +use rustc_session::lint::builtin::UNUSED_ATTRIBUTES; use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast::Attribute; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 3f18f4dbd1fe7..867eb5a193707 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -16,12 +16,11 @@ use self::TargetLint::*; -use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; +use crate::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; use crate::middle::privacy::AccessLevels; use crate::middle::stability; -use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; @@ -32,6 +31,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; +use rustc_session::Session; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index e586ad1836c73..fdd2a8d0778e2 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -1,14 +1,14 @@ use std::cmp; use crate::ich::StableHashingContext; -use crate::lint::builtin; use crate::lint::context::{CheckLintNameResult, LintStore}; -use crate::lint::{self, Level, Lint, LintId, LintSource}; -use crate::session::Session; +use crate::lint::{self, LintSource}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::HirId; +use rustc_session::lint::{builtin, Level, Lint, LintId}; +use rustc_session::Session; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{sym, Symbol}; use syntax::ast; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 17e84c24881c1..93fc09b4a2ac9 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,7 +3,7 @@ pub use self::StabilityLevel::*; -use crate::lint::{self, in_derive_expansion, Lint}; +use crate::lint::in_derive_expansion; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_hir::{self, HirId}; -use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::lint::{self, BuiltinLintDiagnostics, Lint, LintBuffer}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 9de46f86200e1..eca9df688c64f 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -82,7 +82,7 @@ rustc_queries! { desc { "looking up the native libraries of a linked crate" } } - query lint_levels(_: CrateNum) -> &'tcx lint::LintLevelMap { + query lint_levels(_: CrateNum) -> &'tcx LintLevelMap { eval_always desc { "computing the lint levels for items in this crate" } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index bfbcb042e7a73..e4309dd28f4a1 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -10,17 +10,18 @@ use super::elaborate_predicates; -use crate::lint; use crate::traits::{self, Obligation, ObligationCause}; use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; +use syntax::ast; + use std::borrow::Cow; use std::iter::{self}; -use syntax::ast::{self}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { @@ -179,7 +180,7 @@ fn object_safety_violations_for_trait( // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. tcx.lint_node_note( - lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY, + WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, *span, &format!( diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 7b66341ef1c96..f5199dbdabb2f 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -12,7 +12,6 @@ pub mod specialization_graph; use crate::infer::{InferCtxt, InferOk}; -use crate::lint; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; @@ -20,6 +19,7 @@ use crate::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; +use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::DUMMY_SP; use super::util::impl_trait_ref_and_oblig; @@ -342,7 +342,7 @@ pub(super) fn specialization_graph_provider( unreachable!("converted to hard error above") } FutureCompatOverlapErrorKind::Issue33140 => { - lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS + ORDER_DEPENDENT_TRAIT_OBJECTS } }; tcx.struct_span_lint_hir( diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1b0b5fc4d078d..a97f33b31b7a3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -8,7 +8,7 @@ use crate::hir::map as hir_map; use crate::hir::map::DefPathHash; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use crate::lint::{self, Lint}; +use crate::lint::{maybe_lint_level_root, struct_lint_level, LintSource, LintStore}; use crate::middle; use crate::middle::cstore::CrateStoreDyn; use crate::middle::cstore::EncodedMetadata; @@ -61,6 +61,7 @@ use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal}; use rustc_errors::DiagnosticBuilder; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; +use rustc_session::lint::{Level, Lint}; use rustc_session::node_id::NodeMap; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{kw, sym, Symbol}; @@ -946,7 +947,7 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, - pub lint_store: Lrc, + pub lint_store: Lrc, pub dep_graph: DepGraph, @@ -1115,7 +1116,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, - lint_store: Lrc, + lint_store: Lrc, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, @@ -2551,21 +2552,21 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_goals(xs)) } - pub fn lint_hir>( + pub fn lint_hir( self, lint: &'static Lint, hir_id: HirId, - span: S, + span: impl Into, msg: &str, ) { self.struct_span_lint_hir(lint, hir_id, span.into(), msg).emit() } - pub fn lint_hir_note>( + pub fn lint_hir_note( self, lint: &'static Lint, hir_id: HirId, - span: S, + span: impl Into, msg: &str, note: &str, ) { @@ -2574,11 +2575,11 @@ impl<'tcx> TyCtxt<'tcx> { err.emit() } - pub fn lint_node_note>( + pub fn lint_node_note( self, lint: &'static Lint, id: hir::HirId, - span: S, + span: impl Into, msg: &str, note: &str, ) { @@ -2598,7 +2599,7 @@ impl<'tcx> TyCtxt<'tcx> { if id == bound { return bound; } - if lint::maybe_lint_level_root(self, id) { + if maybe_lint_level_root(self, id) { return id; } let next = self.hir().get_parent_node(id); @@ -2613,7 +2614,7 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, mut id: hir::HirId, - ) -> (lint::Level, lint::LintSource) { + ) -> (Level, LintSource) { let sets = self.lint_levels(LOCAL_CRATE); loop { if let Some(pair) = sets.level_and_source(lint, id, self.sess) { @@ -2627,15 +2628,15 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn struct_span_lint_hir>( + pub fn struct_span_lint_hir( self, lint: &'static Lint, hir_id: HirId, - span: S, + span: impl Into, msg: &str, ) -> DiagnosticBuilder<'tcx> { let (level, src) = self.lint_level_at_node(lint, hir_id); - lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg) + struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg) } pub fn struct_lint_node( @@ -2645,7 +2646,7 @@ impl<'tcx> TyCtxt<'tcx> { msg: &str, ) -> DiagnosticBuilder<'tcx> { let (level, src) = self.lint_level_at_node(lint, id); - lint::struct_lint_level(self.sess, lint, level, src, None, msg) + struct_lint_level(self.sess, lint, level, src, None, msg) } pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx StableVec> { diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 6b272ab3d4a9b..1d41871bb33a9 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -1,7 +1,7 @@ use crate::dep_graph::{self, DepNode}; use crate::hir::exports::Export; use crate::infer::canonical::{self, Canonical}; -use crate::lint; +use crate::lint::LintLevelMap; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::cstore::{CrateSource, DepKind, NativeLibraryKind}; use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLibrary}; diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index dced4a0d15b0c..2d45e28044495 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -11,7 +11,7 @@ path = "lib.rs" [dependencies] log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors", package = "rustc_errors" } +rustc_errors = { path = "../librustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } rustc_feature = { path = "../librustc_feature" } rustc_parse = { path = "../librustc_parse" } From b93addba7add1f49249120b724023333db894055 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 03:03:48 +0100 Subject: [PATCH 0230/1253] move in_derive_expansion as Span method --- src/librustc/lint/mod.rs | 8 -------- src/librustc/middle/stability.rs | 5 ++--- src/librustc_span/lib.rs | 5 +++++ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 4afeb14494850..944868e79099b 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -494,11 +494,3 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { ExpnKind::Macro(..) => true, // definitely a plugin } } - -/// Returns `true` if `span` originates in a derive-macro's expansion. -pub fn in_derive_expansion(span: Span) -> bool { - if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_data().kind { - return true; - } - false -} diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 93fc09b4a2ac9..1176ffc79d26d 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,7 +3,6 @@ pub use self::StabilityLevel::*; -use crate::lint::in_derive_expansion; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -201,7 +200,7 @@ pub fn early_report_deprecation( lint: &'static Lint, span: Span, ) { - if in_derive_expansion(span) { + if span.in_derive_expansion() { return; } @@ -218,7 +217,7 @@ fn late_report_deprecation( def_id: DefId, hir_id: HirId, ) { - if in_derive_expansion(span) { + if span.in_derive_expansion() { return; } diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 8cca59df33846..f20cd6ae955f4 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -309,6 +309,11 @@ impl Span { self.ctxt() != SyntaxContext::root() } + /// Returns `true` if `span` originates in a derive-macro's expansion. + pub fn in_derive_expansion(self) -> bool { + matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _)) + } + #[inline] pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span { Span::new(lo, hi, SyntaxContext::root()) From c151782d76d1d664c1e55dd7ec2b44d3a18867c2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 03:28:45 +0100 Subject: [PATCH 0231/1253] reduce diversity in linting methods --- src/librustc/traits/object_safety.rs | 7 +++--- src/librustc/ty/context.rs | 26 -------------------- src/librustc_mir/transform/check_unsafety.rs | 10 ++++---- src/librustc_passes/liveness.rs | 17 +++++++------ 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index e4309dd28f4a1..ce57fb8110496 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -179,7 +179,7 @@ fn object_safety_violations_for_trait( { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.lint_node_note( + tcx.struct_span_lint_hir( WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, *span, @@ -187,8 +187,9 @@ fn object_safety_violations_for_trait( "the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id) ), - &violation.error_msg(), - ); + ) + .note(&violation.error_msg()) + .emit(); false } else { true diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a97f33b31b7a3..eb65caf6fbe8f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2562,32 +2562,6 @@ impl<'tcx> TyCtxt<'tcx> { self.struct_span_lint_hir(lint, hir_id, span.into(), msg).emit() } - pub fn lint_hir_note( - self, - lint: &'static Lint, - hir_id: HirId, - span: impl Into, - msg: &str, - note: &str, - ) { - let mut err = self.struct_span_lint_hir(lint, hir_id, span.into(), msg); - err.note(note); - err.emit() - } - - pub fn lint_node_note( - self, - lint: &'static Lint, - id: hir::HirId, - span: impl Into, - msg: &str, - note: &str, - ) { - let mut err = self.struct_span_lint_hir(lint, id, span.into(), msg); - err.note(note); - err.emit() - } - /// Walks upwards from `id` to find a node which might change lint levels with attributes. /// It stops at `bound` and just returns it if reached. pub fn maybe_lint_level_root_bounded( diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 02c54803842f0..3f342a6e6ca30 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -648,17 +648,17 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) { tcx.unsafe_derive_on_repr_packed(impl_def_id); } else { - tcx.lint_node_note( + tcx.struct_span_lint_hir( SAFE_PACKED_BORROWS, lint_hir_id, source_info.span, &format!( - "{} is unsafe and requires unsafe function or block \ - (error E0133)", + "{} is unsafe and requires unsafe function or block (error E0133)", description ), - &details.as_str(), - ); + ) + .note(&details.as_str()) + .emit(); } } } diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 0426f3fbea236..7718139f6e924 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -1513,13 +1513,16 @@ impl<'tcx> Liveness<'_, 'tcx> { if ln == self.s.exit_ln { false } else { self.assigned_on_exit(ln, var).is_some() }; if is_assigned { - self.ir.tcx.lint_hir_note( - lint::builtin::UNUSED_VARIABLES, - hir_id, - spans, - &format!("variable `{}` is assigned to, but never used", name), - &format!("consider using `_{}` instead", name), - ); + self.ir + .tcx + .struct_span_lint_hir( + lint::builtin::UNUSED_VARIABLES, + hir_id, + spans, + &format!("variable `{}` is assigned to, but never used", name), + ) + .note(&format!("consider using `_{}` instead", name)) + .emit(); } else { let mut err = self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, From 6f1a79cabe011c7487652e61130275a2940c47bc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 03:45:42 +0100 Subject: [PATCH 0232/1253] GlobalCtxt: Erase `LintStore` type. --- src/librustc/ty/context.rs | 10 +++++++--- src/librustc_lint/late.rs | 19 ++++++++++++------- src/librustc_lint/levels.rs | 5 +++-- src/librustc_lint/lib.rs | 1 + 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index eb65caf6fbe8f..15ef6d44d46da 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -8,7 +8,7 @@ use crate::hir::map as hir_map; use crate::hir::map::DefPathHash; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use crate::lint::{maybe_lint_level_root, struct_lint_level, LintSource, LintStore}; +use crate::lint::{maybe_lint_level_root, struct_lint_level, LintSource}; use crate::middle; use crate::middle::cstore::CrateStoreDyn; use crate::middle::cstore::EncodedMetadata; @@ -947,7 +947,11 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, - pub lint_store: Lrc, + /// This only ever stores a `LintStore` but we don't want a dependency on that type here. + /// + /// FIXME(Centril): consider `dyn LintStoreMarker` once + /// we can upcast to `Any` for some additional type safety. + pub lint_store: Lrc, pub dep_graph: DepGraph, @@ -1116,7 +1120,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, - lint_store: Lrc, + lint_store: Lrc, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index d8e0274cf43b9..e3ab604d39881 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -15,8 +15,7 @@ //! for all lint attributes. use rustc::hir::map::Map; -use rustc::lint::LateContext; -use rustc::lint::{LateLintPass, LateLintPassObject}; +use rustc::lint::{LateContext, LateLintPass, LateLintPassObject, LintStore}; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; use rustc_hir as hir; @@ -31,6 +30,12 @@ use syntax::walk_list; use log::debug; use std::slice; +/// Extract the `LintStore` from the query context. +/// This function exists because we've erased `LintStore` as `dyn Any` in the context. +crate fn unerased_lint_store<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx LintStore { + tcx.lint_store.downcast_ref().unwrap() +} + macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); }) } @@ -356,7 +361,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: &tcx.lint_store, + lint_store: unerased_lint_store(tcx), last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(), generics: None, only_module: true, @@ -386,7 +391,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); let mut passes: Vec<_> = - tcx.lint_store.late_module_passes.iter().map(|pass| (pass)()).collect(); + unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] }); @@ -403,7 +408,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: &tcx.lint_store, + lint_store: unerased_lint_store(tcx), last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, only_module: false, @@ -424,7 +429,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.lint_store.late_passes.iter().map(|p| (p)()).collect::>(); + let mut passes = unerased_lint_store(tcx).late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { if !passes.is_empty() { @@ -443,7 +448,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b } let mut passes: Vec<_> = - tcx.lint_store.late_module_passes.iter().map(|pass| (pass)()).collect(); + unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect(); for pass in &mut passes { tcx.sess diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index 3d3e57fe2bae3..a4910a02590d0 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,3 +1,4 @@ +use super::late::unerased_lint_store; use rustc::hir::map::Map; use rustc::lint::{LintLevelMap, LintLevelSets, LintLevelsBuilder, LintStore}; use rustc::ty::query::Providers; @@ -11,11 +12,11 @@ pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); - let store = &tcx.lint_store; + let store = unerased_lint_store(tcx); let mut builder = LintLevelMapBuilder { levels: LintLevelSets::builder(tcx.sess, false, &store), tcx: tcx, - store: store, + store, }; let krate = tcx.hir().krate(); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e708ded603b25..f62e9c466daee 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -14,6 +14,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(crate_visibility_modifier)] #![feature(nll)] #![recursion_limit = "256"] From 03bdfe9db3c7814e474413c4238f3eca7c2bf39a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 04:06:33 +0100 Subject: [PATCH 0233/1253] move logic to LintLevelsBuilder --- src/librustc/lint/context.rs | 4 +- src/librustc/lint/levels.rs | 80 +++++++++++++++--------------------- src/librustc_lint/levels.rs | 9 ++-- 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 867eb5a193707..779077f1ff44d 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -17,7 +17,7 @@ use self::TargetLint::*; use crate::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; -use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; +use crate::lint::levels::LintLevelsBuilder; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; use crate::middle::privacy::AccessLevels; use crate::middle::stability; @@ -674,7 +674,7 @@ impl<'a> EarlyContext<'a> { sess, krate, lint_store, - builder: LintLevelSets::builder(sess, warn_about_weird_lints, lint_store), + builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store), buffered, } } diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index fdd2a8d0778e2..04028c03d4364 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -37,44 +37,8 @@ enum LintSet { } impl LintLevelSets { - pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets { - let mut me = LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid }; - me.process_command_line(sess, lint_store); - return me; - } - - pub fn builder<'a>( - sess: &'a Session, - warn_about_weird_lints: bool, - store: &LintStore, - ) -> LintLevelsBuilder<'a> { - LintLevelsBuilder::new(sess, warn_about_weird_lints, LintLevelSets::new(sess, store)) - } - - fn process_command_line(&mut self, sess: &Session, store: &LintStore) { - let mut specs = FxHashMap::default(); - self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); - - for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, level); - - // If the cap is less than this specified level, e.g., if we've got - // `--cap-lints allow` but we've also got `-D foo` then we ignore - // this specification as the lint cap will set it to allow anyway. - let level = cmp::min(level, self.lint_cap); - - let lint_flag_val = Symbol::intern(lint_name); - let ids = match store.find_lints(&lint_name) { - Ok(ids) => ids, - Err(_) => continue, // errors handled in check_lint_name_cmdline above - }; - for id in ids { - let src = LintSource::CommandLine(lint_flag_val); - specs.insert(id, (level, src)); - } - } - - self.list.push(LintSet::CommandLine { specs: specs }); + fn new() -> Self { + LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid } } fn get_lint_level( @@ -159,19 +123,43 @@ pub struct BuilderPush { } impl<'a> LintLevelsBuilder<'a> { - pub fn new( - sess: &'a Session, - warn_about_weird_lints: bool, - sets: LintLevelSets, - ) -> LintLevelsBuilder<'a> { - assert_eq!(sets.list.len(), 1); - LintLevelsBuilder { + pub fn new(sess: &'a Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { + let mut builder = LintLevelsBuilder { sess, - sets, + sets: LintLevelSets::new(), cur: 0, id_to_set: Default::default(), warn_about_weird_lints, + }; + builder.process_command_line(sess, store); + assert_eq!(builder.sets.list.len(), 1); + builder + } + + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { + let mut specs = FxHashMap::default(); + self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); + + for &(ref lint_name, level) in &sess.opts.lint_opts { + store.check_lint_name_cmdline(sess, &lint_name, level); + + // If the cap is less than this specified level, e.g., if we've got + // `--cap-lints allow` but we've also got `-D foo` then we ignore + // this specification as the lint cap will set it to allow anyway. + let level = cmp::min(level, self.sets.lint_cap); + + let lint_flag_val = Symbol::intern(lint_name); + let ids = match store.find_lints(&lint_name) { + Ok(ids) => ids, + Err(_) => continue, // errors handled in check_lint_name_cmdline above + }; + for id in ids { + let src = LintSource::CommandLine(lint_flag_val); + specs.insert(id, (level, src)); + } } + + self.sets.list.push(LintSet::CommandLine { specs }); } /// Pushes a list of AST lint attributes onto this context. diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index a4910a02590d0..46ea04e5ccfca 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,6 +1,6 @@ use super::late::unerased_lint_store; use rustc::hir::map::Map; -use rustc::lint::{LintLevelMap, LintLevelSets, LintLevelsBuilder, LintStore}; +use rustc::lint::{LintLevelMap, LintLevelsBuilder, LintStore}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_hir as hir; @@ -13,11 +13,8 @@ pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); let store = unerased_lint_store(tcx); - let mut builder = LintLevelMapBuilder { - levels: LintLevelSets::builder(tcx.sess, false, &store), - tcx: tcx, - store, - }; + let levels = LintLevelsBuilder::new(tcx.sess, false, &store); + let mut builder = LintLevelMapBuilder { levels, tcx, store }; let krate = tcx.hir().krate(); let push = builder.levels.push(&krate.attrs, &store); From f577b44712f0cba0404482b3e44d24ceb5b54a9e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 05:20:28 +0100 Subject: [PATCH 0234/1253] move LintSource to levels --- src/librustc/lint/levels.rs | 39 ++++++++++++++++++++++++++----------- src/librustc/lint/mod.rs | 22 ++------------------- src/librustc/ty/context.rs | 6 +++--- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 04028c03d4364..d43bc57ea7a60 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -1,8 +1,8 @@ use std::cmp; use crate::ich::StableHashingContext; +use crate::lint; use crate::lint::context::{CheckLintNameResult, LintStore}; -use crate::lint::{self, LintSource}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; @@ -11,6 +11,7 @@ use rustc_session::lint::{builtin, Level, Lint, LintId}; use rustc_session::Session; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{sym, Symbol}; +use rustc_span::Span; use syntax::ast; use syntax::attr; use syntax::print::pprust; @@ -18,6 +19,22 @@ use syntax::sess::feature_err; use rustc_error_codes::*; +/// How a lint level was set. +#[derive(Clone, Copy, PartialEq, Eq, HashStable)] +pub enum LintSource { + /// Lint is at the default level as declared + /// in rustc or a plugin. + Default, + + /// Lint level was set by an attribute. + Node(Symbol, Span, Option /* RFC 2383 reason */), + + /// Lint level was set by a command-line flag. + CommandLine(Symbol), +} + +pub type LevelSource = (Level, LintSource); + pub struct LintLevelSets { list: Vec, lint_cap: Level, @@ -27,27 +44,27 @@ enum LintSet { CommandLine { // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which // flag. - specs: FxHashMap, + specs: FxHashMap, }, Node { - specs: FxHashMap, + specs: FxHashMap, parent: u32, }, } impl LintLevelSets { - fn new() -> Self { + pub fn new() -> Self { LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid } } - fn get_lint_level( + pub fn get_lint_level( &self, lint: &'static Lint, idx: u32, - aux: Option<&FxHashMap>, + aux: Option<&FxHashMap>, sess: &Session, - ) -> (Level, LintSource) { + ) -> LevelSource { let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux); // If `level` is none then we actually assume the default level for this @@ -59,7 +76,7 @@ impl LintLevelSets { // `allow(warnings)` in scope then we want to respect that instead. if level == Level::Warn { let (warnings_level, warnings_src) = - self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx, aux); + self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); if let Some(configured_warning_level) = warnings_level { if configured_warning_level != Level::Warn { level = configured_warning_level; @@ -79,11 +96,11 @@ impl LintLevelSets { return (level, src); } - fn get_lint_id_level( + pub fn get_lint_id_level( &self, id: LintId, mut idx: u32, - aux: Option<&FxHashMap>, + aux: Option<&FxHashMap>, ) -> (Option, LintSource) { if let Some(specs) = aux { if let Some(&(level, src)) = specs.get(&id) { @@ -499,7 +516,7 @@ impl LintLevelMap { lint: &'static Lint, id: HirId, session: &Session, - ) -> Option<(Level, LintSource)> { + ) -> Option { self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session)) } } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 944868e79099b..eefcb670d0e83 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -18,8 +18,8 @@ //! example) requires more effort. See `emit_lint` and `GatherNodeLevels` //! in `context.rs`. +pub use self::levels::LintSource::{self, *}; pub use self::Level::*; -pub use self::LintSource::*; use crate::ty::TyCtxt; use rustc_data_structures::sync; @@ -29,7 +29,6 @@ use rustc_session::lint::builtin::HardwiredLints; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; -use rustc_span::symbol::Symbol; use rustc_span::Span; use syntax::ast; @@ -38,9 +37,8 @@ pub use crate::lint::context::{ LintContext, LintStore, }; -pub use rustc_session::lint::builtin; +pub use rustc_session::lint::{builtin, LintArray, LintPass}; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; -pub use rustc_session::lint::{LintArray, LintPass}; #[macro_export] macro_rules! late_lint_methods { @@ -316,22 +314,6 @@ pub type EarlyLintPassObject = Box LateLintPass<'a, 'tcx> + sync::Send + sync::Sync + 'static>; -/// How a lint level was set. -#[derive(Clone, Copy, PartialEq, Eq, HashStable)] -pub enum LintSource { - /// Lint is at the default level as declared - /// in rustc or a plugin. - Default, - - /// Lint level was set by an attribute. - Node(ast::Name, Span, Option /* RFC 2383 reason */), - - /// Lint level was set by a command-line flag. - CommandLine(Symbol), -} - -pub type LevelSource = (Level, LintSource); - mod context; pub mod internal; mod levels; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 15ef6d44d46da..86f82c1304c48 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -20,9 +20,6 @@ use crate::mir::interpret::{Allocation, ConstValue, Scalar}; use crate::mir::{ interpret, BodyAndCache, Field, Local, Place, PlaceElem, ProjectionKind, Promoted, }; -use crate::session::config::CrateType; -use crate::session::config::{BorrowckMode, OutputFilenames}; -use crate::session::Session; use crate::traits; use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals}; use crate::ty::free_region_map::FreeRegionMap; @@ -49,6 +46,9 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRATE}; use rustc_hir::{HirId, Node, TraitCandidate}; use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; +use rustc_session::config::CrateType; +use rustc_session::config::{BorrowckMode, OutputFilenames}; +use rustc_session::Session; use arena::SyncDroplessArena; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; From eee84fe3960f0bb79f8bf02577bf00aa44302e00 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 05:57:07 +0100 Subject: [PATCH 0235/1253] move struct_lint_level to levels.rs --- src/librustc/lint/levels.rs | 168 ++++++++++++++++++++++++++++++++++-- src/librustc/lint/mod.rs | 158 +-------------------------------- 2 files changed, 161 insertions(+), 165 deletions(-) diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index d43bc57ea7a60..7e966a7491050 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -1,15 +1,15 @@ use std::cmp; use crate::ich::StableHashingContext; -use crate::lint; use crate::lint::context::{CheckLintNameResult, LintStore}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; use rustc_session::lint::{builtin, Level, Lint, LintId}; -use rustc_session::Session; -use rustc_span::source_map::MultiSpan; +use rustc_session::{DiagnosticMessageId, Session}; +use rustc_span::hygiene::MacroKind; +use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast; @@ -326,7 +326,7 @@ impl<'a> LintLevelsBuilder<'a> { Also `cfg_attr(cargo-clippy)` won't be necessary anymore", name ); - lint::struct_lint_level( + struct_lint_level( self.sess, lint, lvl, @@ -366,7 +366,7 @@ impl<'a> LintLevelsBuilder<'a> { let lint = builtin::RENAMED_AND_REMOVED_LINTS; let (level, src) = self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); - let mut err = lint::struct_lint_level( + let mut err = struct_lint_level( self.sess, lint, level, @@ -389,7 +389,7 @@ impl<'a> LintLevelsBuilder<'a> { let (level, src) = self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); let msg = format!("unknown lint: `{}`", name); - let mut db = lint::struct_lint_level( + let mut db = struct_lint_level( self.sess, lint, level, @@ -480,7 +480,7 @@ impl<'a> LintLevelsBuilder<'a> { msg: &str, ) -> DiagnosticBuilder<'a> { let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); - lint::struct_lint_level(self.sess, lint, level, src, span, msg) + struct_lint_level(self.sess, lint, level, src, span, msg) } /// Registers the ID provided with the current set of lints stored in @@ -553,3 +553,155 @@ impl<'a> HashStable> for LintLevelMap { }) } } + +pub fn struct_lint_level<'a>( + sess: &'a Session, + lint: &'static Lint, + level: Level, + src: LintSource, + span: Option, + msg: &str, +) -> DiagnosticBuilder<'a> { + let mut err = match (level, span) { + (Level::Allow, _) => return sess.diagnostic().struct_dummy(), + (Level::Warn, Some(span)) => sess.struct_span_warn(span, msg), + (Level::Warn, None) => sess.struct_warn(msg), + (Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => sess.struct_span_err(span, msg), + (Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(msg), + }; + + // Check for future incompatibility lints and issue a stronger warning. + let lint_id = LintId::of(lint); + let future_incompatible = lint.future_incompatible; + + // If this code originates in a foreign macro, aka something that this crate + // did not itself author, then it's likely that there's nothing this crate + // can do about it. We probably want to skip the lint entirely. + if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) { + // Any suggestions made here are likely to be incorrect, so anything we + // emit shouldn't be automatically fixed by rustfix. + err.allow_suggestions(false); + + // If this is a future incompatible lint it'll become a hard error, so + // we have to emit *something*. Also allow lints to whitelist themselves + // on a case-by-case basis for emission in a foreign macro. + if future_incompatible.is_none() && !lint.report_in_external_macro { + err.cancel(); + // Don't continue further, since we don't want to have + // `diag_span_note_once` called for a diagnostic that isn't emitted. + return err; + } + } + + let name = lint.name_lower(); + match src { + LintSource::Default => { + sess.diag_note_once( + &mut err, + DiagnosticMessageId::from(lint), + &format!("`#[{}({})]` on by default", level.as_str(), name), + ); + } + LintSource::CommandLine(lint_flag_val) => { + let flag = match level { + Level::Warn => "-W", + Level::Deny => "-D", + Level::Forbid => "-F", + Level::Allow => panic!(), + }; + let hyphen_case_lint_name = name.replace("_", "-"); + if lint_flag_val.as_str() == name { + sess.diag_note_once( + &mut err, + DiagnosticMessageId::from(lint), + &format!( + "requested on the command line with `{} {}`", + flag, hyphen_case_lint_name + ), + ); + } else { + let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-"); + sess.diag_note_once( + &mut err, + DiagnosticMessageId::from(lint), + &format!( + "`{} {}` implied by `{} {}`", + flag, hyphen_case_lint_name, flag, hyphen_case_flag_val + ), + ); + } + } + LintSource::Node(lint_attr_name, src, reason) => { + if let Some(rationale) = reason { + err.note(&rationale.as_str()); + } + sess.diag_span_note_once( + &mut err, + DiagnosticMessageId::from(lint), + src, + "lint level defined here", + ); + if lint_attr_name.as_str() != name { + let level_str = level.as_str(); + sess.diag_note_once( + &mut err, + DiagnosticMessageId::from(lint), + &format!( + "`#[{}({})]` implied by `#[{}({})]`", + level_str, name, level_str, lint_attr_name + ), + ); + } + } + } + + err.code(DiagnosticId::Lint(name)); + + if let Some(future_incompatible) = future_incompatible { + const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \ + it will become a hard error"; + + let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) { + "once this method is added to the standard library, \ + the ambiguity may cause an error or change in behavior!" + .to_owned() + } else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) { + "this borrowing pattern was not meant to be accepted, \ + and may become a hard error in the future" + .to_owned() + } else if let Some(edition) = future_incompatible.edition { + format!("{} in the {} edition!", STANDARD_MESSAGE, edition) + } else { + format!("{} in a future release!", STANDARD_MESSAGE) + }; + let citation = format!("for more information, see {}", future_incompatible.reference); + err.warn(&explanation); + err.note(&citation); + } + + return err; +} + +/// Returns whether `span` originates in a foreign crate's external macro. +/// +/// This is used to test whether a lint should not even begin to figure out whether it should +/// be reported on the current node. +pub fn in_external_macro(sess: &Session, span: Span) -> bool { + let expn_data = span.ctxt().outer_expn_data(); + match expn_data.kind { + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, + ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" + ExpnKind::Macro(MacroKind::Bang, _) => { + if expn_data.def_site.is_dummy() { + // Dummy span for the `def_site` means it's an external macro. + return true; + } + match sess.source_map().span_to_snippet(expn_data.def_site) { + Ok(code) => !code.starts_with("macro_rules"), + // No snippet means external macro or compiler-builtin expansion. + Err(_) => true, + } + } + ExpnKind::Macro(..) => true, // definitely a plugin + } +} diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index eefcb670d0e83..371fa27cb2418 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -23,12 +23,8 @@ pub use self::Level::*; use crate::ty::TyCtxt; use rustc_data_structures::sync; -use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; -use rustc_session::{DiagnosticMessageId, Session}; -use rustc_span::hygiene::MacroKind; -use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; use rustc_span::Span; use syntax::ast; @@ -318,161 +314,9 @@ mod context; pub mod internal; mod levels; -pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder}; - -pub fn struct_lint_level<'a>( - sess: &'a Session, - lint: &'static Lint, - level: Level, - src: LintSource, - span: Option, - msg: &str, -) -> DiagnosticBuilder<'a> { - let mut err = match (level, span) { - (Level::Allow, _) => return sess.diagnostic().struct_dummy(), - (Level::Warn, Some(span)) => sess.struct_span_warn(span, msg), - (Level::Warn, None) => sess.struct_warn(msg), - (Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => sess.struct_span_err(span, msg), - (Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(msg), - }; - - // Check for future incompatibility lints and issue a stronger warning. - let lint_id = LintId::of(lint); - let future_incompatible = lint.future_incompatible; - - // If this code originates in a foreign macro, aka something that this crate - // did not itself author, then it's likely that there's nothing this crate - // can do about it. We probably want to skip the lint entirely. - if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) { - // Any suggestions made here are likely to be incorrect, so anything we - // emit shouldn't be automatically fixed by rustfix. - err.allow_suggestions(false); - - // If this is a future incompatible lint it'll become a hard error, so - // we have to emit *something*. Also allow lints to whitelist themselves - // on a case-by-case basis for emission in a foreign macro. - if future_incompatible.is_none() && !lint.report_in_external_macro { - err.cancel(); - // Don't continue further, since we don't want to have - // `diag_span_note_once` called for a diagnostic that isn't emitted. - return err; - } - } - - let name = lint.name_lower(); - match src { - LintSource::Default => { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!("`#[{}({})]` on by default", level.as_str(), name), - ); - } - LintSource::CommandLine(lint_flag_val) => { - let flag = match level { - Level::Warn => "-W", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Allow => panic!(), - }; - let hyphen_case_lint_name = name.replace("_", "-"); - if lint_flag_val.as_str() == name { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "requested on the command line with `{} {}`", - flag, hyphen_case_lint_name - ), - ); - } else { - let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-"); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`{} {}` implied by `{} {}`", - flag, hyphen_case_lint_name, flag, hyphen_case_flag_val - ), - ); - } - } - LintSource::Node(lint_attr_name, src, reason) => { - if let Some(rationale) = reason { - err.note(&rationale.as_str()); - } - sess.diag_span_note_once( - &mut err, - DiagnosticMessageId::from(lint), - src, - "lint level defined here", - ); - if lint_attr_name.as_str() != name { - let level_str = level.as_str(); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`#[{}({})]` implied by `#[{}({})]`", - level_str, name, level_str, lint_attr_name - ), - ); - } - } - } - - err.code(DiagnosticId::Lint(name)); - - if let Some(future_incompatible) = future_incompatible { - const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \ - it will become a hard error"; - - let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) { - "once this method is added to the standard library, \ - the ambiguity may cause an error or change in behavior!" - .to_owned() - } else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) { - "this borrowing pattern was not meant to be accepted, \ - and may become a hard error in the future" - .to_owned() - } else if let Some(edition) = future_incompatible.edition { - format!("{} in the {} edition!", STANDARD_MESSAGE, edition) - } else { - format!("{} in a future release!", STANDARD_MESSAGE) - }; - let citation = format!("for more information, see {}", future_incompatible.reference); - err.warn(&explanation); - err.note(&citation); - } - - return err; -} +pub use self::levels::{struct_lint_level, LintLevelMap, LintLevelSets, LintLevelsBuilder}; pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { let attrs = tcx.hir().attrs(id); attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) } - -/// Returns whether `span` originates in a foreign crate's external macro. -/// -/// This is used to test whether a lint should not even begin to figure out whether it should -/// be reported on the current node. -pub fn in_external_macro(sess: &Session, span: Span) -> bool { - let expn_data = span.ctxt().outer_expn_data(); - match expn_data.kind { - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, - ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" - ExpnKind::Macro(MacroKind::Bang, _) => { - if expn_data.def_site.is_dummy() { - // Dummy span for the `def_site` means it's an external macro. - return true; - } - match sess.source_map().span_to_snippet(expn_data.def_site) { - Ok(code) => !code.starts_with("macro_rules"), - // No snippet means external macro or compiler-builtin expansion. - Err(_) => true, - } - } - ExpnKind::Macro(..) => true, // definitely a plugin - } -} From 16bf2783b5cd5f0a6155094f885890f4c0834477 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 06:08:07 +0100 Subject: [PATCH 0236/1253] inline maybe_lint_level_root --- src/librustc/lint/mod.rs | 6 ------ src/librustc/ty/context.rs | 14 ++++++-------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 371fa27cb2418..6eec77d1d9075 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,7 +21,6 @@ pub use self::levels::LintSource::{self, *}; pub use self::Level::*; -use crate::ty::TyCtxt; use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; @@ -315,8 +314,3 @@ pub mod internal; mod levels; pub use self::levels::{struct_lint_level, LintLevelMap, LintLevelSets, LintLevelsBuilder}; - -pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { - let attrs = tcx.hir().attrs(id); - attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) -} diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 86f82c1304c48..c28631b982577 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -8,7 +8,7 @@ use crate::hir::map as hir_map; use crate::hir::map::DefPathHash; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use crate::lint::{maybe_lint_level_root, struct_lint_level, LintSource}; +use crate::lint::{struct_lint_level, LintSource}; use crate::middle; use crate::middle::cstore::CrateStoreDyn; use crate::middle::cstore::EncodedMetadata; @@ -2568,19 +2568,17 @@ impl<'tcx> TyCtxt<'tcx> { /// Walks upwards from `id` to find a node which might change lint levels with attributes. /// It stops at `bound` and just returns it if reached. - pub fn maybe_lint_level_root_bounded( - self, - mut id: hir::HirId, - bound: hir::HirId, - ) -> hir::HirId { + pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId { + let hir = self.hir(); loop { if id == bound { return bound; } - if maybe_lint_level_root(self, id) { + + if hir.attrs(id).iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) { return id; } - let next = self.hir().get_parent_node(id); + let next = hir.get_parent_node(id); if next == id { bug!("lint traversal reached the root of the crate"); } From 03dfa642d9080a12e491681097806eb4207d19dc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 06:42:42 +0100 Subject: [PATCH 0237/1253] lints: promote levels.rs to lint.rs & extract passes.rs --- src/librustc/{lint/levels.rs => lint.rs} | 12 ++++++++++-- src/librustc/lint/context.rs | 4 ++-- src/librustc/lint/internal.rs | 3 ++- src/librustc/lint/{mod.rs => passes.rs} | 8 +------- src/librustc/mir/interpret/error.rs | 2 +- src/librustc_lint/array_into_iter.rs | 3 ++- src/librustc_passes/dead.rs | 2 +- src/librustdoc/core.rs | 2 +- src/librustdoc/lib.rs | 1 + 9 files changed, 21 insertions(+), 16 deletions(-) rename src/librustc/{lint/levels.rs => lint.rs} (98%) rename src/librustc/lint/{mod.rs => passes.rs} (98%) diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint.rs similarity index 98% rename from src/librustc/lint/levels.rs rename to src/librustc/lint.rs index 7e966a7491050..c4332fa0c6346 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint.rs @@ -1,12 +1,12 @@ use std::cmp; use crate::ich::StableHashingContext; -use crate::lint::context::{CheckLintNameResult, LintStore}; +use crate::lint::context::CheckLintNameResult; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; -use rustc_session::lint::{builtin, Level, Lint, LintId}; +pub use rustc_session::lint::{builtin, Level, Lint, LintId, LintPass}; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; @@ -19,6 +19,14 @@ use syntax::sess::feature_err; use rustc_error_codes::*; +mod context; +pub mod internal; +mod passes; + +pub use context::add_elided_lifetime_in_path_suggestion; +pub use context::{EarlyContext, LateContext, LintContext, LintStore}; +pub use passes::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; + /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable)] pub enum LintSource { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 779077f1ff44d..702d707346bd8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -17,8 +17,8 @@ use self::TargetLint::*; use crate::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; -use crate::lint::levels::LintLevelsBuilder; -use crate::lint::{EarlyLintPassObject, LateLintPassObject}; +use crate::lint::passes::{EarlyLintPassObject, LateLintPassObject}; +use crate::lint::LintLevelsBuilder; use crate::middle::privacy::AccessLevels; use crate::middle::stability; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 30679226b9b71..33282a7291eb9 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -1,7 +1,8 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::lint::context::{EarlyContext, LateContext, LintContext}; +use crate::lint::passes::{EarlyLintPass, LateLintPass}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/passes.rs similarity index 98% rename from src/librustc/lint/mod.rs rename to src/librustc/lint/passes.rs index 6eec77d1d9075..41671ccc6c0fc 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/passes.rs @@ -18,8 +18,8 @@ //! example) requires more effort. See `emit_lint` and `GatherNodeLevels` //! in `context.rs`. -pub use self::levels::LintSource::{self, *}; pub use self::Level::*; +pub use crate::lint::LintSource::{self, *}; use rustc_data_structures::sync; use rustc_hir as hir; @@ -308,9 +308,3 @@ macro_rules! declare_combined_early_lint_pass { pub type EarlyLintPassObject = Box; pub type LateLintPassObject = Box LateLintPass<'a, 'tcx> + sync::Send + sync::Sync + 'static>; - -mod context; -pub mod internal; -mod levels; - -pub use self::levels::{struct_lint_level, LintLevelMap, LintLevelSets, LintLevelsBuilder}; diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index ed61534d54519..8643bd63d8cba 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -154,7 +154,7 @@ impl<'tcx> ConstEvalErr<'tcx> { .next() .unwrap_or(lint_root); tcx.struct_span_lint_hir( - crate::rustc::lint::builtin::CONST_ERR, + rustc_session::lint::builtin::CONST_ERR, hir_id, tcx.span, message, diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 19d1052d1b243..7f053f9de2953 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -1,8 +1,9 @@ -use rustc::lint::{FutureIncompatibleInfo, LateContext, LateLintPass, LintContext}; +use rustc::lint::{LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_session::lint::FutureIncompatibleInfo; use rustc_span::symbol::sym; declare_lint! { diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index f626a5f8cb0d1..f2778b2aa6bcd 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -3,7 +3,6 @@ // from live codes are live, and everything else is dead. use rustc::hir::map::Map; -use rustc::lint; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::privacy; use rustc::ty::{self, DefIdTree, TyCtxt}; @@ -14,6 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{Node, PatKind, TyKind}; +use rustc_session::lint; use rustc_span; use rustc_span::symbol::sym; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 3cda1b3be75f1..61a7bc765bcf2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,4 +1,3 @@ -use rustc::lint; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::session::config::ErrorOutputType; @@ -14,6 +13,7 @@ use rustc_hir::HirId; use rustc_interface::interface; use rustc_lint; use rustc_resolve as resolve; +use rustc_session::lint; use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::json::JsonEmitter; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b15dae452ff05..032a5c83d1724 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -36,6 +36,7 @@ extern crate rustc_metadata; extern crate rustc_mir; extern crate rustc_parse; extern crate rustc_resolve; +extern crate rustc_session; extern crate rustc_span as rustc_span; extern crate rustc_target; extern crate rustc_typeck; From 8c12c424e28beb9bf69df8ca0f68096d8b9a6a21 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 06:49:49 +0100 Subject: [PATCH 0238/1253] {rustc::lint -> rustc_lint}::internal --- Cargo.lock | 1 + src/librustc/lint.rs | 1 - src/librustc_lint/Cargo.toml | 1 + src/{librustc/lint => librustc_lint}/internal.rs | 4 ++-- src/librustc_lint/lib.rs | 3 ++- 5 files changed, 6 insertions(+), 4 deletions(-) rename src/{librustc/lint => librustc_lint}/internal.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..214114240aff9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3663,6 +3663,7 @@ dependencies = [ "log", "rustc", "rustc_data_structures", + "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_hir", diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs index c4332fa0c6346..b85982ac3ffce 100644 --- a/src/librustc/lint.rs +++ b/src/librustc/lint.rs @@ -20,7 +20,6 @@ use syntax::sess::feature_err; use rustc_error_codes::*; mod context; -pub mod internal; mod passes; pub use context::add_elided_lifetime_in_path_suggestion; diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 7e23e70577975..abf9f96e6475b 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -13,6 +13,7 @@ log = "0.4" unicode-security = "0.0.2" rustc = { path = "../librustc" } rustc_errors = { path = "../librustc_errors" } +rustc_error_codes = { path = "../librustc_error_codes" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } diff --git a/src/librustc/lint/internal.rs b/src/librustc_lint/internal.rs similarity index 98% rename from src/librustc/lint/internal.rs rename to src/librustc_lint/internal.rs index 33282a7291eb9..30417bf5a24fc 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -1,8 +1,8 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::lint::context::{EarlyContext, LateContext, LintContext}; -use crate::lint::passes::{EarlyLintPass, LateLintPass}; +use crate::lint::{EarlyContext, LateContext, LintContext}; +use crate::lint::{EarlyLintPass, LateLintPass}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index f62e9c466daee..e11472e1136f7 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -26,6 +26,7 @@ extern crate rustc_session; mod array_into_iter; pub mod builtin; mod early; +mod internal; mod late; mod levels; mod non_ascii_idents; @@ -53,10 +54,10 @@ use lint::LintId; use array_into_iter::ArrayIntoIter; use builtin::*; +use internal::*; use non_ascii_idents::*; use nonstandard_style::*; use redundant_semicolon::*; -use rustc::lint::internal::*; use types::*; use unused::*; From f58db203623b89e6c9e68d4b9ccb000031825cc4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 07:52:01 +0100 Subject: [PATCH 0239/1253] move rustc::lint::{context, passes} to rustc_lint. Also do some cleanup of the interface. --- Cargo.lock | 1 + src/librustc/lib.rs | 2 - src/librustc/lint.rs | 443 ++---------------- src/librustc_ast_lowering/lib.rs | 3 +- src/librustc_driver/lib.rs | 13 +- src/librustc_interface/interface.rs | 5 +- src/librustc_interface/passes.rs | 13 +- src/librustc_interface/queries.rs | 5 +- src/librustc_lint/array_into_iter.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- .../lint => librustc_lint}/context.rs | 59 +-- src/librustc_lint/early.rs | 9 +- src/librustc_lint/internal.rs | 3 +- src/librustc_lint/late.rs | 4 +- src/librustc_lint/levels.rs | 391 +++++++++++++++- src/librustc_lint/lib.rs | 32 +- src/librustc_lint/non_ascii_idents.rs | 2 +- src/librustc_lint/nonstandard_style.rs | 2 +- .../lint => librustc_lint}/passes.rs | 14 +- src/librustc_lint/redundant_semicolon.rs | 2 +- src/librustc_lint/types.rs | 2 +- src/librustc_lint/unused.rs | 4 +- src/librustc_plugin_impl/Cargo.toml | 1 + src/librustc_plugin_impl/lib.rs | 2 +- 24 files changed, 505 insertions(+), 513 deletions(-) rename src/{librustc/lint => librustc_lint}/context.rs (93%) rename src/{librustc/lint => librustc_lint}/passes.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index 214114240aff9..0008a4a361531 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3789,6 +3789,7 @@ dependencies = [ "rustc_error_codes", "rustc_errors", "rustc_hir", + "rustc_lint", "rustc_metadata", "rustc_span", "syntax", diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index cf424ffe7b293..ef22c6621ae2c 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -72,8 +72,6 @@ extern crate rustc_data_structures; #[macro_use] extern crate log; #[macro_use] -extern crate syntax; -#[macro_use] extern crate smallvec; #[cfg(test)] diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs index b85982ac3ffce..2ed6cd5283b10 100644 --- a/src/librustc/lint.rs +++ b/src/librustc/lint.rs @@ -1,30 +1,15 @@ use std::cmp; use crate::ich::StableHashingContext; -use crate::lint::context::CheckLintNameResult; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; pub use rustc_session::lint::{builtin, Level, Lint, LintId, LintPass}; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; -use rustc_span::symbol::{sym, Symbol}; -use rustc_span::Span; -use syntax::ast; -use syntax::attr; -use syntax::print::pprust; -use syntax::sess::feature_err; - -use rustc_error_codes::*; - -mod context; -mod passes; - -pub use context::add_elided_lifetime_in_path_suggestion; -pub use context::{EarlyContext, LateContext, LintContext, LintStore}; -pub use passes::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; +use rustc_span::{Span, Symbol}; /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable)] @@ -43,11 +28,11 @@ pub enum LintSource { pub type LevelSource = (Level, LintSource); pub struct LintLevelSets { - list: Vec, - lint_cap: Level, + pub list: Vec, + pub lint_cap: Level, } -enum LintSet { +pub enum LintSet { CommandLine { // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which // flag. @@ -133,381 +118,9 @@ impl LintLevelSets { } } -pub struct LintLevelsBuilder<'a> { - sess: &'a Session, - sets: LintLevelSets, - id_to_set: FxHashMap, - cur: u32, - warn_about_weird_lints: bool, -} - -pub struct BuilderPush { - prev: u32, - pub changed: bool, -} - -impl<'a> LintLevelsBuilder<'a> { - pub fn new(sess: &'a Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { - let mut builder = LintLevelsBuilder { - sess, - sets: LintLevelSets::new(), - cur: 0, - id_to_set: Default::default(), - warn_about_weird_lints, - }; - builder.process_command_line(sess, store); - assert_eq!(builder.sets.list.len(), 1); - builder - } - - fn process_command_line(&mut self, sess: &Session, store: &LintStore) { - let mut specs = FxHashMap::default(); - self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); - - for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, level); - - // If the cap is less than this specified level, e.g., if we've got - // `--cap-lints allow` but we've also got `-D foo` then we ignore - // this specification as the lint cap will set it to allow anyway. - let level = cmp::min(level, self.sets.lint_cap); - - let lint_flag_val = Symbol::intern(lint_name); - let ids = match store.find_lints(&lint_name) { - Ok(ids) => ids, - Err(_) => continue, // errors handled in check_lint_name_cmdline above - }; - for id in ids { - let src = LintSource::CommandLine(lint_flag_val); - specs.insert(id, (level, src)); - } - } - - self.sets.list.push(LintSet::CommandLine { specs }); - } - - /// Pushes a list of AST lint attributes onto this context. - /// - /// This function will return a `BuilderPush` object which should be passed - /// to `pop` when this scope for the attributes provided is exited. - /// - /// This function will perform a number of tasks: - /// - /// * It'll validate all lint-related attributes in `attrs` - /// * It'll mark all lint-related attributes as used - /// * Lint levels will be updated based on the attributes provided - /// * Lint attributes are validated, e.g., a #[forbid] can't be switched to - /// #[allow] - /// - /// Don't forget to call `pop`! - pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { - let mut specs = FxHashMap::default(); - let sess = self.sess; - let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); - for attr in attrs { - let level = match Level::from_symbol(attr.name_or_empty()) { - None => continue, - Some(lvl) => lvl, - }; - - let meta = unwrap_or!(attr.meta(), continue); - attr::mark_used(attr); - - let mut metas = unwrap_or!(meta.meta_item_list(), continue); - - if metas.is_empty() { - // FIXME (#55112): issue unused-attributes lint for `#[level()]` - continue; - } - - // Before processing the lint names, look for a reason (RFC 2383) - // at the end. - let mut reason = None; - let tail_li = &metas[metas.len() - 1]; - if let Some(item) = tail_li.meta_item() { - match item.kind { - ast::MetaItemKind::Word => {} // actual lint names handled later - ast::MetaItemKind::NameValue(ref name_value) => { - if item.path == sym::reason { - // found reason, reslice meta list to exclude it - metas = &metas[0..metas.len() - 1]; - // FIXME (#55112): issue unused-attributes lint if we thereby - // don't have any lint names (`#[level(reason = "foo")]`) - if let ast::LitKind::Str(rationale, _) = name_value.kind { - if !self.sess.features_untracked().lint_reasons { - feature_err( - &self.sess.parse_sess, - sym::lint_reasons, - item.span, - "lint reasons are experimental", - ) - .emit(); - } - reason = Some(rationale); - } else { - bad_attr(name_value.span) - .span_label(name_value.span, "reason must be a string literal") - .emit(); - } - } else { - bad_attr(item.span) - .span_label(item.span, "bad attribute argument") - .emit(); - } - } - ast::MetaItemKind::List(_) => { - bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); - } - } - } - - for li in metas { - let meta_item = match li.meta_item() { - Some(meta_item) if meta_item.is_word() => meta_item, - _ => { - let sp = li.span(); - let mut err = bad_attr(sp); - let mut add_label = true; - if let Some(item) = li.meta_item() { - if let ast::MetaItemKind::NameValue(_) = item.kind { - if item.path == sym::reason { - err.span_label(sp, "reason in lint attribute must come last"); - add_label = false; - } - } - } - if add_label { - err.span_label(sp, "bad attribute argument"); - } - err.emit(); - continue; - } - }; - let tool_name = if meta_item.path.segments.len() > 1 { - let tool_ident = meta_item.path.segments[0].ident; - if !attr::is_known_lint_tool(tool_ident) { - struct_span_err!( - sess, - tool_ident.span, - E0710, - "an unknown tool name found in scoped lint: `{}`", - pprust::path_to_string(&meta_item.path), - ) - .emit(); - continue; - } - - Some(tool_ident.name) - } else { - None - }; - let name = meta_item.path.segments.last().expect("empty lint name").ident.name; - match store.check_lint_name(&name.as_str(), tool_name) { - CheckLintNameResult::Ok(ids) => { - let src = LintSource::Node(name, li.span(), reason); - for id in ids { - specs.insert(*id, (level, src)); - } - } - - CheckLintNameResult::Tool(result) => { - match result { - Ok(ids) => { - let complete_name = &format!("{}::{}", tool_name.unwrap(), name); - let src = LintSource::Node( - Symbol::intern(complete_name), - li.span(), - reason, - ); - for id in ids { - specs.insert(*id, (level, src)); - } - } - Err((Some(ids), new_lint_name)) => { - let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (lvl, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); - let msg = format!( - "lint name `{}` is deprecated \ - and may not have an effect in the future. \ - Also `cfg_attr(cargo-clippy)` won't be necessary anymore", - name - ); - struct_lint_level( - self.sess, - lint, - lvl, - src, - Some(li.span().into()), - &msg, - ) - .span_suggestion( - li.span(), - "change it to", - new_lint_name.to_string(), - Applicability::MachineApplicable, - ) - .emit(); - - let src = LintSource::Node( - Symbol::intern(&new_lint_name), - li.span(), - reason, - ); - for id in ids { - specs.insert(*id, (level, src)); - } - } - Err((None, _)) => { - // If Tool(Err(None, _)) is returned, then either the lint does not - // exist in the tool or the code was not compiled with the tool and - // therefore the lint was never added to the `LintStore`. To detect - // this is the responsibility of the lint tool. - } - } - } - - _ if !self.warn_about_weird_lints => {} - - CheckLintNameResult::Warning(msg, renamed) => { - let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (level, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); - let mut err = struct_lint_level( - self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg, - ); - if let Some(new_name) = renamed { - err.span_suggestion( - li.span(), - "use the new name", - new_name, - Applicability::MachineApplicable, - ); - } - err.emit(); - } - CheckLintNameResult::NoLint(suggestion) => { - let lint = builtin::UNKNOWN_LINTS; - let (level, src) = - self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); - let msg = format!("unknown lint: `{}`", name); - let mut db = struct_lint_level( - self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg, - ); - - if let Some(suggestion) = suggestion { - db.span_suggestion( - li.span(), - "did you mean", - suggestion.to_string(), - Applicability::MachineApplicable, - ); - } - - db.emit(); - } - } - } - } - - for (id, &(level, ref src)) in specs.iter() { - if level == Level::Forbid { - continue; - } - let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) { - (Some(Level::Forbid), src) => src, - _ => continue, - }; - let forbidden_lint_name = match forbid_src { - LintSource::Default => id.to_string(), - LintSource::Node(name, _, _) => name.to_string(), - LintSource::CommandLine(name) => name.to_string(), - }; - let (lint_attr_name, lint_attr_span) = match *src { - LintSource::Node(name, span, _) => (name, span), - _ => continue, - }; - let mut diag_builder = struct_span_err!( - self.sess, - lint_attr_span, - E0453, - "{}({}) overruled by outer forbid({})", - level.as_str(), - lint_attr_name, - forbidden_lint_name - ); - diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); - match forbid_src { - LintSource::Default => {} - LintSource::Node(_, forbid_source_span, reason) => { - diag_builder.span_label(forbid_source_span, "`forbid` level set here"); - if let Some(rationale) = reason { - diag_builder.note(&rationale.as_str()); - } - } - LintSource::CommandLine(_) => { - diag_builder.note("`forbid` lint level was set on command line"); - } - } - diag_builder.emit(); - // don't set a separate error for every lint in the group - break; - } - - let prev = self.cur; - if specs.len() > 0 { - self.cur = self.sets.list.len() as u32; - self.sets.list.push(LintSet::Node { specs: specs, parent: prev }); - } - - BuilderPush { prev: prev, changed: prev != self.cur } - } - - /// Called after `push` when the scope of a set of attributes are exited. - pub fn pop(&mut self, push: BuilderPush) { - self.cur = push.prev; - } - - /// Used to emit a lint-related diagnostic based on the current state of - /// this lint context. - pub fn struct_lint( - &self, - lint: &'static Lint, - span: Option, - msg: &str, - ) -> DiagnosticBuilder<'a> { - let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); - struct_lint_level(self.sess, lint, level, src, span, msg) - } - - /// Registers the ID provided with the current set of lints stored in - /// this context. - pub fn register_id(&mut self, id: HirId) { - self.id_to_set.insert(id, self.cur); - } - - pub fn build(self) -> LintLevelSets { - self.sets - } - - pub fn build_map(self) -> LintLevelMap { - LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } - } -} - pub struct LintLevelMap { - sets: LintLevelSets, - id_to_set: FxHashMap, + pub sets: LintLevelSets, + pub id_to_set: FxHashMap, } impl LintLevelMap { @@ -712,3 +325,45 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { ExpnKind::Macro(..) => true, // definitely a plugin } } + +pub fn add_elided_lifetime_in_path_suggestion( + sess: &Session, + db: &mut DiagnosticBuilder<'_>, + n: usize, + path_span: Span, + incl_angl_brckt: bool, + insertion_span: Span, + anon_lts: String, +) { + let (replace_span, suggestion) = if incl_angl_brckt { + (insertion_span, anon_lts) + } else { + // When possible, prefer a suggestion that replaces the whole + // `Path` expression with `Path<'_, T>`, rather than inserting `'_, ` + // at a point (which makes for an ugly/confusing label) + if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) { + // But our spans can get out of whack due to macros; if the place we think + // we want to insert `'_` isn't even within the path expression's span, we + // should bail out of making any suggestion rather than panicking on a + // subtract-with-overflow or string-slice-out-out-bounds (!) + // FIXME: can we do better? + if insertion_span.lo().0 < path_span.lo().0 { + return; + } + let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize; + if insertion_index > snippet.len() { + return; + } + let (before, after) = snippet.split_at(insertion_index); + (path_span, format!("{}{}{}", before, anon_lts, after)) + } else { + (insertion_span, anon_lts) + } + }; + db.span_suggestion( + replace_span, + &format!("indicate the anonymous lifetime{}", pluralize!(n)), + suggestion, + Applicability::MachineApplicable, + ); +} diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 58b8e8a089ad3..d30d0bd8345ff 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -37,7 +37,6 @@ use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; -use rustc::lint::builtin; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -51,7 +50,7 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::IndexVec; use rustc_session::config::nightly_options; -use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::lint::{builtin, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::NodeMap; use rustc_session::Session; use rustc_span::hygiene::ExpnId; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3d31f240a34e0..072b85d716d74 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -23,9 +23,7 @@ extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; -//use rustc_resolve as resolve; -use rustc::lint; -use rustc::lint::Lint; +use rustc::lint::{Lint, LintId}; use rustc::middle::cstore::MetadataLoader; use rustc::session::config::nightly_options; use rustc::session::config::{ErrorOutputType, Input, OutputType, PrintRequest}; @@ -41,6 +39,7 @@ use rustc_feature::{find_gated_cfg, UnstableFeatures}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::get_builtin_codegen_backend; use rustc_interface::{interface, Queries}; +use rustc_lint::LintStore; use rustc_metadata::locator; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; @@ -811,7 +810,7 @@ the command line flag directly. ); } -fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) { +fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_plugins: bool) { println!( " Available lint options: @@ -832,8 +831,8 @@ Available lint options: } fn sort_lint_groups( - lints: Vec<(&'static str, Vec, bool)>, - ) -> Vec<(&'static str, Vec)> { + lints: Vec<(&'static str, Vec, bool)>, + ) -> Vec<(&'static str, Vec)> { let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect(); lints.sort_by_key(|l| l.0); lints @@ -892,7 +891,7 @@ Available lint options: println!(" {} {}", padded("----"), "---------"); println!(" {} {}", padded("warnings"), "all lints that are set to issue warnings"); - let print_lint_groups = |lints: Vec<(&'static str, Vec)>| { + let print_lint_groups = |lints: Vec<(&'static str, Vec)>| { for (name, to) in lints { let name = name.to_lowercase().replace("_", "-"); let desc = to diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index d00875f6fee88..9cd9eb66cf6c1 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -12,6 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; +use rustc_lint::LintStore; use rustc_parse::new_parser_from_source_str; use rustc_span::edition; use rustc_span::source_map::{FileLoader, FileName, SourceMap}; @@ -36,7 +37,7 @@ pub struct Compiler { pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) crate_name: Option, - pub(crate) register_lints: Option>, + pub(crate) register_lints: Option>, pub(crate) override_queries: Option, &mut ty::query::Providers<'_>)>, } @@ -136,7 +137,7 @@ pub struct Config { /// /// Note that if you find a Some here you probably want to call that function in the new /// function being registered. - pub register_lints: Option>, + pub register_lints: Option>, /// This is a callback from the driver that is called just after we have populated /// the list of queries. diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..67f9819f3314d 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -27,6 +27,7 @@ use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_incremental; +use rustc_lint::LintStore; use rustc_mir as mir; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; @@ -100,7 +101,7 @@ declare_box_region_type!( /// Returns `None` if we're aborting after handling -W help. pub fn configure_and_expand( sess: Lrc, - lint_store: Lrc, + lint_store: Lrc, metadata_loader: Box, krate: ast::Crate, crate_name: &str, @@ -150,10 +151,10 @@ impl BoxedResolver { pub fn register_plugins<'a>( sess: &'a Session, metadata_loader: &'a dyn MetadataLoader, - register_lints: impl Fn(&Session, &mut lint::LintStore), + register_lints: impl Fn(&Session, &mut LintStore), mut krate: ast::Crate, crate_name: &str, -) -> Result<(ast::Crate, Lrc)> { +) -> Result<(ast::Crate, Lrc)> { krate = sess.time("attributes_injection", || { rustc_builtin_macros::cmdline_attrs::inject( krate, @@ -214,7 +215,7 @@ pub fn register_plugins<'a>( fn configure_and_expand_inner<'a>( sess: &'a Session, - lint_store: &'a lint::LintStore, + lint_store: &'a LintStore, mut krate: ast::Crate, crate_name: &str, resolver_arenas: &'a ResolverArenas<'a>, @@ -420,7 +421,7 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir<'res, 'tcx>( sess: &'tcx Session, - lint_store: &lint::LintStore, + lint_store: &LintStore, resolver: &'res mut Resolver<'_>, dep_graph: &'res DepGraph, krate: &'res ast::Crate, @@ -705,7 +706,7 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, - lint_store: Lrc, + lint_store: Lrc, hir_forest: &'tcx map::Forest<'tcx>, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 7de1c36ce4b2e..bd9717d3f3d02 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -4,8 +4,6 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map; -use rustc::lint; -use rustc::lint::LintStore; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::session::Session; use rustc::ty::steal::Steal; @@ -15,6 +13,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_incremental::DepGraphFuture; +use rustc_lint::LintStore; use std::any::Any; use std::cell::{Ref, RefCell, RefMut}; use std::mem; @@ -133,7 +132,7 @@ impl<'tcx> Queries<'tcx> { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); - let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; + let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), &*self.codegen_backend().metadata_loader(), diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 7f053f9de2953..fb11b6771e9ca 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -1,4 +1,4 @@ -use rustc::lint::{LateContext, LateLintPass, LintContext}; +use crate::{LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc_errors::Applicability; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index befeb84e57c9c..15a8332a28492 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -21,8 +21,8 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::hir::map::Map; -use rustc::lint::{self, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -51,7 +51,7 @@ use log::debug; use std::fmt::Write; // hardwired lints from librustc -pub use lint::builtin::*; +pub use rustc_session::lint::builtin::*; declare_lint! { WHILE_TRUE, diff --git a/src/librustc/lint/context.rs b/src/librustc_lint/context.rs similarity index 93% rename from src/librustc/lint/context.rs rename to src/librustc_lint/context.rs index 702d707346bd8..2b514c301f2a3 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc_lint/context.rs @@ -16,17 +16,18 @@ use self::TargetLint::*; -use crate::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; -use crate::lint::passes::{EarlyLintPassObject, LateLintPassObject}; -use crate::lint::LintLevelsBuilder; -use crate::middle::privacy::AccessLevels; -use crate::middle::stability; -use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; -use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; +use crate::levels::LintLevelsBuilder; +use crate::passes::{EarlyLintPassObject, LateLintPassObject}; +use rustc::hir::map::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc::lint::add_elided_lifetime_in_path_suggestion; +use rustc::middle::privacy::AccessLevels; +use rustc::middle::stability; +use rustc::ty::layout::{LayoutError, LayoutOf, TyLayout}; +use rustc::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; use rustc_error_codes::*; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_session::lint::BuiltinLintDiagnostics; @@ -467,48 +468,6 @@ impl LintPassObject for EarlyLintPassObject {} impl LintPassObject for LateLintPassObject {} -pub fn add_elided_lifetime_in_path_suggestion( - sess: &Session, - db: &mut DiagnosticBuilder<'_>, - n: usize, - path_span: Span, - incl_angl_brckt: bool, - insertion_span: Span, - anon_lts: String, -) { - let (replace_span, suggestion) = if incl_angl_brckt { - (insertion_span, anon_lts) - } else { - // When possible, prefer a suggestion that replaces the whole - // `Path` expression with `Path<'_, T>`, rather than inserting `'_, ` - // at a point (which makes for an ugly/confusing label) - if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) { - // But our spans can get out of whack due to macros; if the place we think - // we want to insert `'_` isn't even within the path expression's span, we - // should bail out of making any suggestion rather than panicking on a - // subtract-with-overflow or string-slice-out-out-bounds (!) - // FIXME: can we do better? - if insertion_span.lo().0 < path_span.lo().0 { - return; - } - let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize; - if insertion_index > snippet.len() { - return; - } - let (before, after) = snippet.split_at(insertion_index); - (path_span, format!("{}{}{}", before, anon_lts, after)) - } else { - (insertion_span, anon_lts) - } - }; - db.span_suggestion( - replace_span, - &format!("indicate the anonymous lifetime{}", pluralize!(n)), - suggestion, - Applicability::MachineApplicable, - ); -} - pub trait LintContext: Sized { type PassObject: LintPassObject; diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 9a90171985158..490114b2d4d2a 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -14,10 +14,9 @@ //! upon. As the ast is traversed, this keeps track of the current lint level //! for all lint attributes. -use rustc::lint::{EarlyContext, LintStore}; -use rustc::lint::{EarlyLintPass, EarlyLintPassObject}; -use rustc::lint::{LintContext, LintPass}; -use rustc_session::lint::LintBuffer; +use crate::context::{EarlyContext, LintContext, LintStore}; +use crate::passes::{EarlyLintPass, EarlyLintPassObject}; +use rustc_session::lint::{LintBuffer, LintPass}; use rustc_session::Session; use rustc_span::Span; use syntax::ast; @@ -291,7 +290,7 @@ macro_rules! early_lint_pass_impl { ) } -early_lint_methods!(early_lint_pass_impl, []); +crate::early_lint_methods!(early_lint_pass_impl, []); fn early_lint_crate( sess: &Session, diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 30417bf5a24fc..2f8393bd906c0 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -1,8 +1,7 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. -use crate::lint::{EarlyContext, LateContext, LintContext}; -use crate::lint::{EarlyLintPass, LateLintPass}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index e3ab604d39881..eb5f89c9507d3 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -14,8 +14,8 @@ //! upon. As the ast is traversed, this keeps track of the current lint level //! for all lint attributes. +use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; use rustc::hir::map::Map; -use rustc::lint::{LateContext, LateLintPass, LateLintPassObject, LintStore}; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; use rustc_hir as hir; @@ -347,7 +347,7 @@ macro_rules! late_lint_pass_impl { ) } -late_lint_methods!(late_lint_pass_impl, [], ['tcx]); +crate::late_lint_methods!(late_lint_pass_impl, [], ['tcx]); fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tcx: TyCtxt<'tcx>, diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index 46ea04e5ccfca..bbc3e57f5dd01 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,14 +1,27 @@ -use super::late::unerased_lint_store; +use crate::context::{CheckLintNameResult, LintStore}; +use crate::late::unerased_lint_store; use rustc::hir::map::Map; -use rustc::lint::{LintLevelMap, LintLevelsBuilder, LintStore}; +use rustc::lint::struct_lint_level; +use rustc::lint::{LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_data_structures::fx::FxHashMap; +use rustc_error_codes::*; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; +use rustc_session::lint::{builtin, Level, Lint}; +use rustc_session::Session; +use rustc_span::{sym, MultiSpan, Symbol}; use syntax::ast; +use syntax::attr; +use syntax::print::pprust; +use syntax::sess::feature_err; +use syntax::unwrap_or; -pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; +use std::cmp; fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); @@ -28,6 +41,378 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { tcx.arena.alloc(builder.levels.build_map()) } +pub struct LintLevelsBuilder<'a> { + sess: &'a Session, + sets: LintLevelSets, + id_to_set: FxHashMap, + cur: u32, + warn_about_weird_lints: bool, +} + +pub struct BuilderPush { + prev: u32, + pub changed: bool, +} + +impl<'a> LintLevelsBuilder<'a> { + pub fn new(sess: &'a Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { + let mut builder = LintLevelsBuilder { + sess, + sets: LintLevelSets::new(), + cur: 0, + id_to_set: Default::default(), + warn_about_weird_lints, + }; + builder.process_command_line(sess, store); + assert_eq!(builder.sets.list.len(), 1); + builder + } + + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { + let mut specs = FxHashMap::default(); + self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); + + for &(ref lint_name, level) in &sess.opts.lint_opts { + store.check_lint_name_cmdline(sess, &lint_name, level); + + // If the cap is less than this specified level, e.g., if we've got + // `--cap-lints allow` but we've also got `-D foo` then we ignore + // this specification as the lint cap will set it to allow anyway. + let level = cmp::min(level, self.sets.lint_cap); + + let lint_flag_val = Symbol::intern(lint_name); + let ids = match store.find_lints(&lint_name) { + Ok(ids) => ids, + Err(_) => continue, // errors handled in check_lint_name_cmdline above + }; + for id in ids { + let src = LintSource::CommandLine(lint_flag_val); + specs.insert(id, (level, src)); + } + } + + self.sets.list.push(LintSet::CommandLine { specs }); + } + + /// Pushes a list of AST lint attributes onto this context. + /// + /// This function will return a `BuilderPush` object which should be passed + /// to `pop` when this scope for the attributes provided is exited. + /// + /// This function will perform a number of tasks: + /// + /// * It'll validate all lint-related attributes in `attrs` + /// * It'll mark all lint-related attributes as used + /// * Lint levels will be updated based on the attributes provided + /// * Lint attributes are validated, e.g., a #[forbid] can't be switched to + /// #[allow] + /// + /// Don't forget to call `pop`! + pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { + let mut specs = FxHashMap::default(); + let sess = self.sess; + let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); + for attr in attrs { + let level = match Level::from_symbol(attr.name_or_empty()) { + None => continue, + Some(lvl) => lvl, + }; + + let meta = unwrap_or!(attr.meta(), continue); + attr::mark_used(attr); + + let mut metas = unwrap_or!(meta.meta_item_list(), continue); + + if metas.is_empty() { + // FIXME (#55112): issue unused-attributes lint for `#[level()]` + continue; + } + + // Before processing the lint names, look for a reason (RFC 2383) + // at the end. + let mut reason = None; + let tail_li = &metas[metas.len() - 1]; + if let Some(item) = tail_li.meta_item() { + match item.kind { + ast::MetaItemKind::Word => {} // actual lint names handled later + ast::MetaItemKind::NameValue(ref name_value) => { + if item.path == sym::reason { + // found reason, reslice meta list to exclude it + metas = &metas[0..metas.len() - 1]; + // FIXME (#55112): issue unused-attributes lint if we thereby + // don't have any lint names (`#[level(reason = "foo")]`) + if let ast::LitKind::Str(rationale, _) = name_value.kind { + if !self.sess.features_untracked().lint_reasons { + feature_err( + &self.sess.parse_sess, + sym::lint_reasons, + item.span, + "lint reasons are experimental", + ) + .emit(); + } + reason = Some(rationale); + } else { + bad_attr(name_value.span) + .span_label(name_value.span, "reason must be a string literal") + .emit(); + } + } else { + bad_attr(item.span) + .span_label(item.span, "bad attribute argument") + .emit(); + } + } + ast::MetaItemKind::List(_) => { + bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); + } + } + } + + for li in metas { + let meta_item = match li.meta_item() { + Some(meta_item) if meta_item.is_word() => meta_item, + _ => { + let sp = li.span(); + let mut err = bad_attr(sp); + let mut add_label = true; + if let Some(item) = li.meta_item() { + if let ast::MetaItemKind::NameValue(_) = item.kind { + if item.path == sym::reason { + err.span_label(sp, "reason in lint attribute must come last"); + add_label = false; + } + } + } + if add_label { + err.span_label(sp, "bad attribute argument"); + } + err.emit(); + continue; + } + }; + let tool_name = if meta_item.path.segments.len() > 1 { + let tool_ident = meta_item.path.segments[0].ident; + if !attr::is_known_lint_tool(tool_ident) { + struct_span_err!( + sess, + tool_ident.span, + E0710, + "an unknown tool name found in scoped lint: `{}`", + pprust::path_to_string(&meta_item.path), + ) + .emit(); + continue; + } + + Some(tool_ident.name) + } else { + None + }; + let name = meta_item.path.segments.last().expect("empty lint name").ident.name; + match store.check_lint_name(&name.as_str(), tool_name) { + CheckLintNameResult::Ok(ids) => { + let src = LintSource::Node(name, li.span(), reason); + for id in ids { + specs.insert(*id, (level, src)); + } + } + + CheckLintNameResult::Tool(result) => { + match result { + Ok(ids) => { + let complete_name = &format!("{}::{}", tool_name.unwrap(), name); + let src = LintSource::Node( + Symbol::intern(complete_name), + li.span(), + reason, + ); + for id in ids { + specs.insert(*id, (level, src)); + } + } + Err((Some(ids), new_lint_name)) => { + let lint = builtin::RENAMED_AND_REMOVED_LINTS; + let (lvl, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); + let msg = format!( + "lint name `{}` is deprecated \ + and may not have an effect in the future. \ + Also `cfg_attr(cargo-clippy)` won't be necessary anymore", + name + ); + struct_lint_level( + self.sess, + lint, + lvl, + src, + Some(li.span().into()), + &msg, + ) + .span_suggestion( + li.span(), + "change it to", + new_lint_name.to_string(), + Applicability::MachineApplicable, + ) + .emit(); + + let src = LintSource::Node( + Symbol::intern(&new_lint_name), + li.span(), + reason, + ); + for id in ids { + specs.insert(*id, (level, src)); + } + } + Err((None, _)) => { + // If Tool(Err(None, _)) is returned, then either the lint does not + // exist in the tool or the code was not compiled with the tool and + // therefore the lint was never added to the `LintStore`. To detect + // this is the responsibility of the lint tool. + } + } + } + + _ if !self.warn_about_weird_lints => {} + + CheckLintNameResult::Warning(msg, renamed) => { + let lint = builtin::RENAMED_AND_REMOVED_LINTS; + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); + let mut err = struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); + if let Some(new_name) = renamed { + err.span_suggestion( + li.span(), + "use the new name", + new_name, + Applicability::MachineApplicable, + ); + } + err.emit(); + } + CheckLintNameResult::NoLint(suggestion) => { + let lint = builtin::UNKNOWN_LINTS; + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); + let msg = format!("unknown lint: `{}`", name); + let mut db = struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); + + if let Some(suggestion) = suggestion { + db.span_suggestion( + li.span(), + "did you mean", + suggestion.to_string(), + Applicability::MachineApplicable, + ); + } + + db.emit(); + } + } + } + } + + for (id, &(level, ref src)) in specs.iter() { + if level == Level::Forbid { + continue; + } + let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) { + (Some(Level::Forbid), src) => src, + _ => continue, + }; + let forbidden_lint_name = match forbid_src { + LintSource::Default => id.to_string(), + LintSource::Node(name, _, _) => name.to_string(), + LintSource::CommandLine(name) => name.to_string(), + }; + let (lint_attr_name, lint_attr_span) = match *src { + LintSource::Node(name, span, _) => (name, span), + _ => continue, + }; + let mut diag_builder = struct_span_err!( + self.sess, + lint_attr_span, + E0453, + "{}({}) overruled by outer forbid({})", + level.as_str(), + lint_attr_name, + forbidden_lint_name + ); + diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); + match forbid_src { + LintSource::Default => {} + LintSource::Node(_, forbid_source_span, reason) => { + diag_builder.span_label(forbid_source_span, "`forbid` level set here"); + if let Some(rationale) = reason { + diag_builder.note(&rationale.as_str()); + } + } + LintSource::CommandLine(_) => { + diag_builder.note("`forbid` lint level was set on command line"); + } + } + diag_builder.emit(); + // don't set a separate error for every lint in the group + break; + } + + let prev = self.cur; + if specs.len() > 0 { + self.cur = self.sets.list.len() as u32; + self.sets.list.push(LintSet::Node { specs: specs, parent: prev }); + } + + BuilderPush { prev: prev, changed: prev != self.cur } + } + + /// Called after `push` when the scope of a set of attributes are exited. + pub fn pop(&mut self, push: BuilderPush) { + self.cur = push.prev; + } + + /// Used to emit a lint-related diagnostic based on the current state of + /// this lint context. + pub fn struct_lint( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'a> { + let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); + struct_lint_level(self.sess, lint, level, src, span, msg) + } + + /// Registers the ID provided with the current set of lints stored in + /// this context. + pub fn register_id(&mut self, id: HirId) { + self.id_to_set.insert(id, self.cur); + } + + pub fn build(self) -> LintLevelSets { + self.sets + } + + pub fn build_map(self) -> LintLevelMap { + LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } + } +} + struct LintLevelMapBuilder<'a, 'tcx> { levels: LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e11472e1136f7..93eae1d6c1ae5 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] +#![feature(never_type)] #![feature(nll)] #![recursion_limit = "256"] @@ -25,33 +26,29 @@ extern crate rustc_session; mod array_into_iter; pub mod builtin; +mod context; mod early; mod internal; mod late; mod levels; mod non_ascii_idents; mod nonstandard_style; +mod passes; mod redundant_semicolon; mod types; mod unused; -use rustc::lint; -use rustc::lint::builtin::{ - BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, - INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, -}; -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_session::lint::{LintArray, LintPass}; - +use rustc_session::lint::builtin::{ + BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, + INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, +}; use rustc_span::Span; use syntax::ast; -use lint::LintId; - use array_into_iter::ArrayIntoIter; use builtin::*; use internal::*; @@ -61,10 +58,15 @@ use redundant_semicolon::*; use types::*; use unused::*; -/// Useful for other parts of the compiler. +/// Useful for other parts of the compiler / Clippy. pub use builtin::SoftLints; +pub use context::{EarlyContext, LateContext, LintContext, LintStore}; pub use early::check_ast_crate; pub use late::check_crate; +pub use passes::{EarlyLintPass, LateLintPass}; +pub use rustc_session::lint::Level::{self, *}; +pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId}; +pub use rustc_session::lint::{LintArray, LintPass}; pub fn provide(providers: &mut Providers<'_>) { levels::provide(providers); @@ -181,8 +183,8 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]) late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]); -pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore { - let mut lint_store = lint::LintStore::new(); +pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintStore { + let mut lint_store = LintStore::new(); register_builtins(&mut lint_store, no_interleave_lints); if internal_lints { @@ -195,7 +197,7 @@ pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint:: /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { +fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { ($name:expr, $($lint:ident),*) => ( store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); @@ -392,7 +394,7 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { store.register_removed("plugin_as_library", "plugins have been deprecated and retired"); } -fn register_internals(store: &mut lint::LintStore) { +fn register_internals(store: &mut LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index 522aeb6b14420..3c85a1b31b244 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LintContext}; use syntax::ast; declare_lint! { diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index f75bb9ba32c3d..a2b7884241ff7 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/librustc/lint/passes.rs b/src/librustc_lint/passes.rs similarity index 96% rename from src/librustc/lint/passes.rs rename to src/librustc_lint/passes.rs index 41671ccc6c0fc..cb54105381fb2 100644 --- a/src/librustc/lint/passes.rs +++ b/src/librustc_lint/passes.rs @@ -18,23 +18,15 @@ //! example) requires more effort. See `emit_lint` and `GatherNodeLevels` //! in `context.rs`. -pub use self::Level::*; -pub use crate::lint::LintSource::{self, *}; +use crate::context::{EarlyContext, LateContext}; use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; +use rustc_session::lint::LintPass; use rustc_span::Span; use syntax::ast; -pub use crate::lint::context::{ - add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext, - LintContext, LintStore, -}; - -pub use rustc_session::lint::{builtin, LintArray, LintPass}; -pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; - #[macro_export] macro_rules! late_lint_methods { ($macro:path, $args:tt, [$hir:tt]) => ( @@ -169,6 +161,7 @@ macro_rules! declare_combined_late_lint_pass { expand_combined_late_lint_pass_methods!([$($passes),*], $methods); } + #[allow(rustc::lint_pass_impl_without_macro)] impl LintPass for $name { fn name(&self) -> &'static str { panic!() @@ -296,6 +289,7 @@ macro_rules! declare_combined_early_lint_pass { expand_combined_early_lint_pass_methods!([$($passes),*], $methods); } + #[allow(rustc::lint_pass_impl_without_macro)] impl LintPass for $name { fn name(&self) -> &'static str { panic!() diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index dc18f15fe40cb..21b244ad75d4e 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,4 +1,4 @@ -use rustc::lint::{EarlyContext, EarlyLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LintContext}; use rustc_errors::Applicability; use syntax::ast::{ExprKind, Stmt, StmtKind}; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index ab6841c0c09bc..674a82b61961c 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -use rustc::lint::{LateContext, LateLintPass, LintContext}; +use crate::{LateContext, LateLintPass, LintContext}; use rustc::mir::interpret::{sign_extend, truncate}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index da8a23f041e58..26cbda3d97895 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,5 +1,4 @@ -use rustc::lint::builtin::UNUSED_ATTRIBUTES; -use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty::adjustment; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashMap; @@ -8,6 +7,7 @@ use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_session::lint::builtin::UNUSED_ATTRIBUTES; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml index d0b7accafd68b..41e6c699c340e 100644 --- a/src/librustc_plugin_impl/Cargo.toml +++ b/src/librustc_plugin_impl/Cargo.toml @@ -14,6 +14,7 @@ doctest = false rustc = { path = "../librustc" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } +rustc_lint = { path = "../librustc_lint" } rustc_metadata = { path = "../librustc_metadata" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_plugin_impl/lib.rs b/src/librustc_plugin_impl/lib.rs index 682d223f565de..10712eb60b9e3 100644 --- a/src/librustc_plugin_impl/lib.rs +++ b/src/librustc_plugin_impl/lib.rs @@ -9,7 +9,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(nll)] -use rustc::lint::LintStore; +use rustc_lint::LintStore; pub mod build; pub mod load; From b59235975e43ef5f3ea9436a62f4f07ee5b9a63e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 07:58:48 +0100 Subject: [PATCH 0240/1253] lints: move a comment --- src/librustc_lint/lib.rs | 26 +++++++++++++++++++++----- src/librustc_lint/passes.rs | 20 -------------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 93eae1d6c1ae5..6e3382dee9aae 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -1,9 +1,25 @@ -//! # Lints in the Rust compiler +//! Lints, aka compiler warnings. //! -//! This currently only contains the definitions and implementations -//! of most of the lints that `rustc` supports directly, it does not -//! contain the infrastructure for defining/registering lints. That is -//! available in `rustc::lint` and `rustc_driver::plugin` respectively. +//! A 'lint' check is a kind of miscellaneous constraint that a user _might_ +//! want to enforce, but might reasonably want to permit as well, on a +//! module-by-module basis. They contrast with static constraints enforced by +//! other phases of the compiler, which are generally required to hold in order +//! to compile the program at all. +//! +//! Most lints can be written as `LintPass` instances. These run after +//! all other analyses. The `LintPass`es built into rustc are defined +//! within `rustc_session::lint::builtin`, +//! which has further comments on how to add such a lint. +//! rustc can also load user-defined lint plugins via the plugin mechanism. +//! +//! Some of rustc's lints are defined elsewhere in the compiler and work by +//! calling `add_lint()` on the overall `Session` object. This works when +//! it happens before the main lint pass, which emits the lints stored by +//! `add_lint()`. To emit lints after the main lint pass (from codegen, for +//! example) requires more effort. See `emit_lint` and `GatherNodeLevels` +//! in `context.rs`. +//! +//! Some code also exists in `rustc_session::lint`, `rustc::lint`. //! //! ## Note //! diff --git a/src/librustc_lint/passes.rs b/src/librustc_lint/passes.rs index cb54105381fb2..7e5d670767ad8 100644 --- a/src/librustc_lint/passes.rs +++ b/src/librustc_lint/passes.rs @@ -1,23 +1,3 @@ -//! Lints, aka compiler warnings. -//! -//! A 'lint' check is a kind of miscellaneous constraint that a user _might_ -//! want to enforce, but might reasonably want to permit as well, on a -//! module-by-module basis. They contrast with static constraints enforced by -//! other phases of the compiler, which are generally required to hold in order -//! to compile the program at all. -//! -//! Most lints can be written as `LintPass` instances. These run after -//! all other analyses. The `LintPass`es built into rustc are defined -//! within `builtin.rs`, which has further comments on how to add such a lint. -//! rustc can also load user-defined lint plugins via the plugin mechanism. -//! -//! Some of rustc's lints are defined elsewhere in the compiler and work by -//! calling `add_lint()` on the overall `Session` object. This works when -//! it happens before the main lint pass, which emits the lints stored by -//! `add_lint()`. To emit lints after the main lint pass (from codegen, for -//! example) requires more effort. See `emit_lint` and `GatherNodeLevels` -//! in `context.rs`. - use crate::context::{EarlyContext, LateContext}; use rustc_data_structures::sync; From 8be2a04c7e6bf78a614840dc7152990a451ac4e0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 09:40:55 +0100 Subject: [PATCH 0241/1253] pacify the parallel compiler --- src/librustc/ty/context.rs | 5 +++-- src/librustc_lint/late.rs | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c28631b982577..99e6c62f61326 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -41,6 +41,7 @@ use crate::ty::{ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, Pr use crate::ty::{InferConst, ParamConst}; use crate::ty::{List, TyKind, TyS}; use crate::util::common::ErrorReported; +use rustc_data_structures::sync; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRATE}; @@ -951,7 +952,7 @@ pub struct GlobalCtxt<'tcx> { /// /// FIXME(Centril): consider `dyn LintStoreMarker` once /// we can upcast to `Any` for some additional type safety. - pub lint_store: Lrc, + pub lint_store: Lrc, pub dep_graph: DepGraph, @@ -1120,7 +1121,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, - lint_store: Lrc, + lint_store: Lrc, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index eb5f89c9507d3..30a3788377508 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -28,12 +28,14 @@ use syntax::ast; use syntax::walk_list; use log::debug; +use std::any::Any; use std::slice; /// Extract the `LintStore` from the query context. /// This function exists because we've erased `LintStore` as `dyn Any` in the context. crate fn unerased_lint_store<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx LintStore { - tcx.lint_store.downcast_ref().unwrap() + let store: &dyn Any = &*tcx.lint_store; + store.downcast_ref().unwrap() } macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ From 51078ceb44e4482432a13171ddb9978df27dcfbf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 10 Jan 2020 06:53:07 +0100 Subject: [PATCH 0242/1253] fix ui-fulldeps & tests fallout --- src/librustc_interface/tests.rs | 42 +++++++++---------- .../auxiliary/issue-40001-plugin.rs | 6 +-- .../auxiliary/lint-for-crate-rpass.rs | 6 +-- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 6 +-- .../auxiliary/lint-group-plugin-test.rs | 6 +-- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 6 +-- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 6 +-- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index c2e9c35fcd4a7..ec75a1c6a3938 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -2,7 +2,7 @@ extern crate getopts; use crate::interface::parse_cfgspecs; -use rustc::lint; +use rustc::lint::Level; use rustc::middle::cstore; use rustc::session::config::{build_configuration, build_session_options, to_crate_config}; use rustc::session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes}; @@ -186,24 +186,24 @@ fn test_lints_tracking_hash_different_values() { let mut v3 = Options::default(); v1.lint_opts = vec![ - (String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Deny), - (String::from("d"), lint::Forbid), + (String::from("a"), Level::Allow), + (String::from("b"), Level::Warn), + (String::from("c"), Level::Deny), + (String::from("d"), Level::Forbid), ]; v2.lint_opts = vec![ - (String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("X"), lint::Deny), - (String::from("d"), lint::Forbid), + (String::from("a"), Level::Allow), + (String::from("b"), Level::Warn), + (String::from("X"), Level::Deny), + (String::from("d"), Level::Forbid), ]; v3.lint_opts = vec![ - (String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Forbid), - (String::from("d"), lint::Deny), + (String::from("a"), Level::Allow), + (String::from("b"), Level::Warn), + (String::from("c"), Level::Forbid), + (String::from("d"), Level::Deny), ]; assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); @@ -222,17 +222,17 @@ fn test_lints_tracking_hash_different_construction_order() { let mut v2 = Options::default(); v1.lint_opts = vec![ - (String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Deny), - (String::from("d"), lint::Forbid), + (String::from("a"), Level::Allow), + (String::from("b"), Level::Warn), + (String::from("c"), Level::Deny), + (String::from("d"), Level::Forbid), ]; v2.lint_opts = vec![ - (String::from("a"), lint::Allow), - (String::from("c"), lint::Deny), - (String::from("b"), lint::Warn), - (String::from("d"), lint::Forbid), + (String::from("a"), Level::Allow), + (String::from("c"), Level::Deny), + (String::from("b"), Level::Warn), + (String::from("d"), Level::Forbid), ]; assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash()); diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index abb2e93757ed3..725c350fe4e22 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -1,17 +1,17 @@ #![feature(box_syntax, plugin, plugin_registrar, rustc_private)] #![crate_type = "dylib"] -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; extern crate rustc_hir; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; extern crate rustc_span; extern crate syntax; use rustc_hir::intravisit; use rustc_hir as hir; use rustc_hir::Node; -use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; +use rustc_lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; use rustc_driver::plugin::Registry; use rustc_span::source_map; use syntax::print::pprust; diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 4ccbe8a3c0eb0..98963a180c850 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -2,14 +2,14 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; extern crate rustc_hir; extern crate rustc_span; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass}; +use rustc_lint::{LateContext, LintContext, LintPass, LateLintPass}; use rustc_driver::plugin::Registry; use rustc_span::symbol::Symbol; use syntax::attr; diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 360bffaa46f2b..589477da62527 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -3,14 +3,14 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; extern crate rustc_hir; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; extern crate rustc_span; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray}; +use rustc_lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray}; use rustc_driver::plugin::Registry; use rustc_span::symbol::Symbol; use syntax::attr; diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index 786c699947e47..2cc288c21e697 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -4,12 +4,12 @@ #![feature(box_syntax, rustc_private)] // Load rustc as a plugin to get macros. -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; extern crate rustc_hir; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray, LintId}; +use rustc_lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray, LintId}; use rustc_driver::plugin::Registry; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index bb96dba21fc2e..c704701cc480b 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -6,11 +6,11 @@ extern crate syntax; // Load rustc as a plugin to get macros -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; -use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray}; +use rustc_lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray}; use rustc_driver::plugin::Registry; use syntax::ast; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 1704909813797..fa545ddc2bc6b 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -4,11 +4,11 @@ extern crate syntax; // Load rustc as a plugin to get macros -#[macro_use] extern crate rustc; -#[macro_use] extern crate rustc_session; extern crate rustc_driver; +#[macro_use] extern crate rustc_lint; +#[macro_use] extern crate rustc_session; -use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId}; +use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId}; use rustc_driver::plugin::Registry; use syntax::ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); From 4b19c80819efbbf48a0efe0aba0e6e2fd3cafbc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 00:19:29 +0100 Subject: [PATCH 0243/1253] Don't create strings in the fast path --- src/librustc_typeck/astconv.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c15bcd81443d6..84b63e986d978 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1318,10 +1318,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // those that do. self.one_bound_for_assoc_type( || traits::supertraits(tcx, trait_ref), - &trait_ref.print_only_trait_path().to_string(), + || trait_ref.print_only_trait_path().to_string(), binding.item_name, path_span, - match binding.kind { + || match binding.kind { ConvertedBindingKind::Equality(ty) => Some(ty.to_string()), _ => None, }, @@ -1878,10 +1878,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()), ) }, - ¶m_name.as_str(), + || param_name.to_string(), assoc_name, span, - None, + || None, ) } @@ -1890,10 +1890,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn one_bound_for_assoc_type( &self, all_candidates: impl Fn() -> I, - ty_param_name: &str, + ty_param_name: impl Fn() -> String, assoc_name: ast::Ident, span: Span, - is_equality: Option, + is_equality: impl Fn() -> Option, ) -> Result, ErrorReported> where I: Iterator>, @@ -1906,7 +1906,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { None => { self.complain_about_assoc_type_not_found( all_candidates, - ty_param_name, + &ty_param_name(), assoc_name, span, ); @@ -1919,6 +1919,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(bound2) = matching_candidates.next() { debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2); + let is_equality = is_equality(); let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates); let mut err = if is_equality.is_some() { // More specific Error Index entry. @@ -1928,7 +1929,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { E0222, "ambiguous associated type `{}` in bounds of `{}`", assoc_name, - ty_param_name + ty_param_name() ) } else { struct_span_err!( @@ -1937,7 +1938,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { E0221, "ambiguous associated type `{}` in bounds of `{}`", assoc_name, - ty_param_name + ty_param_name() ) }; err.span_label(span, format!("ambiguous associated type `{}`", assoc_name)); @@ -1975,7 +1976,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "use fully qualified syntax to disambiguate", format!( "<{} as {}>::{}", - ty_param_name, + ty_param_name(), bound.print_only_trait_path(), assoc_name, ), @@ -1985,7 +1986,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.note(&format!( "associated type `{}` could derive from `{}`", - ty_param_name, + ty_param_name(), bound.print_only_trait_path(), )); } @@ -1994,7 +1995,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.help(&format!( "consider introducing a new type parameter `T` and adding `where` constraints:\ \n where\n T: {},\n{}", - ty_param_name, + ty_param_name(), where_bounds.join(",\n"), )); } @@ -2108,10 +2109,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.one_bound_for_assoc_type( || traits::supertraits(tcx, ty::Binder::bind(trait_ref)), - "Self", + || "Self".to_string(), assoc_ident, span, - None, + || None, )? } (&ty::Param(_), Res::SelfTy(Some(param_did), None)) From edee9c3898bdc3e319d90322259e535affd6ae49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 00:44:34 +0100 Subject: [PATCH 0244/1253] Lift using interners instead of in_arena --- src/librustc/ty/context.rs | 39 ++++++++++++++----------- src/librustc_data_structures/sharded.rs | 14 +++++++++ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1b0b5fc4d078d..0c00f06b7b3f5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -53,7 +53,7 @@ use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; use arena::SyncDroplessArena; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; -use rustc_data_structures::sharded::ShardedHashMap; +use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{ hash_stable_hashmap, HashStable, StableHasher, StableVec, }; @@ -1560,11 +1560,11 @@ pub trait Lift<'tcx>: fmt::Debug { } macro_rules! nop_lift { - ($ty:ty => $lifted:ty) => { + ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for $ty { type Lifted = $lifted; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - if tcx.interners.arena.in_arena(*self as *const _) { + if tcx.interners.$set.contains_pointer_to(&Interned(*self)) { Some(unsafe { mem::transmute(*self) }) } else { None @@ -1575,14 +1575,14 @@ macro_rules! nop_lift { } macro_rules! nop_list_lift { - ($ty:ty => $lifted:ty) => { + ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { if self.is_empty() { return Some(List::empty()); } - if tcx.interners.arena.in_arena(*self as *const _) { + if tcx.interners.$set.contains_pointer_to(&Interned(*self)) { Some(unsafe { mem::transmute(*self) }) } else { None @@ -1592,21 +1592,21 @@ macro_rules! nop_list_lift { }; } -nop_lift! {Ty<'a> => Ty<'tcx>} -nop_lift! {Region<'a> => Region<'tcx>} -nop_lift! {Goal<'a> => Goal<'tcx>} -nop_lift! {&'a Const<'a> => &'tcx Const<'tcx>} +nop_lift! {type_; Ty<'a> => Ty<'tcx>} +nop_lift! {region; Region<'a> => Region<'tcx>} +nop_lift! {goal; Goal<'a> => Goal<'tcx>} +nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>} -nop_list_lift! {Goal<'a> => Goal<'tcx>} -nop_list_lift! {Clause<'a> => Clause<'tcx>} -nop_list_lift! {Ty<'a> => Ty<'tcx>} -nop_list_lift! {ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} -nop_list_lift! {Predicate<'a> => Predicate<'tcx>} -nop_list_lift! {CanonicalVarInfo => CanonicalVarInfo} -nop_list_lift! {ProjectionKind => ProjectionKind} +nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>} +nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>} +nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} +nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} +nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} +nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo} +nop_list_lift! {projs; ProjectionKind => ProjectionKind} // This is the impl for `&'a InternalSubsts<'a>`. -nop_list_lift! {GenericArg<'a> => GenericArg<'tcx>} +nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} pub mod tls { use super::{ptr_eq, GlobalCtxt, TyCtxt}; @@ -1930,6 +1930,11 @@ impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> { } impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {} +impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> { + fn into_pointer(&self) -> *const () { + self.0 as *const _ as *const () + } +} // N.B., an `Interned` compares and hashes as a `TyKind`. impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> { fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool { diff --git a/src/librustc_data_structures/sharded.rs b/src/librustc_data_structures/sharded.rs index 8b85d97a1d4fe..ee3f88ff1675f 100644 --- a/src/librustc_data_structures/sharded.rs +++ b/src/librustc_data_structures/sharded.rs @@ -137,6 +137,20 @@ impl ShardedHashMap { } } +pub trait IntoPointer { + /// Returns a pointer which outlives `self`. + fn into_pointer(&self) -> *const (); +} + +impl ShardedHashMap { + pub fn contains_pointer_to(&self, value: &T) -> bool { + let hash = make_hash(&value); + let shard = self.get_shard_by_hash(hash).lock(); + let value = value.into_pointer(); + shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some() + } +} + #[inline] fn make_hash(val: &K) -> u64 { let mut state = FxHasher::default(); From b21c9dddb061faf2d0de0c05aa2c26ad295b470e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 01:26:18 +0100 Subject: [PATCH 0245/1253] Use Arena for interning --- src/librustc/arena.rs | 5 ++++- src/librustc/ty/context.rs | 20 ++++---------------- src/librustc/ty/mod.rs | 10 ++++++---- src/librustc_interface/passes.rs | 4 +--- src/librustc_interface/queries.rs | 5 +---- 5 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index cb3fdff53a3b0..15e92d8d84219 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -123,6 +123,9 @@ macro_rules! arena_types { [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>, [] upvars: rustc_data_structures::fx::FxIndexMap, + // Interned types + [] tys: rustc::ty::TyS<$tcx>, + // HIR types [few] hir_forest: rustc::hir::map::Forest<$tcx>, [] arm: rustc_hir::Arm<$tcx>, @@ -176,7 +179,7 @@ macro_rules! declare_arena { ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { #[derive(Default)] pub struct Arena<$tcx> { - dropless: DroplessArena, + pub dropless: DroplessArena, drop: DropArena, $($name: arena_for_type!($a[$ty]),)* } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0c00f06b7b3f5..908fd9a529401 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -50,7 +50,6 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRA use rustc_hir::{HirId, Node, TraitCandidate}; use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; -use arena::SyncDroplessArena; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -81,21 +80,11 @@ use syntax::ast; use syntax::attr; use syntax::expand::allocator::AllocatorKind; -pub struct AllArenas { - pub interner: SyncDroplessArena, -} - -impl AllArenas { - pub fn new() -> Self { - AllArenas { interner: SyncDroplessArena::default() } - } -} - type InternedSet<'tcx, T> = ShardedHashMap, ()>; pub struct CtxtInterners<'tcx> { /// The arena that types, regions, etc. are allocated from. - arena: &'tcx SyncDroplessArena, + arena: &'tcx WorkerLocal>, /// Specifically use a speedy hash algorithm for these hash sets, since /// they're accessed quite often. @@ -115,7 +104,7 @@ pub struct CtxtInterners<'tcx> { } impl<'tcx> CtxtInterners<'tcx> { - fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> { + fn new(arena: &'tcx WorkerLocal>) -> CtxtInterners<'tcx> { CtxtInterners { arena, type_: Default::default(), @@ -1118,7 +1107,6 @@ impl<'tcx> TyCtxt<'tcx> { lint_store: Lrc, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, - arenas: &'tcx AllArenas, arena: &'tcx WorkerLocal>, resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, @@ -1129,7 +1117,7 @@ impl<'tcx> TyCtxt<'tcx> { let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| { s.fatal(&err); }); - let interners = CtxtInterners::new(&arenas.interner); + let interners = CtxtInterners::new(arena); let common_types = CommonTypes::new(&interners); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -2087,7 +2075,7 @@ macro_rules! slice_interners { $(impl<'tcx> TyCtxt<'tcx> { pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { self.interners.$field.intern_ref(v, || { - Interned(List::from_arena(&self.interners.arena, v)) + Interned(List::from_arena(&*self.arena, v)) }).0 } })+ diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d1e37a4ea1151..78b00f259aa64 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -6,6 +6,7 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::Variance::*; +use crate::arena::Arena; use crate::hir::exports::ExportMap; use crate::hir::map as hir_map; @@ -26,7 +27,6 @@ use crate::ty::layout::VariantIdx; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; use crate::ty::walk::TypeWalker; -use arena::SyncDroplessArena; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; @@ -76,7 +76,7 @@ pub use crate::ty::diagnostics::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; -pub use self::context::{keep_local, tls, AllArenas, FreeRegionInfo, TyCtxt}; +pub use self::context::{keep_local, tls, FreeRegionInfo, TyCtxt}; pub use self::context::{ CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, UserType, UserTypeAnnotationIndex, @@ -606,7 +606,7 @@ unsafe impl Sync for List {} impl List { #[inline] - fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List { + fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); assert!(slice.len() != 0); @@ -619,7 +619,9 @@ impl List { let size = offset + slice.len() * mem::size_of::(); - let mem = arena.alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); + let mem = arena + .dropless + .alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); unsafe { let result = &mut *(mem.as_mut_ptr() as *mut List); // Write the length diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..5567d5bf201a0 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -15,7 +15,7 @@ use rustc::session::search_paths::PathKind; use rustc::session::Session; use rustc::traits; use rustc::ty::steal::Steal; -use rustc::ty::{self, AllArenas, GlobalCtxt, ResolverOutputs, TyCtxt}; +use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_builtin_macros; use rustc_codegen_ssa::back::link::emit_metadata; @@ -711,7 +711,6 @@ pub fn create_global_ctxt<'tcx>( outputs: OutputFilenames, crate_name: &str, global_ctxt: &'tcx Once>, - all_arenas: &'tcx AllArenas, arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); @@ -742,7 +741,6 @@ pub fn create_global_ctxt<'tcx>( lint_store, local_providers, extern_providers, - &all_arenas, arena, resolver_outputs, hir_map, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 7de1c36ce4b2e..f0d0297d11a1e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -9,7 +9,7 @@ use rustc::lint::LintStore; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::session::Session; use rustc::ty::steal::Steal; -use rustc::ty::{AllArenas, GlobalCtxt, ResolverOutputs}; +use rustc::ty::{GlobalCtxt, ResolverOutputs}; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; @@ -67,7 +67,6 @@ pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: Once>, - all_arenas: AllArenas, arena: WorkerLocal>, dep_graph_future: Query>, @@ -87,7 +86,6 @@ impl<'tcx> Queries<'tcx> { Queries { compiler, gcx: Once::new(), - all_arenas: AllArenas::new(), arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), parse: Default::default(), @@ -266,7 +264,6 @@ impl<'tcx> Queries<'tcx> { outputs, &crate_name, &self.gcx, - &self.all_arenas, &self.arena, )) }) From f4968c8e00daed7cc4e5658a7abe61557abd4570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 01:28:59 +0100 Subject: [PATCH 0246/1253] Remove SyncTypedArena, SyncDroplessArena and in_arena --- src/libarena/lib.rs | 73 --------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index beb0bac17d2ea..2a3d92edc4956 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -21,7 +21,6 @@ extern crate alloc; use rustc_data_structures::cold_path; -use rustc_data_structures::sync::MTLock; use smallvec::SmallVec; use std::cell::{Cell, RefCell}; @@ -116,11 +115,6 @@ impl Default for TypedArena { } impl TypedArena { - pub fn in_arena(&self, ptr: *const T) -> bool { - let ptr = ptr as *const T as *mut T; - - self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end()) - } /// Allocates an object in the `TypedArena`, returning a reference to it. #[inline] pub fn alloc(&self, object: T) -> &mut T { @@ -334,12 +328,6 @@ impl Default for DroplessArena { } impl DroplessArena { - pub fn in_arena(&self, ptr: *const T) -> bool { - let ptr = ptr as *const u8 as *mut u8; - - self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end()) - } - #[inline] fn align(&self, align: usize) { let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); @@ -500,66 +488,5 @@ impl DroplessArena { } } -#[derive(Default)] -// FIXME(@Zoxc): this type is entirely unused in rustc -pub struct SyncTypedArena { - lock: MTLock>, -} - -impl SyncTypedArena { - #[inline(always)] - pub fn alloc(&self, object: T) -> &mut T { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) } - } - - #[inline(always)] - pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where - T: Copy, - { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) } - } - - #[inline(always)] - pub fn clear(&mut self) { - self.lock.get_mut().clear(); - } -} - -#[derive(Default)] -pub struct SyncDroplessArena { - lock: MTLock, -} - -impl SyncDroplessArena { - #[inline(always)] - pub fn in_arena(&self, ptr: *const T) -> bool { - self.lock.lock().in_arena(ptr) - } - - #[inline(always)] - pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_raw(bytes, align) as *mut [u8]) } - } - - #[inline(always)] - pub fn alloc(&self, object: T) -> &mut T { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) } - } - - #[inline(always)] - pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where - T: Copy, - { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) } - } -} - #[cfg(test)] mod tests; From 883932c6baf7acd28ab712b80ddeda960f6e37da Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 06:49:43 +0100 Subject: [PATCH 0247/1253] Ban `...X` pats, harden tests, and improve diagnostics. Also fix a bug with the span passed in `mk_range`. --- src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/pat.rs | 26 ++++- src/test/ui/error-codes/E0586.stderr | 6 +- .../feature-gate-half-open-range-patterns.rs | 1 + ...ature-gate-half-open-range-patterns.stderr | 28 +++-- ...nge-pats-inclusive-dotdotdot-bad-syntax.rs | 32 ++++++ ...pats-inclusive-dotdotdot-bad-syntax.stderr | 35 ++++++ .../half-open-range-pats-inclusive-no-end.rs | 11 ++ ...lf-open-range-pats-inclusive-no-end.stderr | 40 +++++-- ...lf-open-range-pats-ref-ambiguous-interp.rs | 2 + ...pen-range-pats-ref-ambiguous-interp.stderr | 22 +++- .../half-open-range-pats-syntactic-pass.rs | 22 ++-- src/test/ui/impossible_range.rs | 6 +- src/test/ui/impossible_range.stderr | 12 +- .../ui/parser/attr-stmt-expr-attr-bad.stderr | 12 +- src/test/ui/parser/range_inclusive.rs | 2 +- src/test/ui/parser/range_inclusive.stderr | 6 +- src/test/ui/parser/recover-range-pats.rs | 10 +- src/test/ui/parser/recover-range-pats.stderr | 106 +++++++++--------- 19 files changed, 260 insertions(+), 121 deletions(-) create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs create mode 100644 src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 2d6a94ce620cf..bdb55a713f1dc 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1966,7 +1966,7 @@ impl<'a> Parser<'a> { limits: RangeLimits, ) -> PResult<'a, ExprKind> { if end.is_none() && limits == RangeLimits::Closed { - self.error_inclusive_range_with_no_end(self.token.span); + self.error_inclusive_range_with_no_end(self.prev_span); Ok(ExprKind::Err) } else { Ok(ExprKind::Range(start, end, limits)) diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 50756ddec9f2d..0c2cfc20daf0f 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -661,14 +661,34 @@ impl<'a> Parser<'a> { pub(super) fn error_inclusive_range_with_no_end(&self, span: Span) { use rustc_error_codes::E0586; struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end") - .help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)") + .span_suggestion_short( + span, + "use `..` instead", + "..".to_string(), + Applicability::MachineApplicable, + ) + .note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)") .emit(); } - /// Parse a range-to pattern, e.g. `..X` and `..=X` where `X` remains to be parsed. - fn parse_pat_range_to(&mut self, re: Spanned) -> PResult<'a, PatKind> { + /// Parse a range-to pattern, `..X` or `..=X` where `X` remains to be parsed. + /// + /// The form `...X` is prohibited to reduce confusion with the potential + /// expression syntax `...expr` for splatting in expressions. + fn parse_pat_range_to(&mut self, mut re: Spanned) -> PResult<'a, PatKind> { let end = self.parse_pat_range_end()?; self.sess.gated_spans.gate(sym::half_open_range_patterns, re.span.to(self.prev_span)); + if let RangeEnd::Included(ref mut syn @ RangeSyntax::DotDotDot) = &mut re.node { + *syn = RangeSyntax::DotDotEq; + self.struct_span_err(re.span, "range-to patterns with `...` are not allowed") + .span_suggestion_short( + re.span, + "use `..=` instead", + "..=".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + } Ok(PatKind::Range(None, Some(end), re)) } diff --git a/src/test/ui/error-codes/E0586.stderr b/src/test/ui/error-codes/E0586.stderr index d1e7e3f47442f..0bbf9a6080349 100644 --- a/src/test/ui/error-codes/E0586.stderr +++ b/src/test/ui/error-codes/E0586.stderr @@ -1,10 +1,10 @@ error[E0586]: inclusive range with no end - --> $DIR/E0586.rs:3:22 + --> $DIR/E0586.rs:3:19 | LL | let x = &tmp[1..=]; - | ^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: aborting due to previous error diff --git a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs index 4cb8230a7b620..1733012b9c54f 100644 --- a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs +++ b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs @@ -8,6 +8,7 @@ fn foo() { //~^ ERROR half-open range patterns are unstable if let ...5 = 0 {} //~^ ERROR half-open range patterns are unstable + //~| ERROR range-to patterns with `...` are not allowed if let ..5 = 0 {} //~^ ERROR half-open range patterns are unstable if let 5.. = 0 {} diff --git a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr index 68ba654de76da..99db339cf74e1 100644 --- a/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr +++ b/src/test/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.stderr @@ -1,18 +1,24 @@ +error: range-to patterns with `...` are not allowed + --> $DIR/feature-gate-half-open-range-patterns.rs:9:12 + | +LL | if let ...5 = 0 {} + | ^^^ help: use `..=` instead + error[E0586]: inclusive range with no end - --> $DIR/feature-gate-half-open-range-patterns.rs:15:13 + --> $DIR/feature-gate-half-open-range-patterns.rs:16:13 | LL | if let 5..= = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/feature-gate-half-open-range-patterns.rs:18:13 + --> $DIR/feature-gate-half-open-range-patterns.rs:19:13 | LL | if let 5... = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0658]: half-open range patterns are unstable --> $DIR/feature-gate-half-open-range-patterns.rs:7:12 @@ -33,7 +39,7 @@ LL | if let ...5 = 0 {} = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable error[E0658]: half-open range patterns are unstable - --> $DIR/feature-gate-half-open-range-patterns.rs:11:12 + --> $DIR/feature-gate-half-open-range-patterns.rs:12:12 | LL | if let ..5 = 0 {} | ^^^ @@ -42,7 +48,7 @@ LL | if let ..5 = 0 {} = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable error[E0658]: half-open range patterns are unstable - --> $DIR/feature-gate-half-open-range-patterns.rs:13:12 + --> $DIR/feature-gate-half-open-range-patterns.rs:14:12 | LL | if let 5.. = 0 {} | ^^^ @@ -51,7 +57,7 @@ LL | if let 5.. = 0 {} = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable error[E0658]: half-open range patterns are unstable - --> $DIR/feature-gate-half-open-range-patterns.rs:15:12 + --> $DIR/feature-gate-half-open-range-patterns.rs:16:12 | LL | if let 5..= = 0 {} | ^^^^ @@ -60,7 +66,7 @@ LL | if let 5..= = 0 {} = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable error[E0658]: half-open range patterns are unstable - --> $DIR/feature-gate-half-open-range-patterns.rs:18:12 + --> $DIR/feature-gate-half-open-range-patterns.rs:19:12 | LL | if let 5... = 0 {} | ^^^^ @@ -68,7 +74,7 @@ LL | if let 5... = 0 {} = note: for more information, see https://github.com/rust-lang/rust/issues/67264 = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0586, E0658. For more information about an error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs new file mode 100644 index 0000000000000..daed775cf7c01 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs @@ -0,0 +1,32 @@ +// Test that `...X` range-to patterns are syntactically invalid. +// +// See https://github.com/rust-lang/rust/pull/67258#issuecomment-565656155 +// for the reason why. To summarize, we might want to introduce `...expr` as +// an expression form for splatting (or "untupling") in an expression context. +// While there is no syntactic ambiguity with `...X` in a pattern context, +// there's a potential confusion factor here, and we would prefer to keep patterns +// and expressions in-sync. As such, we do not allow `...X` in patterns either. + +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match scrutinee { + ...X => {} //~ ERROR range-to patterns with `...` are not allowed + ...0 => {} //~ ERROR range-to patterns with `...` are not allowed + ...'a' => {} //~ ERROR range-to patterns with `...` are not allowed + ...0.0f32 => {} //~ ERROR range-to patterns with `...` are not allowed + } +} + +fn syntax2() { + macro_rules! mac { + ($e:expr) => { + let ...$e; //~ ERROR range-to patterns with `...` are not allowed + } + } + + mac!(0); +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr new file mode 100644 index 0000000000000..ba2e7ea8b5354 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr @@ -0,0 +1,35 @@ +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:17:9 + | +LL | ...X => {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:18:9 + | +LL | ...0 => {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:19:9 + | +LL | ...'a' => {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:20:9 + | +LL | ...0.0f32 => {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:27:17 + | +LL | let ...$e; + | ^^^ help: use `..=` instead +... +LL | mac!(0); + | -------- in this macro invocation + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs index 03166e3675571..9ace0c357b2d4 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs @@ -13,3 +13,14 @@ fn foo() { if let X... = 1 {} //~ ERROR inclusive range with no end if let X..= = 1 {} //~ ERROR inclusive range with no end } + +fn bar() { + macro_rules! mac { + ($e:expr) => { + let $e...; //~ ERROR inclusive range with no end + let $e..=; //~ ERROR inclusive range with no end + } + } + + mac!(0); +} diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr index 2b4d95f684284..2bdb8ea57668a 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr @@ -2,34 +2,56 @@ error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-inclusive-no-end.rs:10:13 | LL | if let 0... = 1 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-inclusive-no-end.rs:11:13 | LL | if let 0..= = 1 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-inclusive-no-end.rs:13:13 | LL | if let X... = 1 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-inclusive-no-end.rs:14:13 | LL | if let X..= = 1 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) -error: aborting due to 4 previous errors +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:20:19 + | +LL | let $e...; + | ^^^ help: use `..` instead +... +LL | mac!(0); + | -------- in this macro invocation + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/half-open-range-pats-inclusive-no-end.rs:21:19 + | +LL | let $e..=; + | ^^^ help: use `..` instead +... +LL | mac!(0); + | -------- in this macro invocation + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs index e9a5361e63d27..f054bbea4e3e7 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs @@ -20,5 +20,7 @@ fn syntax() { &..=0 | _ => {} //~^ ERROR the range pattern here has ambiguous interpretation &...0 | _ => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~| ERROR range-to patterns with `...` are not allowed } } diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr index 5d3aded022224..a5f7c390627ba 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr @@ -8,9 +8,9 @@ error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:11 | LL | &0..= | _ => {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: the range pattern here has ambiguous interpretation --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:10 @@ -22,9 +22,9 @@ error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:13:11 | LL | &0... | _ => {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: the range pattern here has ambiguous interpretation --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:18:10 @@ -38,6 +38,18 @@ error: the range pattern here has ambiguous interpretation LL | &..=0 | _ => {} | ^^^^ help: add parentheses to clarify the precedence: `(..=0)` -error: aborting due to 6 previous errors +error: range-to patterns with `...` are not allowed + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:22:10 + | +LL | &...0 | _ => {} + | ^^^ help: use `..=` instead + +error: the range pattern here has ambiguous interpretation + --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:22:10 + | +LL | &...0 | _ => {} + | ^^^^ help: add parentheses to clarify the precedence: `(..=0)` + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs index a663acd2d191c..8bb98d3b5c56f 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs @@ -11,22 +11,20 @@ fn main() {} fn syntax() { match scrutinee { X.. | 0.. | 'a'.. | 0.0f32.. => {} - ..=X | ...X | ..X => {} - ..=0 | ...0 | ..0 => {} - ..='a' | ...'a' | ..'a' => {} - ..=0.0f32 | ...0.0f32 | ..0.0f32 => {} + ..=X | ..X => {} + ..=0 | ..0 => {} + ..='a' | ..'a' => {} + ..=0.0f32 | ..0.0f32 => {} } +} +fn syntax2() { macro_rules! mac { ($e:expr) => { - let ..$e; - let ...$e; - let ..=$e; - let $e..; - let $e...; - let $e..=; + match 0u8 { ..$e => {}, _ => {} } + match 0u8 { ..=$e => {}, _ => {} } + match 0u8 { $e.. => {}, _ => {} } } } - - mac!(0); + mac!(42u8); } diff --git a/src/test/ui/impossible_range.rs b/src/test/ui/impossible_range.rs index 6345af001112f..21e5c03eb1605 100644 --- a/src/test/ui/impossible_range.rs +++ b/src/test/ui/impossible_range.rs @@ -1,4 +1,4 @@ -// Make sure that invalid ranges generate an error during HIR lowering, not an ICE +// Make sure that invalid ranges generate an error during parsing, not an ICE pub fn main() { ..; @@ -6,12 +6,12 @@ pub fn main() { ..1; 0..1; ..=; //~ERROR inclusive range with no end - //~^HELP bounded at the end + //~^HELP use `..` instead } fn _foo1() { ..=1; 0..=1; 0..=; //~ERROR inclusive range with no end - //~^HELP bounded at the end + //~^HELP use `..` instead } diff --git a/src/test/ui/impossible_range.stderr b/src/test/ui/impossible_range.stderr index 091fe37c7a1f7..ea2ab0f299d1b 100644 --- a/src/test/ui/impossible_range.stderr +++ b/src/test/ui/impossible_range.stderr @@ -1,18 +1,18 @@ error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:8:8 + --> $DIR/impossible_range.rs:8:5 | LL | ..=; - | ^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:15:9 + --> $DIR/impossible_range.rs:15:6 | LL | 0..=; - | ^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index 654b49ab62022..4775b9b7bc003 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -342,9 +342,9 @@ error[E0586]: inclusive range with no end --> $DIR/attr-stmt-expr-attr-bad.rs:94:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:94:38 @@ -356,9 +356,9 @@ error[E0586]: inclusive range with no end --> $DIR/attr-stmt-expr-attr-bad.rs:97:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:97:38 @@ -376,9 +376,9 @@ error[E0586]: inclusive range with no end --> $DIR/attr-stmt-expr-attr-bad.rs:102:35 | LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: expected one of `=>`, `if`, or `|`, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:102:38 diff --git a/src/test/ui/parser/range_inclusive.rs b/src/test/ui/parser/range_inclusive.rs index bc61c5b49ea87..7c3b906b47f9f 100644 --- a/src/test/ui/parser/range_inclusive.rs +++ b/src/test/ui/parser/range_inclusive.rs @@ -2,5 +2,5 @@ pub fn main() { for _ in 1..= {} //~ERROR inclusive range with no end - //~^HELP bounded at the end + //~^HELP use `..` instead } diff --git a/src/test/ui/parser/range_inclusive.stderr b/src/test/ui/parser/range_inclusive.stderr index 12b7edae79f52..1dd4799459681 100644 --- a/src/test/ui/parser/range_inclusive.stderr +++ b/src/test/ui/parser/range_inclusive.stderr @@ -1,10 +1,10 @@ error[E0586]: inclusive range with no end - --> $DIR/range_inclusive.rs:4:19 + --> $DIR/range_inclusive.rs:4:15 | LL | for _ in 1..= {} - | ^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: aborting due to previous error diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs index a5aae2861b282..e07ea6221d7c9 100644 --- a/src/test/ui/parser/recover-range-pats.rs +++ b/src/test/ui/parser/recover-range-pats.rs @@ -107,15 +107,15 @@ fn inclusive_to() { fn inclusive2_to() { if let ...3 = 0 {} - //~^ ERROR `...` range patterns are deprecated + //~^ ERROR range-to patterns with `...` are not allowed if let ...Y = 0 {} - //~^ ERROR `...` range patterns are deprecated + //~^ ERROR range-to patterns with `...` are not allowed if let ...true = 0 {} - //~^ ERROR `...` range patterns are deprecated + //~^ ERROR range-to patterns with `...` are not allowed //~| ERROR only char and numeric types if let ....3 = 0 {} //~^ ERROR float literals must have an integer part - //~| ERROR `...` range patterns are deprecated + //~| ERROR range-to patterns with `...` are not allowed //~| ERROR mismatched types } @@ -135,7 +135,7 @@ fn with_macro_expr_var() { ($e:expr) => { let ..$e; let ...$e; - //~^ ERROR `...` range patterns are deprecated + //~^ ERROR range-to patterns with `...` are not allowed let ..=$e; let $e..; let $e...; //~ ERROR inclusive range with no end diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index d3d3169022a65..f43f9bf301218 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -44,25 +44,25 @@ error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:69:13 | LL | if let 0..= = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:70:13 | LL | if let X..= = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:71:16 | LL | if let true..= = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part --> $DIR/recover-range-pats.rs:73:12 @@ -74,33 +74,33 @@ error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:73:14 | LL | if let .0..= = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:79:13 | LL | if let 0... = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:80:13 | LL | if let X... = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:81:16 | LL | if let true... = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part --> $DIR/recover-range-pats.rs:83:12 @@ -112,9 +112,9 @@ error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:83:14 | LL | if let .0... = 0 {} - | ^^^ + | ^^^ help: use `..` instead | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part --> $DIR/recover-range-pats.rs:93:15 @@ -128,33 +128,66 @@ error: float literals must have an integer part LL | if let ..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:109:12 + | +LL | if let ...3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:111:12 + | +LL | if let ...Y = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:113:12 + | +LL | if let ...true = 0 {} + | ^^^ help: use `..=` instead + error: float literals must have an integer part --> $DIR/recover-range-pats.rs:116:15 | LL | if let ....3 = 0 {} | ^^ help: must have an integer part: `0.3` +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ....3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:137:17 + | +LL | let ...$e; + | ^^^ help: use `..=` instead +... +LL | mac!(0); + | -------- in this macro invocation + error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:141:19 | LL | let $e...; - | ^^^ + | ^^^ help: use `..` instead ... LL | mac!(0); | -------- in this macro invocation | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:142:19 | LL | let $e..=; - | ^^^ + | ^^^ help: use `..` instead ... LL | mac!(0); | -------- in this macro invocation | - = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: `...` range patterns are deprecated --> $DIR/recover-range-pats.rs:42:13 @@ -210,30 +243,6 @@ error: `...` range patterns are deprecated LL | if let X... .0 = 0 {} | ^^^ help: use `..=` for an inclusive range -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:109:12 - | -LL | if let ...3 = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:111:12 - | -LL | if let ...Y = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:113:12 - | -LL | if let ...true = 0 {} - | ^^^ help: use `..=` for an inclusive range - -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:116:12 - | -LL | if let ....3 = 0 {} - | ^^^ help: use `..=` for an inclusive range - error: `...` range patterns are deprecated --> $DIR/recover-range-pats.rs:126:20 | @@ -243,15 +252,6 @@ LL | let $e1...$e2; LL | mac2!(0, 1); | ------------ in this macro invocation -error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:137:17 - | -LL | let ...$e; - | ^^^ help: use `..=` for an inclusive range -... -LL | mac!(0); - | -------- in this macro invocation - error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:20:12 | From 8e35c4f74ccc8e5cd537f50dd02ffb25edfd5ba6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 8 Jan 2020 20:27:06 +0300 Subject: [PATCH 0248/1253] feature_gate: Remove `GateStrength` --- src/librustc_ast_passes/feature_gate.rs | 47 ++++++------------------- src/librustc_session/parse.rs | 38 +------------------- 2 files changed, 11 insertions(+), 74 deletions(-) diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 1e396d6fe8e47..e6f4535a38dba 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -8,37 +8,25 @@ use rustc_span::Span; use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; use syntax::attr; -use syntax::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess}; +use syntax::sess::{feature_err, feature_err_issue, ParseSess}; use syntax::visit::{self, FnKind, Visitor}; use log::debug; macro_rules! gate_feature_fn { - ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{ - let (cx, has_feature, span, name, explain, level) = - (&*$cx, $has_feature, $span, $name, $explain, $level); + ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ + let (cx, has_feature, span, name, explain) = (&*$cx, $has_feature, $span, $name, $explain); let has_feature: bool = has_feature(&$cx.features); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); if !has_feature && !span.allows_unstable($name) { - leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level) - .emit(); + feature_err_issue(cx.parse_sess, name, span, GateIssue::Language, explain).emit(); } }}; } -macro_rules! gate_feature { +macro_rules! gate_feature_post { ($cx: expr, $feature: ident, $span: expr, $explain: expr) => { - gate_feature_fn!( - $cx, - |x: &Features| x.$feature, - $span, - sym::$feature, - $explain, - GateStrength::Hard - ) - }; - ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => { - gate_feature_fn!($cx, |x: &Features| x.$feature, $span, sym::$feature, $explain, $level) + gate_feature_fn!($cx, |x: &Features| x.$feature, $span, sym::$feature, $explain) }; } @@ -51,21 +39,6 @@ struct PostExpansionVisitor<'a> { features: &'a Features, } -macro_rules! gate_feature_post { - ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{ - let (cx, span) = ($cx, $span); - if !span.allows_unstable(sym::$feature) { - gate_feature!(cx, $feature, span, $explain) - } - }}; - ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{ - let (cx, span) = ($cx, $span); - if !span.allows_unstable(sym::$feature) { - gate_feature!(cx, $feature, span, $explain, $level) - } - }}; -} - impl<'a> PostExpansionVisitor<'a> { fn check_abi(&self, abi: ast::StrLit) { let ast::StrLit { symbol_unescaped, span, .. } = abi; @@ -257,7 +230,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); // Check feature gates for built-in attributes. if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { - gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard); + gate_feature_fn!(self, has_feature, attr.span, name, descr); } // Check unstable flavors of the `#[doc]` attribute. if attr.check_name(sym::doc) { @@ -265,7 +238,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => { $(if nested_meta.check_name(sym::$name) { let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental"); - gate_feature!(self, $feature, attr.span, msg); + gate_feature_post!(self, $feature, attr.span, msg); })* }} @@ -666,7 +639,7 @@ pub fn check_crate( macro_rules! gate_all { ($gate:ident, $msg:literal) => { for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { - gate_feature!(&visitor, $gate, *span, $msg); + gate_feature_post!(&visitor, $gate, *span, $msg); } }; } @@ -688,7 +661,7 @@ pub fn check_crate( // disabling these uses of early feature-gatings. if false { for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { - gate_feature!(&visitor, $gate, *span, $msg); + gate_feature_post!(&visitor, $gate, *span, $msg); } } }; diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 946e77d35595e..a98cf929095ea 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -62,16 +62,6 @@ impl GatedSpans { } } -/// The strenght of a feature gate. -/// Either it is a `Hard` error, or only a `Soft` warning. -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum GateStrength { - /// A hard error. (Most feature gates should use this.) - Hard, - /// Only a warning. (Use this only as backwards-compatibility demands.) - Soft, -} - /// Construct a diagnostic for a language feature error due to the given `span`. /// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`. pub fn feature_err<'a>( @@ -94,26 +84,7 @@ pub fn feature_err_issue<'a>( issue: GateIssue, explain: &str, ) -> DiagnosticBuilder<'a> { - leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) -} - -/// Construct a diagnostic for a feature gate error / warning. -/// -/// You should typically just use `feature_err` instead. -pub fn leveled_feature_err<'a>( - sess: &'a ParseSess, - feature: Symbol, - span: impl Into, - issue: GateIssue, - explain: &str, - level: GateStrength, -) -> DiagnosticBuilder<'a> { - let diag = &sess.span_diagnostic; - - let mut err = match level { - GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)), - GateStrength::Soft => diag.struct_span_warn(span, explain), - }; + let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658)); if let Some(n) = find_feature_issue(feature, issue) { err.note(&format!( @@ -127,13 +98,6 @@ pub fn leveled_feature_err<'a>( err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); } - // If we're on stable and only emitting a "soft" warning, add a note to - // clarify that the feature isn't "on" (rather than being on but - // warning-worthy). - if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft { - err.help("a nightly build of the compiler is required to enable this feature"); - } - err } From 10720b418ecc72709adddba1b26e2cb293558e1b Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 26 Dec 2019 10:46:32 -0500 Subject: [PATCH 0249/1253] Fix a memory leak in emcc if a Rust panic is caught by C++ and discarded --- src/libpanic_unwind/emcc.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 9d3fe5254f8a9..61f33fd4d5d66 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -52,22 +52,32 @@ pub fn payload() -> *mut u8 { ptr::null_mut() } +struct Exception { + data: Option>, +} + pub unsafe fn cleanup(ptr: *mut u8) -> Box { assert!(!ptr.is_null()); - let adjusted_ptr = __cxa_begin_catch(ptr as *mut libc::c_void); - let ex = ptr::read(adjusted_ptr as *mut _); + let adjusted_ptr = __cxa_begin_catch(ptr as *mut libc::c_void) as *mut Exception; + let ex = (*adjusted_ptr).data.take(); __cxa_end_catch(); - ex + ex.unwrap() } pub unsafe fn panic(data: Box) -> u32 { let sz = mem::size_of_val(&data); - let exception = __cxa_allocate_exception(sz); + let exception = __cxa_allocate_exception(sz) as *mut Exception; if exception.is_null() { return uw::_URC_FATAL_PHASE1_ERROR as u32; } - ptr::write(exception as *mut _, data); - __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, ptr::null_mut()); + ptr::write(exception, Exception { data: Some(data) }); + __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup); + + extern "C" fn exception_cleanup(ptr: *mut libc::c_void) { + unsafe { + ptr::drop_in_place(ptr as *mut Exception); + } + } } #[lang = "eh_personality"] @@ -89,7 +99,7 @@ extern "C" { fn __cxa_throw( thrown_exception: *mut libc::c_void, tinfo: *const TypeInfo, - dest: *mut libc::c_void, + dest: extern "C" fn(*mut libc::c_void), ) -> !; fn __gxx_personality_v0( version: c_int, From 46f52260d89517bcb1c49b189dfb54645776e8c3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 26 Dec 2019 10:26:53 +0100 Subject: [PATCH 0250/1253] Simplify exception cleanup for libunwind-style unwinding --- src/libpanic_unwind/gcc.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 6a48fa05f8d08..6bec2686533eb 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -57,7 +57,7 @@ use unwind as uw; #[repr(C)] struct Exception { _uwe: uw::_Unwind_Exception, - cause: Option>, + cause: Box, } pub unsafe fn panic(data: Box) -> u32 { @@ -67,7 +67,7 @@ pub unsafe fn panic(data: Box) -> u32 { exception_cleanup, private: [0; uw::unwinder_private_data_size], }, - cause: Some(data), + cause: data, }); let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception; return uw::_Unwind_RaiseException(exception_param) as u32; @@ -87,10 +87,8 @@ pub fn payload() -> *mut u8 { } pub unsafe fn cleanup(ptr: *mut u8) -> Box { - let my_ep = ptr as *mut Exception; - let cause = (*my_ep).cause.take(); - uw::_Unwind_DeleteException(ptr as *mut _); - cause.unwrap() + let exception = Box::from_raw(ptr as *mut Exception); + exception.cause } // Rust's exception class identifier. This is used by personality routines to From c15ad84519193c3b7fd5c364cd46598303df92e5 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 29 Dec 2019 21:16:20 +0100 Subject: [PATCH 0251/1253] Fix a memory leak in SEH unwinding if a Rust panic is caught by C++ and discarded --- src/libpanic_unwind/lib.rs | 1 + src/libpanic_unwind/seh.rs | 61 +++++++++++++++++++++++--- src/librustc_codegen_llvm/intrinsic.rs | 23 +++++++--- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index e721162edc067..9451eefb9a5cc 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -26,6 +26,7 @@ #![feature(staged_api)] #![feature(std_internals)] #![feature(unwind_attributes)] +#![feature(abi_thiscall)] #![panic_runtime] #![feature(panic_runtime)] diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index e1907ec4e5f32..417de8e23cc9b 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -77,8 +77,11 @@ use libc::{c_int, c_uint, c_void}; // #include // // struct rust_panic { +// rust_panic(const rust_panic&); +// ~rust_panic(); +// // uint64_t x[2]; -// } +// }; // // void foo() { // rust_panic a = {0, 1}; @@ -128,7 +131,7 @@ mod imp { #[repr(C)] pub struct _ThrowInfo { pub attributes: c_uint, - pub pnfnUnwind: imp::ptr_t, + pub pmfnUnwind: imp::ptr_t, pub pForwardCompat: imp::ptr_t, pub pCatchableTypeArray: imp::ptr_t, } @@ -145,7 +148,7 @@ pub struct _CatchableType { pub pType: imp::ptr_t, pub thisDisplacement: _PMD, pub sizeOrOffset: c_int, - pub copy_function: imp::ptr_t, + pub copyFunction: imp::ptr_t, } #[repr(C)] @@ -168,7 +171,7 @@ const TYPE_NAME: [u8; 11] = *b"rust_panic\0"; static mut THROW_INFO: _ThrowInfo = _ThrowInfo { attributes: 0, - pnfnUnwind: ptr!(0), + pmfnUnwind: ptr!(0), pForwardCompat: ptr!(0), pCatchableTypeArray: ptr!(0), }; @@ -181,7 +184,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType { pType: ptr!(0), thisDisplacement: _PMD { mdisp: 0, pdisp: -1, vdisp: 0 }, sizeOrOffset: mem::size_of::<[u64; 2]>() as c_int, - copy_function: ptr!(0), + copyFunction: ptr!(0), }; extern "C" { @@ -208,6 +211,39 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { name: TYPE_NAME, }; +// Destructor used if the C++ code decides to capture the exception and drop it +// without propagating it. The catch part of the try intrinsic will set the +// first word of the exception object to 0 so that it is skipped by the +// destructor. +// +// Note that x86 Windows uses the "thiscall" calling convention for C++ member +// functions instead of the default "C" calling convention. +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86")] { + unsafe extern "thiscall" fn exception_cleanup(e: *mut [u64; 2]) { + if (*e)[0] != 0 { + cleanup(*e); + } + } + unsafe extern "thiscall" fn exception_copy(_dest: *mut [u64; 2], + _src: *mut [u64; 2]) + -> *mut [u64; 2] { + panic!("Rust panics cannot be copied"); + } + } else { + unsafe extern "C" fn exception_cleanup(e: *mut [u64; 2]) { + if (*e)[0] != 0 { + cleanup(*e); + } + } + unsafe extern "C" fn exception_copy(_dest: *mut [u64; 2], + _src: *mut [u64; 2]) + -> *mut [u64; 2] { + panic!("Rust panics cannot be copied"); + } + } +} + pub unsafe fn panic(data: Box) -> u32 { use core::intrinsics::atomic_store; @@ -220,8 +256,7 @@ pub unsafe fn panic(data: Box) -> u32 { // exception (constructed above). let ptrs = mem::transmute::<_, raw::TraitObject>(data); let mut ptrs = [ptrs.data as u64, ptrs.vtable as u64]; - let ptrs_ptr = ptrs.as_mut_ptr(); - let throw_ptr = ptrs_ptr as *mut _; + let throw_ptr = ptrs.as_mut_ptr() as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the // pointers between these structure are just that, pointers. On 64-bit MSVC, @@ -243,6 +278,12 @@ pub unsafe fn panic(data: Box) -> u32 { // // In any case, we basically need to do something like this until we can // express more operations in statics (and we may never be able to). + if !cfg!(bootstrap) { + atomic_store( + &mut THROW_INFO.pmfnUnwind as *mut _ as *mut u32, + ptr!(exception_cleanup) as u32, + ); + } atomic_store( &mut THROW_INFO.pCatchableTypeArray as *mut _ as *mut u32, ptr!(&CATCHABLE_TYPE_ARRAY as *const _) as u32, @@ -255,6 +296,12 @@ pub unsafe fn panic(data: Box) -> u32 { &mut CATCHABLE_TYPE.pType as *mut _ as *mut u32, ptr!(&TYPE_DESCRIPTOR as *const _) as u32, ); + if !cfg!(bootstrap) { + atomic_store( + &mut CATCHABLE_TYPE.copyFunction as *mut _ as *mut u32, + ptr!(exception_copy) as u32, + ); + } extern "system" { #[unwind(allowed)] diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 8ea50a972ece6..5adff0d1f9233 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -922,6 +922,9 @@ fn codegen_msvc_try( // #include // // struct rust_panic { + // rust_panic(const rust_panic&); + // ~rust_panic(); + // // uint64_t x[2]; // } // @@ -929,17 +932,19 @@ fn codegen_msvc_try( // try { // foo(); // return 0; - // } catch(rust_panic a) { + // } catch(rust_panic& a) { // ret[0] = a.x[0]; // ret[1] = a.x[1]; + // a.x[0] = 0; // return 1; // } // } // // More information can be found in libstd's seh.rs implementation. let i64_2 = bx.type_array(bx.type_i64(), 2); - let i64_align = bx.tcx().data_layout.i64_align.abi; - let slot = bx.alloca(i64_2, i64_align); + let i64_2_ptr = bx.type_ptr_to(i64_2); + let ptr_align = bx.tcx().data_layout.pointer_align.abi; + let slot = bx.alloca(i64_2_ptr, ptr_align); bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None); normal.ret(bx.const_i32(0)); @@ -951,11 +956,19 @@ fn codegen_msvc_try( Some(did) => bx.get_static(did), None => bug!("eh_catch_typeinfo not defined, but needed for SEH unwinding"), }; - let funclet = catchpad.catch_pad(cs, &[tydesc, bx.const_i32(0), slot]); + let flags = bx.const_i32(8); // Catch by reference + let funclet = catchpad.catch_pad(cs, &[tydesc, flags, slot]); - let payload = catchpad.load(slot, i64_align); + let i64_align = bx.tcx().data_layout.i64_align.abi; + let payload_ptr = catchpad.load(slot, ptr_align); + let payload = catchpad.load(payload_ptr, i64_align); let local_ptr = catchpad.bitcast(local_ptr, bx.type_ptr_to(i64_2)); catchpad.store(payload, local_ptr, i64_align); + + // Clear the first word of the exception so avoid double-dropping it. + let payload_0_ptr = catchpad.inbounds_gep(payload_ptr, &[bx.const_i32(0), bx.const_i32(0)]); + catchpad.store(bx.const_u64(0), payload_0_ptr, i64_align); + catchpad.catch_ret(&funclet, caught.llbb()); caught.ret(bx.const_i32(1)); From 43611921120e2df3383f99b42bf060a6be28f23e Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 29 Dec 2019 23:23:40 +0100 Subject: [PATCH 0252/1253] Add a test to check that swallowed Rust panics are dropped properly. --- .../foreign-exceptions/foo.cpp | 17 +++++++++++ .../foreign-exceptions/foo.rs | 30 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp index b0fd65f88e7de..ef5cd74c65283 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp @@ -57,4 +57,21 @@ extern "C" { throw; } } + + void swallow_exception(void (*cb)()) { + try { + // Do a rethrow to ensure that the exception is only dropped once. + // This is necessary since we don't support copying exceptions. + try { + cb(); + } catch (...) { + println("rethrowing Rust panic"); + throw; + }; + } catch (rust_panic e) { + assert(false && "shouldn't be able to catch a rust panic"); + } catch (...) { + println("swallowing foreign exception in catch (...)"); + } + } } diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs index 399c78f8d2d02..d9818dffc502b 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs @@ -4,7 +4,6 @@ // For linking libstdc++ on MinGW #![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))] - #![feature(unwind_attributes)] use std::panic::{catch_unwind, AssertUnwindSafe}; @@ -20,6 +19,8 @@ impl<'a> Drop for DropCheck<'a> { extern "C" { fn throw_cxx_exception(); + fn swallow_exception(cb: extern "C" fn()); + #[unwind(allowed)] fn cxx_catch_callback(cb: extern "C" fn(), ok: *mut bool); } @@ -60,7 +61,34 @@ fn throw_rust_panic() { assert!(cxx_ok); } +fn check_exception_drop() { + static mut DROP_COUNT: usize = 0; + + struct CountDrop; + impl Drop for CountDrop { + fn drop(&mut self) { + println!("CountDrop::drop"); + unsafe { + DROP_COUNT += 1; + } + } + } + + + #[unwind(allowed)] + extern "C" fn callback() { + println!("throwing rust panic #2"); + panic!(CountDrop); + } + + unsafe { + swallow_exception(callback); + assert_eq!(DROP_COUNT, 1); + } +} + fn main() { unsafe { throw_cxx_exception() }; throw_rust_panic(); + check_exception_drop(); } From 838e3874fc11f24ebe8a7dff02a7f7614a5d2938 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 1 Jan 2020 22:14:37 +0100 Subject: [PATCH 0253/1253] Explain the panic! in exception_copy --- src/libpanic_unwind/seh.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index 417de8e23cc9b..ef27e38c2d1d6 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -218,6 +218,12 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // // Note that x86 Windows uses the "thiscall" calling convention for C++ member // functions instead of the default "C" calling convention. +// +// The exception_copy function is a bit special here: it is invoked by the MSVC +// runtime under a try/catch block and the panic that we generate here will be +// used as the result of the exception copy. This is used by the C++ runtime to +// support capturing exceptions with std::exception_ptr, which we can't support +// because Box isn't clonable. cfg_if::cfg_if! { if #[cfg(target_arch = "x86")] { unsafe extern "thiscall" fn exception_cleanup(e: *mut [u64; 2]) { @@ -225,6 +231,7 @@ cfg_if::cfg_if! { cleanup(*e); } } + #[unwind(allowed)] unsafe extern "thiscall" fn exception_copy(_dest: *mut [u64; 2], _src: *mut [u64; 2]) -> *mut [u64; 2] { @@ -236,6 +243,7 @@ cfg_if::cfg_if! { cleanup(*e); } } + #[unwind(allowed)] unsafe extern "C" fn exception_copy(_dest: *mut [u64; 2], _src: *mut [u64; 2]) -> *mut [u64; 2] { From ed217a53ff959414e9c723d8fecf80bc797a5a77 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 1 Jan 2020 22:24:39 +0100 Subject: [PATCH 0254/1253] Explain flag value of 8 for msvc_try --- src/librustc_codegen_llvm/intrinsic.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 5adff0d1f9233..27308cabd45e6 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -952,11 +952,15 @@ fn codegen_msvc_try( let cs = catchswitch.catch_switch(None, None, 1); catchswitch.add_handler(cs, catchpad.llbb()); + // The flag value of 8 indicates that we are catching the exception by + // reference instead of by value. + // + // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang + let flags = bx.const_i32(8); let tydesc = match bx.tcx().lang_items().eh_catch_typeinfo() { Some(did) => bx.get_static(did), None => bug!("eh_catch_typeinfo not defined, but needed for SEH unwinding"), }; - let flags = bx.const_i32(8); // Catch by reference let funclet = catchpad.catch_pad(cs, &[tydesc, flags, slot]); let i64_align = bx.tcx().data_layout.i64_align.abi; From 757ed07f374edfe93be5c9084ac5c44ba738e1b2 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 7 Jan 2020 11:36:57 +0100 Subject: [PATCH 0255/1253] Apply review feedback --- src/libpanic_unwind/emcc.rs | 4 ++++ src/libpanic_unwind/seh.rs | 31 +++++++++++--------------- src/librustc_codegen_llvm/intrinsic.rs | 6 ++++- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 61f33fd4d5d66..fbadf4ac6a058 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -53,6 +53,10 @@ pub fn payload() -> *mut u8 { } struct Exception { + // This needs to be an Option because the object's lifetime follows C++ + // semantics: when catch_unwind moves the Box out of the exception it must + // still leave the exception object in a valid state because its destructor + // is still going to be called by __cxa_end_catch.. data: Option>, } diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index ef27e38c2d1d6..f1d0080472a01 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -224,33 +224,28 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // used as the result of the exception copy. This is used by the C++ runtime to // support capturing exceptions with std::exception_ptr, which we can't support // because Box isn't clonable. -cfg_if::cfg_if! { - if #[cfg(target_arch = "x86")] { - unsafe extern "thiscall" fn exception_cleanup(e: *mut [u64; 2]) { - if (*e)[0] != 0 { - cleanup(*e); - } - } - #[unwind(allowed)] - unsafe extern "thiscall" fn exception_copy(_dest: *mut [u64; 2], - _src: *mut [u64; 2]) - -> *mut [u64; 2] { - panic!("Rust panics cannot be copied"); - } - } else { - unsafe extern "C" fn exception_cleanup(e: *mut [u64; 2]) { +macro_rules! define_cleanup { + ($abi:tt) => { + unsafe extern $abi fn exception_cleanup(e: *mut [u64; 2]) { if (*e)[0] != 0 { cleanup(*e); } } #[unwind(allowed)] - unsafe extern "C" fn exception_copy(_dest: *mut [u64; 2], - _src: *mut [u64; 2]) - -> *mut [u64; 2] { + unsafe extern $abi fn exception_copy(_dest: *mut [u64; 2], + _src: *mut [u64; 2]) + -> *mut [u64; 2] { panic!("Rust panics cannot be copied"); } } } +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86")] { + define_cleanup!("thiscall"); + } else { + define_cleanup!("C"); + } +} pub unsafe fn panic(data: Box) -> u32 { use core::intrinsics::atomic_store; diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 27308cabd45e6..031837c1efbe8 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -953,7 +953,9 @@ fn codegen_msvc_try( catchswitch.add_handler(cs, catchpad.llbb()); // The flag value of 8 indicates that we are catching the exception by - // reference instead of by value. + // reference instead of by value. We can't use catch by value because + // that requires copying the exception object, which we don't support + // since our exception object effectively contains a Box. // // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang let flags = bx.const_i32(8); @@ -970,6 +972,8 @@ fn codegen_msvc_try( catchpad.store(payload, local_ptr, i64_align); // Clear the first word of the exception so avoid double-dropping it. + // This will be read by the destructor which is implicitly called at the + // end of the catch block by the runtime. let payload_0_ptr = catchpad.inbounds_gep(payload_ptr, &[bx.const_i32(0), bx.const_i32(0)]); catchpad.store(bx.const_u64(0), payload_0_ptr, i64_align); From 3a025760be8f4c56f0777fa34ba64a4f7bada8e7 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 10 Jan 2020 00:19:40 +0000 Subject: [PATCH 0256/1253] Abort if C++ tries to swallow a Rust panic --- src/libpanic_unwind/emcc.rs | 1 + src/libpanic_unwind/gcc.rs | 1 + src/libpanic_unwind/lib.rs | 6 ++++ src/libpanic_unwind/seh.rs | 1 + src/libstd/panicking.rs | 8 +++++ .../foreign-exceptions/foo.cpp | 17 ----------- .../foreign-exceptions/foo.rs | 29 ------------------- 7 files changed, 17 insertions(+), 46 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index fbadf4ac6a058..268bafd240930 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -80,6 +80,7 @@ pub unsafe fn panic(data: Box) -> u32 { extern "C" fn exception_cleanup(ptr: *mut libc::c_void) { unsafe { ptr::drop_in_place(ptr as *mut Exception); + super::__rust_drop_panic(); } } } diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 6bec2686533eb..6e04317d491fc 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -78,6 +78,7 @@ pub unsafe fn panic(data: Box) -> u32 { ) { unsafe { let _: Box = Box::from_raw(exception as *mut Exception); + super::__rust_drop_panic(); } } } diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 9451eefb9a5cc..6383ae39fb6db 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -61,6 +61,12 @@ cfg_if::cfg_if! { } } +extern "C" { + /// Handler in libstd called when a panic object is dropped outside of + /// `catch_unwind`. + fn __rust_drop_panic() -> !; +} + mod dwarf; // Entry point for catching an exception, implemented using the `try` intrinsic diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index f1d0080472a01..d9dca2c0f4f47 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -229,6 +229,7 @@ macro_rules! define_cleanup { unsafe extern $abi fn exception_cleanup(e: *mut [u64; 2]) { if (*e)[0] != 0 { cleanup(*e); + super::__rust_drop_panic(); } } #[unwind(allowed)] diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 599ccc809be1f..43c2965f2315a 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -55,6 +55,14 @@ extern "C" { fn __rust_start_panic(payload: usize) -> u32; } +/// This function is called by the panic runtime if FFI code catches a Rust +/// panic but doesn't rethrow it. We don't support this case since it messes +/// with our panic count. +#[rustc_std_internal_symbol] +extern "C" fn __rust_drop_panic() -> ! { + rtabort!("Rust panics must be rethrown"); +} + #[derive(Copy, Clone)] enum Hook { Default, diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp index ef5cd74c65283..b0fd65f88e7de 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp @@ -57,21 +57,4 @@ extern "C" { throw; } } - - void swallow_exception(void (*cb)()) { - try { - // Do a rethrow to ensure that the exception is only dropped once. - // This is necessary since we don't support copying exceptions. - try { - cb(); - } catch (...) { - println("rethrowing Rust panic"); - throw; - }; - } catch (rust_panic e) { - assert(false && "shouldn't be able to catch a rust panic"); - } catch (...) { - println("swallowing foreign exception in catch (...)"); - } - } } diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs index d9818dffc502b..9c2045c8c89f7 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs @@ -19,8 +19,6 @@ impl<'a> Drop for DropCheck<'a> { extern "C" { fn throw_cxx_exception(); - fn swallow_exception(cb: extern "C" fn()); - #[unwind(allowed)] fn cxx_catch_callback(cb: extern "C" fn(), ok: *mut bool); } @@ -61,34 +59,7 @@ fn throw_rust_panic() { assert!(cxx_ok); } -fn check_exception_drop() { - static mut DROP_COUNT: usize = 0; - - struct CountDrop; - impl Drop for CountDrop { - fn drop(&mut self) { - println!("CountDrop::drop"); - unsafe { - DROP_COUNT += 1; - } - } - } - - - #[unwind(allowed)] - extern "C" fn callback() { - println!("throwing rust panic #2"); - panic!(CountDrop); - } - - unsafe { - swallow_exception(callback); - assert_eq!(DROP_COUNT, 1); - } -} - fn main() { unsafe { throw_cxx_exception() }; throw_rust_panic(); - check_exception_drop(); } From 9ef4fd7e19c347f9e04b44b3470ebf22ecea71a1 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 Jan 2020 13:04:06 +0000 Subject: [PATCH 0257/1253] Clarify the relationship between `extended` and `tools` in `config.toml` --- config.toml.example | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/config.toml.example b/config.toml.example index bfd9e18cdd41a..c9e17337ee23f 100644 --- a/config.toml.example +++ b/config.toml.example @@ -181,21 +181,23 @@ # Indicate whether the vendored sources are used for Rust dependencies or not #vendor = false -# Typically the build system will build the rust compiler twice. The second +# Typically the build system will build the Rust compiler twice. The second # compiler, however, will simply use its own libraries to link against. If you # would rather to perform a full bootstrap, compiling the compiler three times, # then you can set this option to true. You shouldn't ever need to set this # option to true. #full-bootstrap = false -# Enable a build of the extended rust tool set which is not only the compiler +# Enable a build of the extended Rust tool set which is not only the compiler # but also tools such as Cargo. This will also produce "combined installers" # which are used to install Rust and Cargo together. This is disabled by -# default. +# default. The `tools` option (immediately below) specifies which tools should +# be built if `extended = true`. #extended = false -# Installs chosen set of extended tools if enabled. By default builds all. -# If chosen tool failed to build the installation fails. +# Installs chosen set of extended tools if `extended = true`. By default builds all. +# If chosen tool failed to build the installation fails. If `extended = false`, this +# option is ignored. #tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"] # Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose From e51eccd2eff685bda7b5d6734ff4923b706bd476 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 11 Jan 2020 14:40:07 +0100 Subject: [PATCH 0258/1253] Make codegen tests wordsize independent --- src/test/codegen/consts.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index a5478a0379111..a89ecdfd3a901 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -14,10 +14,9 @@ // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}} getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* @2, i32 0, i32 0, i32 0), {{.*}}, align 8 +// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}} getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* @2, i32 0, i32 0, i32 0), {{.*}}, #[derive(Copy, Clone)] - // repr(i16) is required for the {low,high}_align_const test #[repr(i16)] pub enum E { @@ -31,7 +30,7 @@ pub static STATIC: E = E::A(0); // CHECK-LABEL: @static_enum_const #[no_mangle] pub fn static_enum_const() -> E { - STATIC + STATIC } // CHECK-LABEL: @inline_enum_const @@ -43,15 +42,15 @@ pub fn inline_enum_const() -> E { // CHECK-LABEL: @low_align_const #[no_mangle] pub fn low_align_const() -> E { -// Check that low_align_const and high_align_const use the same constant -// CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), align 8 + // Check that low_align_const and high_align_const use the same constant + // CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), *&E::A(0) } // CHECK-LABEL: @high_align_const #[no_mangle] pub fn high_align_const() -> E { -// Check that low_align_const and high_align_const use the same constant -// CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), align 8 + // Check that low_align_const and high_align_const use the same constant + // CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), *&E::A(0) } From c5a9a14c9f793ce20d34cffac09f4ee21d541565 Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Wed, 1 Jan 2020 00:25:20 +0100 Subject: [PATCH 0259/1253] Constify alloc::Layout Tracking issue #67521, Layout::new in #66254 --- src/libcore/alloc.rs | 12 ++++++++---- src/libcore/lib.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 163f9170b8bfb..4354e1c7b5f69 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -64,8 +64,9 @@ impl Layout { /// must not overflow (i.e., the rounded value must be less than /// `usize::MAX`). #[stable(feature = "alloc_layout", since = "1.28.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn from_size_align(size: usize, align: usize) -> Result { + pub const fn from_size_align(size: usize, align: usize) -> Result { if !align.is_power_of_two() { return Err(LayoutErr { private: () }); } @@ -106,15 +107,17 @@ impl Layout { /// The minimum size in bytes for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn size(&self) -> usize { + pub const fn size(&self) -> usize { self.size_ } /// The minimum byte alignment for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn align(&self) -> usize { + pub const fn align(&self) -> usize { self.align_.get() } @@ -181,8 +184,9 @@ impl Layout { /// address for the whole allocated block of memory. One way to /// satisfy this constraint is to ensure `align <= self.align()`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn padding_needed_for(&self, align: usize) -> usize { + pub const fn padding_needed_for(&self, align: usize) -> usize { let len = self.size(); // Rounded up value is: diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 6c4956663841c..95ffe4f438f5f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -70,6 +70,7 @@ #![feature(bound_cloned)] #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] +#![feature(const_alloc_layout)] #![feature(const_if_match)] #![feature(const_panic)] #![feature(const_fn_union)] From 6d5170c960d1cf0ad1137bbf65e4d1c992cc21fe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 19:10:11 +0100 Subject: [PATCH 0260/1253] Move some queries from rustc::ty to librustc_passes. --- src/librustc/ty/mod.rs | 356 +---------------------------------- src/librustc_passes/lib.rs | 3 + src/librustc_passes/ty.rs | 369 +++++++++++++++++++++++++++++++++++++ 3 files changed, 374 insertions(+), 354 deletions(-) create mode 100644 src/librustc_passes/ty.rs diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d1e37a4ea1151..e6acb6b74dc63 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -18,7 +18,6 @@ use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::mir::interpret::ErrorHandled; use crate::mir::GeneratorLayout; use crate::mir::ReadOnlyBodyAndCache; -use crate::session::CrateDisambiguator; use crate::session::DataTypeKind; use crate::traits::{self, Reveal}; use crate::ty; @@ -31,7 +30,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -2423,70 +2421,6 @@ impl<'tcx> AdtDef { pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { tcx.adt_sized_constraint(self.did).0 } - - fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec> { - let result = match ty.kind { - Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) - | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], - - Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { - // these are never sized - return the target type - vec![ty] - } - - Tuple(ref tys) => match tys.last() { - None => vec![], - Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()), - }, - - Adt(adt, substs) => { - // recursive case - let adt_tys = adt.sized_constraint(tcx); - debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); - adt_tys - .iter() - .map(|ty| ty.subst(tcx, substs)) - .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) - .collect() - } - - Projection(..) | Opaque(..) => { - // must calculate explicitly. - // FIXME: consider special-casing always-Sized projections - vec![ty] - } - - UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - - Param(..) => { - // perf hack: if there is a `T: Sized` bound, then - // we know that `T` is Sized and do not need to check - // it on the impl. - - let sized_trait = match tcx.lang_items().sized_trait() { - Some(x) => x, - _ => return vec![ty], - }; - let sized_predicate = Binder::dummy(TraitRef { - def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]), - }) - .to_predicate(); - let predicates = tcx.predicates_of(self.did).predicates; - if predicates.iter().any(|(p, _)| *p == sized_predicate) { - vec![] - } else { - vec![ty] - } - } - - Placeholder(..) | Bound(..) | Infer(..) => { - bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) - } - }; - debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); - result - } } impl<'tcx> FieldDef { @@ -2742,57 +2676,6 @@ impl<'tcx> TyCtxt<'tcx> { is_associated_item.then(|| self.associated_item(def_id)) } - fn associated_item_from_trait_item_ref( - self, - parent_def_id: DefId, - parent_vis: &hir::Visibility<'_>, - trait_item_ref: &hir::TraitItemRef, - ) -> AssocItem { - let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id); - let (kind, has_self) = match trait_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), - }; - - AssocItem { - ident: trait_item_ref.ident, - kind, - // Visibility of trait items is inherited from their traits. - vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self), - defaultness: trait_item_ref.defaultness, - def_id, - container: TraitContainer(parent_def_id), - method_has_self_argument: has_self, - } - } - - fn associated_item_from_impl_item_ref( - self, - parent_def_id: DefId, - impl_item_ref: &hir::ImplItemRef<'_>, - ) -> AssocItem { - let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id); - let (kind, has_self) = match impl_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), - }; - - AssocItem { - ident: impl_item_ref.ident, - kind, - // Visibility of trait impl items doesn't matter. - vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self), - defaultness: impl_item_ref.defaultness, - def_id, - container: ImplContainer(parent_def_id), - method_has_self_argument: has_self, - } - } - pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize { tables.field_indices().get(hir_id).cloned().expect("no index for a field") } @@ -3070,105 +2953,9 @@ impl Iterator for AssocItemsIterator<'_> { } } -fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let parent_id = tcx.hir().get_parent_item(id); - let parent_def_id = tcx.hir().local_def_id(parent_id); - let parent_item = tcx.hir().expect_item(parent_id); - match parent_item.kind { - hir::ItemKind::Impl(.., ref impl_item_refs) => { - if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = - tcx.associated_item_from_impl_item_ref(parent_def_id, impl_item_ref); - debug_assert_eq!(assoc_item.def_id, def_id); - return assoc_item; - } - } - - hir::ItemKind::Trait(.., ref trait_item_refs) => { - if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = tcx.associated_item_from_trait_item_ref( - parent_def_id, - &parent_item.vis, - trait_item_ref, - ); - debug_assert_eq!(assoc_item.def_id, def_id); - return assoc_item; - } - } - - _ => {} - } - - span_bug!( - parent_item.span, - "unexpected parent of trait or impl item or item not found: {:?}", - parent_item.kind - ) -} - #[derive(Clone, HashStable)] pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); -/// Calculates the `Sized` constraint. -/// -/// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type -/// - a type parameter or projection whose Sizedness can't be known -/// - a tuple of type parameters or projections, if there are multiple -/// such. -/// - a Error, if a type contained itself. The representability -/// check should catch this case. -fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> AdtSizedConstraint<'_> { - let def = tcx.adt_def(def_id); - - let result = tcx.mk_type_list( - def.variants - .iter() - .flat_map(|v| v.fields.last()) - .flat_map(|f| def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))), - ); - - debug!("adt_sized_constraint: {:?} => {:?}", def, result); - - AdtSizedConstraint(result) -} - -fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let item = tcx.hir().expect_item(id); - match item.kind { - hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter( - trait_item_refs - .iter() - .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)), - ), - hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( - impl_item_refs - .iter() - .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)), - ), - hir::ItemKind::TraitAlias(..) => &[], - _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), - } -} - -fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { - tcx.hir().span_if_local(def_id).unwrap() -} - -/// If the given `DefId` describes an item belonging to a trait, -/// returns the `DefId` of the trait that the trait item belongs to; -/// otherwise, returns `None`. -fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container { - TraitContainer(def_id) => Some(def_id), - ImplContainer(_) => None, - }) -} - /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition. pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { @@ -3181,151 +2968,12 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { None } -/// See `ParamEnv` struct definition for details. -fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ParamEnv<'_> { - // The param_env of an impl Trait type is its defining function's param_env - if let Some(parent) = is_impl_trait_defn(tcx, def_id) { - return param_env(tcx, parent); - } - // Compute the bounds on Self and the type parameters. - - let InstantiatedPredicates { predicates } = tcx.predicates_of(def_id).instantiate_identity(tcx); - - // Finally, we have to normalize the bounds in the environment, in - // case they contain any associated type projections. This process - // can yield errors if the put in illegal associated types, like - // `::Bar` where `i32` does not implement `Foo`. We - // report these errors right here; this doesn't actually feel - // right to me, because constructing the environment feels like a - // kind of a "idempotent" action, but I'm not sure where would be - // a better place. In practice, we construct environments for - // every fn once during type checking, and we'll abort if there - // are any errors at that point, so after type checking you can be - // sure that this will succeed without errors anyway. - - let unnormalized_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - traits::Reveal::UserFacing, - tcx.sess.opts.debugging_opts.chalk.then_some(def_id), - ); - - let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { - tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) - }); - let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); - traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) -} - -fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.sess.local_crate_disambiguator() -} - -fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.crate_name.clone() -} - -fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.hir().crate_hash -} - -fn instance_def_size_estimate<'tcx>(tcx: TyCtxt<'tcx>, instance_def: InstanceDef<'tcx>) -> usize { - match instance_def { - InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { - let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() - } - // Estimate the size of other compiler-generated shims to be 1. - _ => 1, - } -} - -/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. -/// -/// See [`ImplOverlapKind::Issue33140`] for more details. -fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { - debug!("issue33140_self_ty({:?})", def_id); - - let trait_ref = tcx - .impl_trait_ref(def_id) - .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); - - debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); - - let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive - && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); - - // Check whether these impls would be ok for a marker trait. - if !is_marker_like { - debug!("issue33140_self_ty - not marker-like!"); - return None; - } - - // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` - if trait_ref.substs.len() != 1 { - debug!("issue33140_self_ty - impl has substs!"); - return None; - } - - let predicates = tcx.predicates_of(def_id); - if predicates.parent.is_some() || !predicates.predicates.is_empty() { - debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); - return None; - } - - let self_ty = trait_ref.self_ty(); - let self_ty_matches = match self_ty.kind { - ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), - _ => false, - }; - - if self_ty_matches { - debug!("issue33140_self_ty - MATCHES!"); - Some(self_ty) - } else { - debug!("issue33140_self_ty - non-matching self type"); - None - } -} - -/// Check if a function is async. -fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { - let hir_id = tcx - .hir() - .as_local_hir_id(def_id) - .unwrap_or_else(|| bug!("asyncness: expected local `DefId`, got `{:?}`", def_id)); - - let node = tcx.hir().get(hir_id); - - let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { - bug!("asyncness: expected fn-like node but got `{:?}`", def_id); - }); - - fn_like.asyncness() -} - pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); layout::provide(providers); - *providers = ty::query::Providers { - asyncness, - associated_item, - associated_item_def_ids, - adt_sized_constraint, - def_span, - param_env, - trait_of_item, - crate_disambiguator, - original_crate_name, - crate_hash, - trait_impls_of: trait_def::trait_impls_of_provider, - instance_def_size_estimate, - issue33140_self_ty, - ..*providers - }; + *providers = + ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, ..*providers }; } /// A map for the local crate mapping each type to a vector of its diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 65eb07b989d83..8bd06465628fa 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(slice_patterns)] @@ -30,6 +31,7 @@ pub mod loops; mod reachable; mod region; pub mod stability; +mod ty; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); @@ -42,4 +44,5 @@ pub fn provide(providers: &mut Providers<'_>) { reachable::provide(providers); region::provide(providers); stability::provide(providers); + ty::provide(providers); } diff --git a/src/librustc_passes/ty.rs b/src/librustc_passes/ty.rs new file mode 100644 index 0000000000000..fc8beb67e4ada --- /dev/null +++ b/src/librustc_passes/ty.rs @@ -0,0 +1,369 @@ +use rustc::hir::map as hir_map; +use rustc::session::CrateDisambiguator; +use rustc::traits::{self}; +use rustc::ty::subst::Subst; +use rustc::ty::{self, ToPredicate, Ty, TyCtxt}; +use rustc_data_structures::svh::Svh; +use rustc_hir as hir; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_span::symbol::Symbol; +use rustc_span::Span; + +fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>) -> Vec> { + use ty::TyKind::*; + + let result = match ty.kind { + Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) + | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], + + Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { + // these are never sized - return the target type + vec![ty] + } + + Tuple(ref tys) => match tys.last() { + None => vec![], + Some(ty) => sized_constraint_for_ty(tcx, adtdef, ty.expect_ty()), + }, + + Adt(adt, substs) => { + // recursive case + let adt_tys = adt.sized_constraint(tcx); + debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); + adt_tys + .iter() + .map(|ty| ty.subst(tcx, substs)) + .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) + .collect() + } + + Projection(..) | Opaque(..) => { + // must calculate explicitly. + // FIXME: consider special-casing always-Sized projections + vec![ty] + } + + UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + + Param(..) => { + // perf hack: if there is a `T: Sized` bound, then + // we know that `T` is Sized and do not need to check + // it on the impl. + + let sized_trait = match tcx.lang_items().sized_trait() { + Some(x) => x, + _ => return vec![ty], + }; + let sized_predicate = ty::Binder::dummy(ty::TraitRef { + def_id: sized_trait, + substs: tcx.mk_substs_trait(ty, &[]), + }) + .to_predicate(); + let predicates = tcx.predicates_of(adtdef.did).predicates; + if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } + } + + Placeholder(..) | Bound(..) | Infer(..) => { + bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) + } + }; + debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); + result +} + +fn associated_item_from_trait_item_ref( + tcx: TyCtxt<'_>, + parent_def_id: DefId, + parent_vis: &hir::Visibility<'_>, + trait_item_ref: &hir::TraitItemRef, +) -> ty::AssocItem { + let def_id = tcx.hir().local_def_id(trait_item_ref.id.hir_id); + let (kind, has_self) = match trait_item_ref.kind { + hir::AssocItemKind::Const => (ty::AssocKind::Const, false), + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), + }; + + ty::AssocItem { + ident: trait_item_ref.ident, + kind, + // Visibility of trait items is inherited from their traits. + vis: ty::Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, tcx), + defaultness: trait_item_ref.defaultness, + def_id, + container: ty::TraitContainer(parent_def_id), + method_has_self_argument: has_self, + } +} + +fn associated_item_from_impl_item_ref( + tcx: TyCtxt<'_>, + parent_def_id: DefId, + impl_item_ref: &hir::ImplItemRef<'_>, +) -> ty::AssocItem { + let def_id = tcx.hir().local_def_id(impl_item_ref.id.hir_id); + let (kind, has_self) = match impl_item_ref.kind { + hir::AssocItemKind::Const => (ty::AssocKind::Const, false), + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), + }; + + ty::AssocItem { + ident: impl_item_ref.ident, + kind, + // Visibility of trait impl items doesn't matter. + vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, tcx), + defaultness: impl_item_ref.defaultness, + def_id, + container: ty::ImplContainer(parent_def_id), + method_has_self_argument: has_self, + } +} + +fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { + let id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let parent_id = tcx.hir().get_parent_item(id); + let parent_def_id = tcx.hir().local_def_id(parent_id); + let parent_item = tcx.hir().expect_item(parent_id); + match parent_item.kind { + hir::ItemKind::Impl(.., ref impl_item_refs) => { + if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { + let assoc_item = + associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + hir::ItemKind::Trait(.., ref trait_item_refs) => { + if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { + let assoc_item = associated_item_from_trait_item_ref( + tcx, + parent_def_id, + &parent_item.vis, + trait_item_ref, + ); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + _ => {} + } + + span_bug!( + parent_item.span, + "unexpected parent of trait or impl item or item not found: {:?}", + parent_item.kind + ) +} + +/// Calculates the `Sized` constraint. +/// +/// In fact, there are only a few options for the types in the constraint: +/// - an obviously-unsized type +/// - a type parameter or projection whose Sizedness can't be known +/// - a tuple of type parameters or projections, if there are multiple +/// such. +/// - a Error, if a type contained itself. The representability +/// check should catch this case. +fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstraint<'_> { + let def = tcx.adt_def(def_id); + + let result = tcx.mk_type_list( + def.variants + .iter() + .flat_map(|v| v.fields.last()) + .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))), + ); + + debug!("adt_sized_constraint: {:?} => {:?}", def, result); + + ty::AdtSizedConstraint(result) +} + +fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { + let id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let item = tcx.hir().expect_item(id); + match item.kind { + hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter( + trait_item_refs + .iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), + hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( + impl_item_refs + .iter() + .map(|impl_item_ref| impl_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), + hir::ItemKind::TraitAlias(..) => &[], + _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), + } +} + +fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { + tcx.hir().span_if_local(def_id).unwrap() +} + +/// If the given `DefId` describes an item belonging to a trait, +/// returns the `DefId` of the trait that the trait item belongs to; +/// otherwise, returns `None`. +fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container { + ty::TraitContainer(def_id) => Some(def_id), + ty::ImplContainer(_) => None, + }) +} + +/// See `ParamEnv` struct definition for details. +fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + // The param_env of an impl Trait type is its defining function's param_env + if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { + return param_env(tcx, parent); + } + // Compute the bounds on Self and the type parameters. + + let ty::InstantiatedPredicates { predicates } = + tcx.predicates_of(def_id).instantiate_identity(tcx); + + // Finally, we have to normalize the bounds in the environment, in + // case they contain any associated type projections. This process + // can yield errors if the put in illegal associated types, like + // `::Bar` where `i32` does not implement `Foo`. We + // report these errors right here; this doesn't actually feel + // right to me, because constructing the environment feels like a + // kind of a "idempotent" action, but I'm not sure where would be + // a better place. In practice, we construct environments for + // every fn once during type checking, and we'll abort if there + // are any errors at that point, so after type checking you can be + // sure that this will succeed without errors anyway. + + let unnormalized_env = ty::ParamEnv::new( + tcx.intern_predicates(&predicates), + traits::Reveal::UserFacing, + tcx.sess.opts.debugging_opts.chalk.then_some(def_id), + ); + + let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { + tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) + }); + let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); + traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) +} + +fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.sess.local_crate_disambiguator() +} + +fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.crate_name.clone() +} + +fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.hir().crate_hash +} + +fn instance_def_size_estimate<'tcx>( + tcx: TyCtxt<'tcx>, + instance_def: ty::InstanceDef<'tcx>, +) -> usize { + use ty::InstanceDef; + + match instance_def { + InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { + let mir = tcx.instance_mir(instance_def); + mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + } + // Estimate the size of other compiler-generated shims to be 1. + _ => 1, + } +} + +/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. +/// +/// See [`ImplOverlapKind::Issue33140`] for more details. +fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { + debug!("issue33140_self_ty({:?})", def_id); + + let trait_ref = tcx + .impl_trait_ref(def_id) + .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); + + debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); + + let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive + && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); + + // Check whether these impls would be ok for a marker trait. + if !is_marker_like { + debug!("issue33140_self_ty - not marker-like!"); + return None; + } + + // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` + if trait_ref.substs.len() != 1 { + debug!("issue33140_self_ty - impl has substs!"); + return None; + } + + let predicates = tcx.predicates_of(def_id); + if predicates.parent.is_some() || !predicates.predicates.is_empty() { + debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); + return None; + } + + let self_ty = trait_ref.self_ty(); + let self_ty_matches = match self_ty.kind { + ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), + _ => false, + }; + + if self_ty_matches { + debug!("issue33140_self_ty - MATCHES!"); + Some(self_ty) + } else { + debug!("issue33140_self_ty - non-matching self type"); + None + } +} + +/// Check if a function is async. +fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { + let hir_id = tcx + .hir() + .as_local_hir_id(def_id) + .unwrap_or_else(|| bug!("asyncness: expected local `DefId`, got `{:?}`", def_id)); + + let node = tcx.hir().get(hir_id); + + let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { + bug!("asyncness: expected fn-like node but got `{:?}`", def_id); + }); + + fn_like.asyncness() +} + +pub fn provide(providers: &mut ty::query::Providers<'_>) { + *providers = ty::query::Providers { + asyncness, + associated_item, + associated_item_def_ids, + adt_sized_constraint, + def_span, + param_env, + trait_of_item, + crate_disambiguator, + original_crate_name, + crate_hash, + instance_def_size_estimate, + issue33140_self_ty, + ..*providers + }; +} From d59e9b40a3712fa29e59b17cc2a9a10549cae79f Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 11 Jan 2020 16:56:21 +0800 Subject: [PATCH 0261/1253] Implement Cursor for linked lists. (RFC 2570). --- src/liballoc/collections/linked_list.rs | 457 +++++++++++++++++- src/liballoc/collections/linked_list/tests.rs | 98 ++++ 2 files changed, 531 insertions(+), 24 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 29bf2fdb30cf7..d0ad1ec283942 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -242,6 +242,88 @@ impl LinkedList { self.len -= 1; } + + /// Splices a series of nodes between two existing nodes. + /// + /// Warning: this will not check that the provided node belongs to the two existing lists. + #[inline] + unsafe fn splice_nodes( + &mut self, + existing_prev: Option>>, + existing_next: Option>>, + splice_start: NonNull>, + splice_end: NonNull>, + splice_length: usize, + ) { + // This method takes care not to create multiple mutable references to whole nodes at the same time, + // to maintain validity of aliasing pointers into `element`. + if let Some(mut existing_prev) = existing_prev { + existing_prev.as_mut().next = Some(splice_start); + } else { + self.head = Some(splice_start); + } + if let Some(mut existing_next) = existing_next { + existing_next.as_mut().prev = Some(splice_end); + } else { + self.tail = Some(splice_end); + } + let mut splice_start = splice_start; + splice_start.as_mut().prev = existing_prev; + let mut splice_end = splice_end; + splice_end.as_mut().next = existing_next; + + self.len += splice_length; + } + + /// Detaches all nodes from a linked list as a series of nodes. + #[inline] + fn detach_all_nodes(mut self) -> Option<(NonNull>, NonNull>, usize)> { + let head = self.head.take(); + let tail = self.tail.take(); + let len = mem::replace(&mut self.len, 0); + if let Some(head) = head { + let tail = tail.unwrap_or_else(|| unsafe { core::hint::unreachable_unchecked() }); + Some((head, tail, len)) + } else { + None + } + } + + #[inline] + unsafe fn split_off_after_node( + &mut self, + split_node: Option>>, + at: usize, + ) -> Self { + // The split node is the new tail node of the first part and owns + // the head of the second part. + if let Some(mut split_node) = split_node { + let second_part_head; + let second_part_tail; + second_part_head = split_node.as_mut().next.take(); + if let Some(mut head) = second_part_head { + head.as_mut().prev = None; + second_part_tail = self.tail; + } else { + second_part_tail = None; + } + + let second_part = LinkedList { + head: second_part_head, + tail: second_part_tail, + len: self.len - at, + marker: PhantomData, + }; + + // Fix the tail ptr of the first part + self.tail = Some(split_node); + self.len = at; + + second_part + } else { + mem::replace(self, LinkedList::new()) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -319,6 +401,27 @@ impl LinkedList { } } + /// Moves all elements from `other` to the begin of the list. + #[unstable(feature = "linked_list_prepend", issue = "none")] + pub fn prepend(&mut self, other: &mut Self) { + match self.head { + None => mem::swap(self, other), + Some(mut head) => { + // `as_mut` is okay here because we have exclusive access to the entirety + // of both lists. + if let Some(mut other_tail) = other.tail.take() { + unsafe { + head.as_mut().prev = Some(other_tail); + other_tail.as_mut().next = Some(head); + } + + self.head = other.head.take(); + self.len += mem::replace(&mut other.len, 0); + } + } + } + } + /// Provides a forward iterator. /// /// # Examples @@ -373,6 +476,20 @@ impl LinkedList { IterMut { head: self.head, tail: self.tail, len: self.len, list: self } } + /// Provides a cursor. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor(&self) -> Cursor<'_, T> { + Cursor { index: 0, current: self.head, list: self } + } + + /// Provides a cursor with editing operations. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_mut(&mut self) -> CursorMut<'_, T> { + CursorMut { index: 0, current: self.head, list: self } + } + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. @@ -703,30 +820,7 @@ impl LinkedList { } iter.tail }; - - // The split node is the new tail node of the first part and owns - // the head of the second part. - let second_part_head; - - unsafe { - second_part_head = split_node.unwrap().as_mut().next.take(); - if let Some(mut head) = second_part_head { - head.as_mut().prev = None; - } - } - - let second_part = LinkedList { - head: second_part_head, - tail: self.tail, - len: len - at, - marker: PhantomData, - }; - - // Fix the tail ptr of the first part - self.tail = split_node; - self.len = at; - - second_part + unsafe { self.split_off_after_node(split_node, at) } } /// Creates an iterator which uses a closure to determine if an element should be removed. @@ -986,6 +1080,321 @@ impl IterMut<'_, T> { } } +/// A cursor over a `LinkedList`. +/// +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can +/// safely mutate the list during iteration. This is because the lifetime of its yielded +/// references is tied to its own lifetime, instead of just the underlying list. This means +/// cursors cannot yield multiple elements at once. +/// +/// Cursors always rest between two elements in the list, and index in a logically circular way. +/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and +/// tail of the list. +/// +/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +#[unstable(feature = "linked_list_cursors", issue = "58533")] +pub struct Cursor<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a LinkedList, +} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +impl fmt::Debug for Cursor<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Cursor").field(&self.list).field(&self.index).finish() + } +} + +/// A cursor over a `LinkedList` with editing operations. +/// +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can +/// safely mutate the list during iteration. This is because the lifetime of its yielded +/// references is tied to its own lifetime, instead of just the underlying list. This means +/// cursors cannot yield multiple elements at once. +/// +/// Cursors always rest between two elements in the list, and index in a logically circular way. +/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and +/// tail of the list. +/// +/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +#[unstable(feature = "linked_list_cursors", issue = "58533")] +pub struct CursorMut<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a mut LinkedList, +} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +impl fmt::Debug for CursorMut<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("CursorMut").field(&self.list).field(&self.index).finish() + } +} + +impl<'a, T> Cursor<'a, T> { + /// Move to the subsequent element of the list if it exists or the empty + /// element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_next(&mut self) { + match self.current.take() { + // We had no current element; the cursor was sitting at the start position + // Next element should be the head of the list + None => { + self.current = self.list.head; + self.index = 0; + } + // We had a previous element, so let's go to its next + Some(current) => unsafe { + self.current = current.as_ref().next; + self.index += 1; + }, + } + } + + /// Move to the previous element of the list + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_prev(&mut self) { + match self.current.take() { + // No current. We're at the start of the list. Yield None and jump to the end. + None => { + self.current = self.list.tail; + self.index = self.list.len().checked_sub(1).unwrap_or(0); + } + // Have a prev. Yield it and go to the previous element. + Some(current) => unsafe { + self.current = current.as_ref().prev; + self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); + }, + } + } + + /// Get the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn current(&self) -> Option<&'a T> { + unsafe { self.current.map(|current| &(*current.as_ptr()).element) } + } + + /// Get the next element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_next(&self) -> Option<&'a T> { + unsafe { + let next = match self.current { + None => self.list.head, + Some(current) => current.as_ref().next, + }; + next.map(|next| &(*next.as_ptr()).element) + } + } + + /// Get the previous element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_prev(&self) -> Option<&'a T> { + unsafe { + let prev = match self.current { + None => self.list.tail, + Some(current) => current.as_ref().prev, + }; + prev.map(|prev| &(*prev.as_ptr()).element) + } + } +} + +impl<'a, T> CursorMut<'a, T> { + /// Move to the subsequent element of the list if it exists or the empty + /// element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_next(&mut self) { + match self.current.take() { + // We had no current element; the cursor was sitting at the start position + // Next element should be the head of the list + None => { + self.current = self.list.head; + self.index = 0; + } + // We had a previous element, so let's go to its next + Some(current) => unsafe { + self.current = current.as_ref().next; + self.index += 1; + }, + } + } + + /// Move to the previous element of the list + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_prev(&mut self) { + match self.current.take() { + // No current. We're at the start of the list. Yield None and jump to the end. + None => { + self.current = self.list.tail; + self.index = self.list.len().checked_sub(1).unwrap_or(0); + } + // Have a prev. Yield it and go to the previous element. + Some(current) => unsafe { + self.current = current.as_ref().prev; + self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); + }, + } + } + + /// Get the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn current(&mut self) -> Option<&mut T> { + unsafe { self.current.map(|current| &mut (*current.as_ptr()).element) } + } + + /// Get the next element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_next(&mut self) -> Option<&mut T> { + unsafe { + let next = match self.current { + None => self.list.head, + Some(current) => current.as_ref().next, + }; + next.map(|next| &mut (*next.as_ptr()).element) + } + } + + /// Get the previous element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_prev(&mut self) -> Option<&mut T> { + unsafe { + let prev = match self.current { + None => self.list.tail, + Some(current) => current.as_ref().prev, + }; + prev.map(|prev| &mut (*prev.as_ptr()).element) + } + } + + /// Get an immutable cursor at the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn as_cursor<'cm>(&'cm self) -> Cursor<'cm, T> { + Cursor { list: self.list, current: self.current, index: self.index } + } +} + +// Now the list editing operations + +impl<'a, T> CursorMut<'a, T> { + /// Insert `item` after the cursor + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn insert_after(&mut self, item: T) { + unsafe { + let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); + let (node, node_next) = match self.current { + None => (None, self.list.head), + Some(node) => { + let node_next = node.as_ref().next; + (Some(node), node_next) + } + }; + self.list.splice_nodes(node, node_next, spliced_node, spliced_node, 1); + if self.current.is_none() { + // The ghost element's index has increased by 1. + self.index += 1; + } + } + } + + /// Insert `item` before the cursor + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn insert_before(&mut self, item: T) { + unsafe { + let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); + let (node_prev, node) = match self.current { + None => (self.list.tail, None), + Some(node) => { + let node_prev = node.as_ref().prev; + (node_prev, Some(node)) + } + }; + self.list.splice_nodes(node_prev, node, spliced_node, spliced_node, 1); + self.index += 1; + } + } + + /// Remove and return the current item, moving the cursor to the next item + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn remove(&mut self) -> Option { + let unlinked_node = self.current?; + unsafe { + self.current = unlinked_node.as_ref().next; + self.list.unlink_node(unlinked_node); + let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); + Some((*unlinked_node).element) + } + } + + /// Insert `list` between the current element and the next + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_after(&mut self, list: LinkedList) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let (node, node_next) = match self.current { + None => (None, self.list.head), + Some(node) => { + let node_next = node.as_ref().next; + (Some(node), node_next) + } + }; + self.list.splice_nodes(node, node_next, splice_head, splice_tail, splice_len); + if self.current.is_none() { + // The ghost element's index has increased by `splice_len`. + self.index += splice_len; + } + } + } + + /// Insert `list` between the previous element and current + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_before(&mut self, list: LinkedList) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let (node_prev, node) = match self.current { + None => (self.list.tail, None), + Some(node) => { + let node_prev = node.as_ref().prev; + (node_prev, Some(node)) + } + }; + self.list.splice_nodes(node_prev, node, splice_head, splice_tail, splice_len); + self.index += splice_len; + } + } + + /// Split the list in two after the current element + /// The returned list consists of all elements following the current one. + // note: consuming the cursor is not necessary here, but it makes sense + // given the interface + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn split_after(self) -> LinkedList { + let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; + unsafe { + let split_off_node = self.current; + self.list.split_off_after_node(split_off_node, split_off_idx) + } + } + /// Split the list in two before the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn split_before(self) -> LinkedList { + let split_off_idx = self.index; + unsafe { + let split_off_node = match self.current { + Some(node) => node.as_ref().prev, + None => self.list.tail, + }; + self.list.split_off_after_node(split_off_node, split_off_idx) + } + } +} + /// An iterator produced by calling `drain_filter` on LinkedList. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] pub struct DrainFilter<'a, T: 'a, F: 'a> diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 1b1d8eab39bfc..51b23e23cd276 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -304,3 +304,101 @@ fn drain_to_empty_test() { assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); assert_eq!(m.into_iter().collect::>(), &[]); } + +#[test] +fn test_cursor_move_peek() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor(); + assert_eq!(cursor.current(), Some(&1)); + assert_eq!(cursor.peek_next(), Some(&2)); + assert_eq!(cursor.peek_prev(), None); + cursor.move_prev(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&1)); + assert_eq!(cursor.peek_prev(), Some(&6)); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.current(), Some(&2)); + assert_eq!(cursor.peek_next(), Some(&3)); + assert_eq!(cursor.peek_prev(), Some(&1)); + + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + assert_eq!(cursor.current(), Some(&mut 1)); + assert_eq!(cursor.peek_next(), Some(&mut 2)); + assert_eq!(cursor.peek_prev(), None); + cursor.move_prev(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&mut 1)); + assert_eq!(cursor.peek_prev(), Some(&mut 6)); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.current(), Some(&mut 2)); + assert_eq!(cursor.peek_next(), Some(&mut 3)); + assert_eq!(cursor.peek_prev(), Some(&mut 1)); + let mut cursor2 = cursor.as_cursor(); + assert_eq!(cursor2.current(), Some(&2)); + cursor2.move_next(); + assert_eq!(cursor2.current(), Some(&3)); + assert_eq!(cursor.current(), Some(&mut 2)); +} + +#[test] +fn test_cursor_mut_insert() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + cursor.insert_before(7); + cursor.insert_after(8); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[7, 1, 8, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + cursor.insert_before(9); + cursor.insert_after(10); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + assert_eq!(cursor.remove(), None); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.remove(), Some(7)); + cursor.move_prev(); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.remove(), Some(9)); + cursor.move_next(); + assert_eq!(cursor.remove(), Some(10)); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + let mut p: LinkedList = LinkedList::new(); + p.extend(&[100, 101, 102, 103]); + let mut q: LinkedList = LinkedList::new(); + q.extend(&[200, 201, 202, 203]); + cursor.splice_after(p); + cursor.splice_before(q); + check_links(&m); + assert_eq!( + m.iter().cloned().collect::>(), + &[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6] + ); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + let tmp = cursor.split_before(); + assert_eq!(tmp.into_iter().collect::>(), &[]); + let mut cursor = m.cursor_mut(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + let tmp = cursor.split_after(); + assert_eq!(tmp.into_iter().collect::>(), &[102, 103, 8, 2, 3, 4, 5, 6]); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[200, 201, 202, 203, 1, 100, 101]); +} From ed039e8f8443a84dddfda8be7379ca7b4aaeccd9 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 11 Jan 2020 13:19:57 -0600 Subject: [PATCH 0262/1253] restore some rustc_parse visibilities --- src/librustc_parse/parser/mod.rs | 13 +++++++++---- src/librustc_parse/parser/module.rs | 12 ++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index a1035d320b31c..1368230168e07 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -2,6 +2,7 @@ pub mod attr; mod expr; mod item; mod module; +pub use module::{ModulePath, ModulePathSuccess}; mod pat; mod path; mod ty; @@ -117,7 +118,8 @@ pub struct Parser<'a> { /// Used to determine the path to externally loaded source files. pub(super) directory: Directory<'a>, /// `true` to parse sub-modules in other files. - pub(super) recurse_into_file_modules: bool, + // Public for rustfmt usage. + pub recurse_into_file_modules: bool, /// Name of the root module this parser originated from. If `None`, then the /// name is not known. This does not change while the parser is descending /// into modules, and sub-parsers have new values for this name. @@ -126,7 +128,8 @@ pub struct Parser<'a> { token_cursor: TokenCursor, desugar_doc_comments: bool, /// `true` we should configure out of line modules as we parse. - cfg_mods: bool, + // Public for rustfmt usage. + pub cfg_mods: bool, /// This field is used to keep track of how many left angle brackets we have seen. This is /// required in order to detect extra leading left angle brackets (`<` characters) and error /// appropriately. @@ -483,7 +486,8 @@ impl<'a> Parser<'a> { } } - fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { + // Public for rustfmt usage. + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.parse_ident_common(true) } @@ -540,7 +544,8 @@ impl<'a> Parser<'a> { /// If the next token is the given keyword, eats it and returns `true`. /// Otherwise, returns `false`. An expectation is also added for diagnostics purposes. - fn eat_keyword(&mut self, kw: Symbol) -> bool { + // Public for rustfmt usage. + pub fn eat_keyword(&mut self, kw: Symbol) -> bool { if self.check_keyword(kw) { self.bump(); true diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 3254ab5b46325..6ce94d3c6793c 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -14,13 +14,15 @@ use syntax::token::{self, TokenKind}; use std::path::{self, Path, PathBuf}; /// Information about the path to a module. -pub(super) struct ModulePath { +// Public for rustfmt usage. +pub struct ModulePath { name: String, path_exists: bool, pub result: Result, } -pub(super) struct ModulePathSuccess { +// Public for rustfmt usage. +pub struct ModulePathSuccess { pub path: PathBuf, pub directory_ownership: DirectoryOwnership, } @@ -177,7 +179,8 @@ impl<'a> Parser<'a> { } } - pub(super) fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option { + // Public for rustfmt usage. + pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option { if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) { let s = s.as_str(); @@ -194,7 +197,8 @@ impl<'a> Parser<'a> { } /// Returns a path to a module. - pub(super) fn default_submod_path( + // Public for rustfmt usage. + pub fn default_submod_path( id: ast::Ident, relative: Option, dir_path: &Path, From f9a57469612ba457fb7865aef944bf05d7664516 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 7 Jan 2020 14:32:37 -0500 Subject: [PATCH 0263/1253] parse extended terminfo format --- src/libterm/lib.rs | 2 +- src/libterm/terminfo/mod.rs | 4 +-- src/libterm/terminfo/parser/compiled.rs | 39 +++++++++++++++---------- src/libterm/win.rs | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index d2e3b07ab855d..2116b433fce3f 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -91,7 +91,7 @@ pub fn stderr() -> Option> { #[allow(missing_docs)] pub mod color { /// Number for a terminal color - pub type Color = u16; + pub type Color = u32; pub const BLACK: Color = 0; pub const RED: Color = 1; diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index f1adc536a3dc4..918875e792a66 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -24,7 +24,7 @@ pub struct TermInfo { /// Map of capability name to boolean value pub bools: HashMap, /// Map of capability name to numeric value - pub numbers: HashMap, + pub numbers: HashMap, /// Map of capability name to raw (unexpanded) string pub strings: HashMap>, } @@ -129,7 +129,7 @@ fn cap_for_attr(attr: Attr) -> &'static str { /// A Terminal that knows how many colors it supports, with a reference to its /// parsed Terminfo database record. pub struct TerminfoTerminal { - num_colors: u16, + num_colors: u32, out: T, ti: TermInfo, } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index d36adb72c8eef..fbc5aebdb2c6c 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -159,16 +159,16 @@ pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear", fn read_le_u16(r: &mut dyn io::Read) -> io::Result { let mut b = [0; 2]; - let mut amt = 0; - while amt < b.len() { - match r.read(&mut b[amt..])? { - 0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")), - n => amt += n, - } - } + r.read_exact(&mut b)?; Ok((b[0] as u16) | ((b[1] as u16) << 8)) } +fn read_le_u32(r: &mut dyn io::Read) -> io::Result { + let mut b = [0; 4]; + r.read_exact(&mut b)?; + Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24)) +} + fn read_byte(r: &mut dyn io::Read) -> io::Result { match r.bytes().next() { Some(s) => s, @@ -194,9 +194,12 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result false, + 0o01036 => true, + _ => return Err(format!("invalid magic number, found {:o}", magic)), + }; // According to the spec, these fields must be >= -1 where -1 means that the feature is not // supported. Using 0 instead of -1 works because we skip sections with length 0. @@ -258,11 +261,15 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result = t! { - (0..numbers_count).filter_map(|i| match read_le_u16(file) { - Ok(0xFFFF) => None, - Ok(n) => Some(Ok((nnames[i].to_string(), n))), - Err(e) => Some(Err(e)) + let numbers_map: HashMap = t! { + (0..numbers_count).filter_map(|i| { + let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) }; + + match number { + Ok(0xFFFF) => None, + Ok(n) => Some(Ok((nnames[i].to_string(), n))), + Err(e) => Some(Err(e)) + } }).collect() }; @@ -318,7 +325,7 @@ pub fn msys_terminfo() -> TermInfo { strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec()); let mut numbers = HashMap::new(); - numbers.insert("colors".to_string(), 8u16); + numbers.insert("colors".to_string(), 8); TermInfo { names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version diff --git a/src/libterm/win.rs b/src/libterm/win.rs index b6c607a30816c..c24cf9518aa25 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -89,7 +89,7 @@ fn bits_to_color(bits: u16) -> color::Color { _ => unreachable!(), }; - color | (bits & 0x8) // copy the hi-intensity bit + color | (u32::from(bits) & 0x8) // copy the hi-intensity bit } impl WinConsole { From 0e1cd59547ae7e5f62d7f948205e867d82505105 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Mon, 6 Jan 2020 19:51:01 +0100 Subject: [PATCH 0264/1253] Galloping search for binary_search_util --- .../binary_search_util/mod.rs | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/src/librustc_data_structures/binary_search_util/mod.rs index 6d1e1abbcef1d..ede5757a479de 100644 --- a/src/librustc_data_structures/binary_search_util/mod.rs +++ b/src/librustc_data_structures/binary_search_util/mod.rs @@ -14,35 +14,55 @@ where Ok(mid) => mid, Err(_) => return &[], }; + let size = data.len(); - // We get back *some* element with the given key -- so - // search backwards to find the *first* one. - // - // (It'd be more efficient to use a "galloping" search - // here, but it's not really worth it for small-ish - // amounts of data.) + // We get back *some* element with the given key -- so do + // a galloping search backwards to find the *first* one. let mut start = mid; - while start > 0 { - if key_fn(&data[start - 1]) == *key { - start -= 1; - } else { + let mut previous = mid; + let mut step = 1; + loop { + start = start.saturating_sub(step); + if start == 0 || key_fn(&data[start]) != *key { break; } + previous = start; + step *= 2; + } + step = previous - start; + while step > 1 { + let half = step / 2; + let mid = start + half; + if key_fn(&data[mid]) != *key { + start = mid; + } + step -= half; + } + // adjust by one if we have overshot + if start < size && key_fn(&data[start]) != *key { + start += 1; } // Now search forward to find the *last* one. - // - // (It'd be more efficient to use a "galloping" search - // here, but it's not really worth it for small-ish - // amounts of data.) - let mut end = mid + 1; - let max = data.len(); - while end < max { - if key_fn(&data[end]) == *key { - end += 1; - } else { + let mut end = mid; + let mut previous = mid; + let mut step = 1; + loop { + end = end.saturating_add(step).min(size); + if end == size || key_fn(&data[end]) != *key { break; } + previous = end; + step *= 2; + } + step = end - previous; + while step > 1 { + let half = step / 2; + let mid = end - half; + if key_fn(&data[mid]) != *key { + end = mid; + } + step -= half; } &data[start..end] From 7b564c67deb6f5e9d7102871d63a9ad3d7161278 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 4 Jan 2020 16:46:47 -0500 Subject: [PATCH 0265/1253] use winapi for non-stdlib Windows bindings --- Cargo.lock | 6 ++ src/bootstrap/Cargo.toml | 4 ++ src/bootstrap/job.rs | 88 +++-------------------- src/bootstrap/util.rs | 62 ++++------------ src/librustc/lib.rs | 1 - src/librustc_data_structures/Cargo.toml | 3 + src/librustc_data_structures/flock.rs | 34 +-------- src/librustc_data_structures/lib.rs | 3 - src/librustc_data_structures/profiling.rs | 46 ++++-------- src/librustc_driver/Cargo.toml | 3 + src/librustc_driver/lib.rs | 18 ++--- src/librustc_errors/Cargo.toml | 3 + src/librustc_errors/lock.rs | 27 ++----- src/librustc_interface/Cargo.toml | 3 + src/librustc_interface/util.rs | 14 ++-- src/librustc_metadata/Cargo.toml | 3 + src/librustc_metadata/dynamic_lib.rs | 33 ++++----- src/tools/compiletest/src/runtest.rs | 6 +- 18 files changed, 94 insertions(+), 263 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..0e7f91283cfaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,6 +201,7 @@ dependencies = [ "serde_json", "time", "toml", + "winapi 0.3.8", ] [[package]] @@ -3491,6 +3492,7 @@ dependencies = [ "serialize", "smallvec 1.0.0", "stable_deref_trait", + "winapi 0.3.8", ] [[package]] @@ -3518,6 +3520,7 @@ dependencies = [ "rustc_target", "serialize", "syntax", + "winapi 0.3.8", ] [[package]] @@ -3537,6 +3540,7 @@ dependencies = [ "term_size", "termcolor", "unicode-width", + "winapi 0.3.8", ] [[package]] @@ -3647,6 +3651,7 @@ dependencies = [ "smallvec 1.0.0", "syntax", "tempfile", + "winapi 0.3.8", ] [[package]] @@ -3715,6 +3720,7 @@ dependencies = [ "smallvec 1.0.0", "stable_deref_trait", "syntax", + "winapi 0.3.8", ] [[package]] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 3ab00a6e147fc..c09f58cc591a6 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -49,5 +49,9 @@ lazy_static = "1.3.0" time = "0.1" ignore = "0.4.10" +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = ["fileapi", "ioapiset", "jobapi2", "handleapi", "winioctl"] + [dev-dependencies] pretty_assertions = "0.5" diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index 57153e2ad39f4..efeb86540b7b7 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -35,84 +35,16 @@ use std::io; use std::mem; use std::ptr; -type HANDLE = *mut u8; -type BOOL = i32; -type DWORD = u32; -type LPHANDLE = *mut HANDLE; -type LPVOID = *mut u8; -type JOBOBJECTINFOCLASS = i32; -type SIZE_T = usize; -type LARGE_INTEGER = i64; -type UINT = u32; -type ULONG_PTR = usize; -type ULONGLONG = u64; - -const FALSE: BOOL = 0; -const DUPLICATE_SAME_ACCESS: DWORD = 0x2; -const PROCESS_DUP_HANDLE: DWORD = 0x40; -const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9; -const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000; -const JOB_OBJECT_LIMIT_PRIORITY_CLASS: DWORD = 0x00000020; -const SEM_FAILCRITICALERRORS: UINT = 0x0001; -const SEM_NOGPFAULTERRORBOX: UINT = 0x0002; -const BELOW_NORMAL_PRIORITY_CLASS: DWORD = 0x00004000; - -extern "system" { - fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE; - fn CloseHandle(hObject: HANDLE) -> BOOL; - fn GetCurrentProcess() -> HANDLE; - fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE; - fn DuplicateHandle( - hSourceProcessHandle: HANDLE, - hSourceHandle: HANDLE, - hTargetProcessHandle: HANDLE, - lpTargetHandle: LPHANDLE, - dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwOptions: DWORD, - ) -> BOOL; - fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL; - fn SetInformationJobObject( - hJob: HANDLE, - JobObjectInformationClass: JOBOBJECTINFOCLASS, - lpJobObjectInformation: LPVOID, - cbJobObjectInformationLength: DWORD, - ) -> BOOL; - fn SetErrorMode(mode: UINT) -> UINT; -} - -#[repr(C)] -struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION { - BasicLimitInformation: JOBOBJECT_BASIC_LIMIT_INFORMATION, - IoInfo: IO_COUNTERS, - ProcessMemoryLimit: SIZE_T, - JobMemoryLimit: SIZE_T, - PeakProcessMemoryUsed: SIZE_T, - PeakJobMemoryUsed: SIZE_T, -} - -#[repr(C)] -struct IO_COUNTERS { - ReadOperationCount: ULONGLONG, - WriteOperationCount: ULONGLONG, - OtherOperationCount: ULONGLONG, - ReadTransferCount: ULONGLONG, - WriteTransferCount: ULONGLONG, - OtherTransferCount: ULONGLONG, -} - -#[repr(C)] -struct JOBOBJECT_BASIC_LIMIT_INFORMATION { - PerProcessUserTimeLimit: LARGE_INTEGER, - PerJobUserTimeLimit: LARGE_INTEGER, - LimitFlags: DWORD, - MinimumWorkingsetSize: SIZE_T, - MaximumWorkingsetSize: SIZE_T, - ActiveProcessLimit: DWORD, - Affinity: ULONG_PTR, - PriorityClass: DWORD, - SchedulingClass: DWORD, -} +use winapi::shared::minwindef::{DWORD, FALSE, LPVOID}; +use winapi::um::errhandlingapi::SetErrorMode; +use winapi::um::handleapi::{CloseHandle, DuplicateHandle}; +use winapi::um::jobapi2::{AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject}; +use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcess}; +use winapi::um::winbase::{BELOW_NORMAL_PRIORITY_CLASS, SEM_NOGPFAULTERRORBOX}; +use winapi::um::winnt::{ + JobObjectExtendedLimitInformation, DUPLICATE_SAME_ACCESS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION, + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS, PROCESS_DUP_HANDLE, +}; pub unsafe fn setup(build: &mut Build) { // Enable the Windows Error Reporting dialog which msys disables, diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 5fd25981851d4..7d1efe4610f9c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -123,37 +123,24 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { // what can be found here: // // http://www.flexhex.com/docs/articles/hard-links.phtml - // - // Copied from std #[cfg(windows)] - #[allow(nonstandard_style)] fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> { use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; use std::ptr; - const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; - const GENERIC_WRITE: DWORD = 0x40000000; - const OPEN_EXISTING: DWORD = 3; - const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000; - const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000; - const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4; - const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003; - const FILE_SHARE_DELETE: DWORD = 0x4; - const FILE_SHARE_READ: DWORD = 0x1; - const FILE_SHARE_WRITE: DWORD = 0x2; - - type BOOL = i32; - type DWORD = u32; - type HANDLE = *mut u8; - type LPCWSTR = *const u16; - type LPDWORD = *mut DWORD; - type LPOVERLAPPED = *mut u8; - type LPSECURITY_ATTRIBUTES = *mut u8; - type LPVOID = *mut u8; - type WCHAR = u16; - type WORD = u16; - + use winapi::shared::minwindef::{DWORD, WORD}; + use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING}; + use winapi::um::handleapi::CloseHandle; + use winapi::um::ioapiset::DeviceIoControl; + use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT}; + use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT; + use winapi::um::winnt::{ + FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE, + IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR, + }; + + #[allow(non_snake_case)] #[repr(C)] struct REPARSE_MOUNTPOINT_DATA_BUFFER { ReparseTag: DWORD, @@ -165,29 +152,6 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ReparseTarget: WCHAR, } - extern "system" { - fn CreateFileW( - lpFileName: LPCWSTR, - dwDesiredAccess: DWORD, - dwShareMode: DWORD, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - dwCreationDisposition: DWORD, - dwFlagsAndAttributes: DWORD, - hTemplateFile: HANDLE, - ) -> HANDLE; - fn DeviceIoControl( - hDevice: HANDLE, - dwIoControlCode: DWORD, - lpInBuffer: LPVOID, - nInBufferSize: DWORD, - lpOutBuffer: LPVOID, - nOutBufferSize: DWORD, - lpBytesReturned: LPDWORD, - lpOverlapped: LPOVERLAPPED, - ) -> BOOL; - fn CloseHandle(hObject: HANDLE) -> BOOL; - } - fn to_u16s>(s: S) -> io::Result> { Ok(s.as_ref().encode_wide().chain(Some(0)).collect()) } @@ -212,7 +176,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ptr::null_mut(), ); - let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]; let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; let buf = &mut (*db).ReparseTarget as *mut u16; let mut i = 0; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 3c0160a04527e..30372e4af5033 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -34,7 +34,6 @@ #![feature(const_transmute)] #![feature(core_intrinsics)] #![feature(drain_filter)] -#![cfg_attr(windows, feature(libc))] #![feature(never_type)] #![feature(exhaustive_patterns)] #![feature(overlapping_marker_traits)] diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 19db9834fd48e..fb4f818c4b249 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -31,3 +31,6 @@ measureme = "0.7.1" [dependencies.parking_lot] version = "0.9" features = ["nightly"] + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["fileapi", "psapi"] } diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index e3282c5d276b0..2a0139fa90d5a 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -87,39 +87,11 @@ cfg_if! { } else if #[cfg(windows)] { use std::mem; use std::os::windows::prelude::*; - use std::os::windows::raw::HANDLE; use std::fs::{File, OpenOptions}; - use std::os::raw::{c_ulong, c_int}; - - type DWORD = c_ulong; - type BOOL = c_int; - type ULONG_PTR = usize; - - type LPOVERLAPPED = *mut OVERLAPPED; - const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002; - const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001; - - const FILE_SHARE_DELETE: DWORD = 0x4; - const FILE_SHARE_READ: DWORD = 0x1; - const FILE_SHARE_WRITE: DWORD = 0x2; - - #[repr(C)] - struct OVERLAPPED { - Internal: ULONG_PTR, - InternalHigh: ULONG_PTR, - Offset: DWORD, - OffsetHigh: DWORD, - hEvent: HANDLE, - } - extern "system" { - fn LockFileEx(hFile: HANDLE, - dwFlags: DWORD, - dwReserved: DWORD, - nNumberOfBytesToLockLow: DWORD, - nNumberOfBytesToLockHigh: DWORD, - lpOverlapped: LPOVERLAPPED) -> BOOL; - } + use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK}; + use winapi::um::fileapi::LockFileEx; + use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; #[derive(Debug)] pub struct Lock { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 51a38a7d2ab9c..6db2910bca496 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -33,9 +33,6 @@ extern crate libc; #[macro_use] extern crate cfg_if; -#[cfg(windows)] -extern crate libc; - pub use rustc_serialize::hex::ToHex; #[inline(never)] diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 8deb43d50f938..004db0a79a880 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -569,39 +569,19 @@ fn get_resident() -> Option { #[cfg(windows)] fn get_resident() -> Option { - type BOOL = i32; - type DWORD = u32; - type HANDLE = *mut u8; - use libc::size_t; - #[repr(C)] - #[allow(non_snake_case)] - struct PROCESS_MEMORY_COUNTERS { - cb: DWORD, - PageFaultCount: DWORD, - PeakWorkingSetSize: size_t, - WorkingSetSize: size_t, - QuotaPeakPagedPoolUsage: size_t, - QuotaPagedPoolUsage: size_t, - QuotaPeakNonPagedPoolUsage: size_t, - QuotaNonPagedPoolUsage: size_t, - PagefileUsage: size_t, - PeakPagefileUsage: size_t, - } - #[allow(non_camel_case_types)] - type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS; - #[link(name = "psapi")] - extern "system" { - fn GetCurrentProcess() -> HANDLE; - fn GetProcessMemoryInfo( - Process: HANDLE, - ppsmemCounters: PPROCESS_MEMORY_COUNTERS, - cb: DWORD, - ) -> BOOL; - } - let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { std::mem::zeroed() }; - pmc.cb = std::mem::size_of_val(&pmc) as DWORD; - match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } { + use std::mem::{self, MaybeUninit}; + use winapi::shared::minwindef::DWORD; + use winapi::um::processthreadsapi::GetCurrentProcess; + use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}; + + let mut pmc = MaybeUninit::::uninit(); + match unsafe { + GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD) + } { 0 => None, - _ => Some(pmc.WorkingSetSize as usize), + _ => { + let pmc = unsafe { pmc.assume_init() }; + Some(pmc.WorkingSetSize as usize) + } } } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 37449f9402eff..b856e5da5a093 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -32,5 +32,8 @@ rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } + [features] llvm = ['rustc_interface/llvm'] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3d31f240a34e0..5aba824e32c7a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -515,15 +515,10 @@ fn stdout_isatty() -> bool { #[cfg(windows)] fn stdout_isatty() -> bool { - type DWORD = u32; - type BOOL = i32; - type HANDLE = *mut u8; - type LPDWORD = *mut u32; - const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; - extern "system" { - fn GetStdHandle(which: DWORD) -> HANDLE; - fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; - } + use winapi::um::consoleapi::GetConsoleMode; + use winapi::um::processenv::GetStdHandle; + use winapi::um::winbase::STD_OUTPUT_HANDLE; + unsafe { let handle = GetStdHandle(STD_OUTPUT_HANDLE); let mut out = 0; @@ -1215,11 +1210,8 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { #[cfg(windows)] unsafe { if env::var("RUSTC_BREAK_ON_ICE").is_ok() { - extern "system" { - fn DebugBreak(); - } // Trigger a debugger if we crashed during bootstrap - DebugBreak(); + winapi::um::debugapi::DebugBreak(); } } } diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 0d0989677c585..01ea80659d6b9 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -19,3 +19,6 @@ atty = "0.2" termcolor = "1.0" annotate-snippets = "0.6.1" term_size = "0.3.1" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] } diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs index 198a9c12406e5..a73472021d412 100644 --- a/src/librustc_errors/lock.rs +++ b/src/librustc_errors/lock.rs @@ -12,31 +12,14 @@ use std::any::Any; #[cfg(windows)] -#[allow(nonstandard_style)] pub fn acquire_global_lock(name: &str) -> Box { use std::ffi::CString; use std::io; - type LPSECURITY_ATTRIBUTES = *mut u8; - type BOOL = i32; - type LPCSTR = *const u8; - type HANDLE = *mut u8; - type DWORD = u32; - - const INFINITE: DWORD = !0; - const WAIT_OBJECT_0: DWORD = 0; - const WAIT_ABANDONED: DWORD = 0x00000080; - - extern "system" { - fn CreateMutexA( - lpMutexAttributes: LPSECURITY_ATTRIBUTES, - bInitialOwner: BOOL, - lpName: LPCSTR, - ) -> HANDLE; - fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; - fn ReleaseMutex(hMutex: HANDLE) -> BOOL; - fn CloseHandle(hObject: HANDLE) -> BOOL; - } + use winapi::shared::ntdef::HANDLE; + use winapi::um::handleapi::CloseHandle; + use winapi::um::synchapi::{CreateMutexA, ReleaseMutex, WaitForSingleObject}; + use winapi::um::winbase::{INFINITE, WAIT_ABANDONED, WAIT_OBJECT_0}; struct Handle(HANDLE); @@ -65,7 +48,7 @@ pub fn acquire_global_lock(name: &str) -> Box { // // This will silently create one if it doesn't already exist, or it'll // open up a handle to one if it already exists. - let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr() as *const u8); + let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr()); if mutex.is_null() { panic!( "failed to create global mutex named `{}`: {}", diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index eb0551c606548..548985c451408 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -42,6 +42,9 @@ rustc_resolve = { path = "../librustc_resolve" } tempfile = "3.0.5" once_cell = "1" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi"] } + [dev-dependencies] rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 2fafd3af7a5ff..21f9fa4816591 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -340,19 +340,17 @@ fn sysroot_candidates() -> Vec { fn current_dll_path() -> Option { use std::ffi::OsString; use std::os::windows::prelude::*; + use std::ptr; - extern "system" { - fn GetModuleHandleExW(dwFlags: u32, lpModuleName: usize, phModule: *mut usize) -> i32; - fn GetModuleFileNameW(hModule: usize, lpFilename: *mut u16, nSize: u32) -> u32; - } - - const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 0x00000004; + use winapi::um::libloaderapi::{ + GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + }; unsafe { - let mut module = 0; + let mut module = ptr::null_mut(); let r = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - current_dll_path as usize, + current_dll_path as usize as *mut _, &mut module, ); if r == 0 { diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 48767c377a94c..0a0bcb190bea7 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -27,3 +27,6 @@ rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } rustc_span = { path = "../librustc_span" } rustc_error_codes = { path = "../librustc_error_codes" } + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] } diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index fa4983d8a815e..f04d0239d4923 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -111,9 +111,9 @@ mod dl { ) -> Result<*mut u8, String> { check_for_errors_in(|| libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8) } + pub(super) unsafe fn close(handle: *mut u8) { libc::dlclose(handle as *mut libc::c_void); - () } } @@ -124,27 +124,15 @@ mod dl { use std::os::windows::prelude::*; use std::ptr; - use libc::{c_char, c_uint, c_void}; - - type DWORD = u32; - type HMODULE = *mut u8; - type BOOL = i32; - type LPCWSTR = *const u16; - type LPCSTR = *const i8; - - extern "system" { - fn SetThreadErrorMode(dwNewMode: DWORD, lpOldMode: *mut DWORD) -> c_uint; - fn LoadLibraryW(name: LPCWSTR) -> HMODULE; - fn GetModuleHandleExW(dwFlags: DWORD, name: LPCWSTR, handle: *mut HMODULE) -> BOOL; - fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void; - fn FreeLibrary(handle: HMODULE) -> BOOL; - } + use winapi::shared::minwindef::HMODULE; + use winapi::um::errhandlingapi::SetThreadErrorMode; + use winapi::um::libloaderapi::{FreeLibrary, GetModuleHandleExW, GetProcAddress, LoadLibraryW}; + use winapi::um::winbase::SEM_FAILCRITICALERRORS; pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { // disable "dll load failed" error dialog. let prev_error_mode = unsafe { - // SEM_FAILCRITICALERRORS 0x01 - let new_error_mode = 1; + let new_error_mode = SEM_FAILCRITICALERRORS; let mut prev_error_mode = 0; let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode); if result == 0 { @@ -156,12 +144,12 @@ mod dl { let result = match filename { Some(filename) => { let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect(); - let result = unsafe { LoadLibraryW(filename_str.as_ptr()) }; + let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8; ptr_result(result) } None => { let mut handle = ptr::null_mut(); - let succeeded = unsafe { GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle) }; + let succeeded = unsafe { GetModuleHandleExW(0, ptr::null(), &mut handle) }; if succeeded == 0 { Err(io::Error::last_os_error().to_string()) } else { @@ -177,7 +165,10 @@ mod dl { result } - pub(super) unsafe fn symbol(handle: *mut u8, symbol: *const c_char) -> Result<*mut u8, String> { + pub(super) unsafe fn symbol( + handle: *mut u8, + symbol: *const libc::c_char, + ) -> Result<*mut u8, String> { let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8; ptr_result(ptr) } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1912c9ef5baeb..3a114a0b71517 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -42,10 +42,8 @@ mod tests; #[cfg(windows)] fn disable_error_reporting R, R>(f: F) -> R { use std::sync::Mutex; - const SEM_NOGPFAULTERRORBOX: u32 = 0x0002; - extern "system" { - fn SetErrorMode(mode: u32) -> u32; - } + use winapi::um::errhandlingapi::SetErrorMode; + use winapi::um::winbase::SEM_NOGPFAULTERRORBOX; lazy_static! { static ref LOCK: Mutex<()> = { Mutex::new(()) }; From b4fddf0f0806662430b42cb5b226ac1e3d381026 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 15:55:12 +1300 Subject: [PATCH 0266/1253] Forbid elided lifetimes within const generic parameter types. --- src/librustc_ast_lowering/lib.rs | 14 ++++--- .../const-param-elided-lifetime.rs | 19 +++++++++ .../const-param-elided-lifetime.stderr | 40 +++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/const-generics/const-param-elided-lifetime.rs create mode 100644 src/test/ui/const-generics/const-param-elided-lifetime.stderr diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 58b8e8a089ad3..9775871a11bfe 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -2121,12 +2121,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(param.ident), kind) } - GenericParamKind::Const { ref ty } => ( - hir::ParamName::Plain(param.ident), - hir::GenericParamKind::Const { - ty: self.lower_ty(&ty, ImplTraitContext::disallowed()), - }, - ), + GenericParamKind::Const { ref ty } => { + let ty = self + .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| { + this.lower_ty(&ty, ImplTraitContext::disallowed()) + }); + + (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty }) + } }; hir::GenericParam { diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs new file mode 100644 index 0000000000000..ff98368bca280 --- /dev/null +++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct A; +//~^ ERROR `&` without an explicit lifetime name cannot be used here +trait B {} + +impl A { //~ ERROR `&` without an explicit lifetime name cannot be used here + fn foo(&self) {} + //~^ ERROR `&` without an explicit lifetime name cannot be used here +} + +impl B for A {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here + +fn bar() {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.stderr new file mode 100644 index 0000000000000..9f29dbf980a47 --- /dev/null +++ b/src/test/ui/const-generics/const-param-elided-lifetime.stderr @@ -0,0 +1,40 @@ +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:4:19 + | +LL | struct A; + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:8:15 + | +LL | impl A { + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:9:21 + | +LL | fn foo(&self) {} + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:13:15 + | +LL | impl B for A {} + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:16:17 + | +LL | fn bar() {} + | ^ explicit lifetime name needed here + +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-elided-lifetime.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 5 previous errors + From 9e46ddc7a2c1bcef52bfa9e4ae547b296814e2b9 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 17:32:50 +1300 Subject: [PATCH 0267/1253] Added comment about behaviour. --- src/test/ui/const-generics/const-param-elided-lifetime.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs index ff98368bca280..5679dd35c307a 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.rs +++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs @@ -1,3 +1,8 @@ +// Elided lifetimes within the type of a const generic parameters is disallowed. This matches the +// behaviour of trait bounds where `fn foo>() {}` is illegal. Though we could change +// elided lifetimes within the type of a const generic parameters to be 'static, like elided +// lifetimes within const/static items. + #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash From 091ba6daa0a0a528b5d9fc816529a9bb25503960 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sun, 12 Jan 2020 13:15:00 +0800 Subject: [PATCH 0268/1253] Address review comments. --- src/liballoc/collections/linked_list.rs | 233 ++++++++++++------ src/liballoc/collections/linked_list/tests.rs | 11 +- 2 files changed, 161 insertions(+), 83 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d0ad1ec283942..3524c6e9817e1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -251,8 +251,8 @@ impl LinkedList { &mut self, existing_prev: Option>>, existing_next: Option>>, - splice_start: NonNull>, - splice_end: NonNull>, + mut splice_start: NonNull>, + mut splice_end: NonNull>, splice_length: usize, ) { // This method takes care not to create multiple mutable references to whole nodes at the same time, @@ -267,9 +267,7 @@ impl LinkedList { } else { self.tail = Some(splice_end); } - let mut splice_start = splice_start; splice_start.as_mut().prev = existing_prev; - let mut splice_end = splice_end; splice_end.as_mut().next = existing_next; self.len += splice_length; @@ -289,6 +287,41 @@ impl LinkedList { } } + #[inline] + unsafe fn split_off_before_node( + &mut self, + split_node: Option>>, + at: usize, + ) -> Self { + // The split node is the new head node of the second part + if let Some(mut split_node) = split_node { + let first_part_head; + let first_part_tail; + first_part_tail = split_node.as_mut().prev.take(); + if let Some(mut tail) = first_part_tail { + tail.as_mut().next = None; + first_part_head = self.head; + } else { + first_part_head = None; + } + + let first_part = LinkedList { + head: first_part_head, + tail: first_part_tail, + len: at, + marker: PhantomData, + }; + + // Fix the head ptr of the second part + self.head = Some(split_node); + self.len = self.len - at; + + first_part + } else { + mem::replace(self, LinkedList::new()) + } + } + #[inline] unsafe fn split_off_after_node( &mut self, @@ -1082,16 +1115,13 @@ impl IterMut<'_, T> { /// A cursor over a `LinkedList`. /// -/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can -/// safely mutate the list during iteration. This is because the lifetime of its yielded -/// references is tied to its own lifetime, instead of just the underlying list. This means -/// cursors cannot yield multiple elements at once. +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth. /// /// Cursors always rest between two elements in the list, and index in a logically circular way. /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. /// -/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct Cursor<'a, T: 'a> { index: usize, @@ -1117,7 +1147,7 @@ impl fmt::Debug for Cursor<'_, T> { /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. /// -/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct CursorMut<'a, T: 'a> { index: usize, @@ -1133,8 +1163,11 @@ impl fmt::Debug for CursorMut<'_, T> { } impl<'a, T> Cursor<'a, T> { - /// Move to the subsequent element of the list if it exists or the empty - /// element + /// Moves the cursor to the next element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_next(&mut self) { match self.current.take() { @@ -1152,7 +1185,11 @@ impl<'a, T> Cursor<'a, T> { } } - /// Move to the previous element of the list + /// Moves the cursor to the previous element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_prev(&mut self) { match self.current.take() { @@ -1169,13 +1206,21 @@ impl<'a, T> Cursor<'a, T> { } } - /// Get the current element + /// Returns a reference to the element that the cursor is currently + /// pointing to. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&self) -> Option<&'a T> { unsafe { self.current.map(|current| &(*current.as_ptr()).element) } } - /// Get the next element + /// Returns a reference to the next element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&self) -> Option<&'a T> { unsafe { @@ -1187,7 +1232,11 @@ impl<'a, T> Cursor<'a, T> { } } - /// Get the previous element + /// Returns a reference to the previous element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&self) -> Option<&'a T> { unsafe { @@ -1201,8 +1250,11 @@ impl<'a, T> Cursor<'a, T> { } impl<'a, T> CursorMut<'a, T> { - /// Move to the subsequent element of the list if it exists or the empty - /// element + /// Moves the cursor to the next element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_next(&mut self) { match self.current.take() { @@ -1220,7 +1272,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Move to the previous element of the list + /// Moves the cursor to the previous element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_prev(&mut self) { match self.current.take() { @@ -1237,13 +1293,21 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get the current element + /// Returns a reference to the element that the cursor is currently + /// pointing to. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&mut self) -> Option<&mut T> { unsafe { self.current.map(|current| &mut (*current.as_ptr()).element) } } - /// Get the next element + /// Returns a reference to the next element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&mut self) -> Option<&mut T> { unsafe { @@ -1255,7 +1319,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get the previous element + /// Returns a reference to the previous element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&mut self) -> Option<&mut T> { unsafe { @@ -1267,7 +1335,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get an immutable cursor at the current element + /// Returns a read-only cursor pointing to the current element. + /// + /// The lifetime of the returned `Cursor` is bound to that of the + /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the + /// `CursorMut` is frozen for the lifetime of the `Cursor`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn as_cursor<'cm>(&'cm self) -> Cursor<'cm, T> { Cursor { list: self.list, current: self.current, index: self.index } @@ -1277,56 +1349,65 @@ impl<'a, T> CursorMut<'a, T> { // Now the list editing operations impl<'a, T> CursorMut<'a, T> { - /// Insert `item` after the cursor + /// Inserts a new element into the `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new element is + /// inserted at the front of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { unsafe { let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); - let (node, node_next) = match self.current { - None => (None, self.list.head), - Some(node) => { - let node_next = node.as_ref().next; - (Some(node), node_next) - } + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, }; - self.list.splice_nodes(node, node_next, spliced_node, spliced_node, 1); + self.list.splice_nodes(self.current, node_next, spliced_node, spliced_node, 1); if self.current.is_none() { - // The ghost element's index has increased by 1. - self.index += 1; + // The "ghost" non-element's index has changed. + self.index = self.list.len; } } } - /// Insert `item` before the cursor + /// Inserts a new element into the `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new element is + /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { unsafe { let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); - let (node_prev, node) = match self.current { - None => (self.list.tail, None), - Some(node) => { - let node_prev = node.as_ref().prev; - (node_prev, Some(node)) - } + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, }; - self.list.splice_nodes(node_prev, node, spliced_node, spliced_node, 1); + self.list.splice_nodes(node_prev, self.current, spliced_node, spliced_node, 1); self.index += 1; } } - /// Remove and return the current item, moving the cursor to the next item + /// Removes the current element from the `LinkedList`. + /// + /// The element that was removed is returned, and the cursor is + /// moved to point to the next element in the `LinkedList`. + /// + /// If the cursor is currently pointing to the "ghost" non-element then no element + /// is removed and `None` is returned. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn remove(&mut self) -> Option { + pub fn remove_current(&mut self) -> Option { let unlinked_node = self.current?; unsafe { self.current = unlinked_node.as_ref().next; self.list.unlink_node(unlinked_node); let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); - Some((*unlinked_node).element) + Some(unlinked_node.element) } } - /// Insert `list` between the current element and the next + /// Inserts the elements from the given `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the start of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_after(&mut self, list: LinkedList) { unsafe { @@ -1334,22 +1415,22 @@ impl<'a, T> CursorMut<'a, T> { Some(parts) => parts, _ => return, }; - let (node, node_next) = match self.current { - None => (None, self.list.head), - Some(node) => { - let node_next = node.as_ref().next; - (Some(node), node_next) - } + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, }; - self.list.splice_nodes(node, node_next, splice_head, splice_tail, splice_len); + self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); if self.current.is_none() { - // The ghost element's index has increased by `splice_len`. - self.index += splice_len; + // The "ghost" non-element's index has changed. + self.index = self.list.len; } } } - /// Insert `list` between the previous element and current + /// Inserts the elements from the given `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_before(&mut self, list: LinkedList) { unsafe { @@ -1357,41 +1438,37 @@ impl<'a, T> CursorMut<'a, T> { Some(parts) => parts, _ => return, }; - let (node_prev, node) = match self.current { - None => (self.list.tail, None), - Some(node) => { - let node_prev = node.as_ref().prev; - (node_prev, Some(node)) - } + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, }; - self.list.splice_nodes(node_prev, node, splice_head, splice_tail, splice_len); + self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); self.index += splice_len; } } - /// Split the list in two after the current element - /// The returned list consists of all elements following the current one. - // note: consuming the cursor is not necessary here, but it makes sense - // given the interface + /// Splits the list into two after the current element. This will return a + /// new list consisting of everything after the cursor, with the original + /// list retaining everything before. + /// + /// If the cursor is pointing at the "ghost" non-element then the entire contents + /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_after(self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; - unsafe { - let split_off_node = self.current; - self.list.split_off_after_node(split_off_node, split_off_idx) - } + unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } - /// Split the list in two before the current element + + /// Splits the list into two before the current element. This will return a + /// new list consisting of everything before the cursor, with the original + /// list retaining everything after. + /// + /// If the cursor is pointing at the "ghost" non-element then the entire contents + /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_before(self) -> LinkedList { let split_off_idx = self.index; - unsafe { - let split_off_node = match self.current { - Some(node) => node.as_ref().prev, - None => self.list.tail, - }; - self.list.split_off_after_node(split_off_node, split_off_idx) - } + unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 51b23e23cd276..29eb1b4abd732 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -362,16 +362,16 @@ fn test_cursor_mut_insert() { assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); let mut cursor = m.cursor_mut(); cursor.move_prev(); - assert_eq!(cursor.remove(), None); + assert_eq!(cursor.remove_current(), None); cursor.move_next(); cursor.move_next(); - assert_eq!(cursor.remove(), Some(7)); + assert_eq!(cursor.remove_current(), Some(7)); cursor.move_prev(); cursor.move_prev(); cursor.move_prev(); - assert_eq!(cursor.remove(), Some(9)); + assert_eq!(cursor.remove_current(), Some(9)); cursor.move_next(); - assert_eq!(cursor.remove(), Some(10)); + assert_eq!(cursor.remove_current(), Some(10)); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); let mut cursor = m.cursor_mut(); @@ -389,7 +389,8 @@ fn test_cursor_mut_insert() { let mut cursor = m.cursor_mut(); cursor.move_prev(); let tmp = cursor.split_before(); - assert_eq!(tmp.into_iter().collect::>(), &[]); + assert_eq!(m.into_iter().collect::>(), &[]); + m = tmp; let mut cursor = m.cursor_mut(); cursor.move_next(); cursor.move_next(); From a404cfabc704971d4a9d1dca317fd9f0c325d906 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 12 Jan 2020 15:25:41 +0900 Subject: [PATCH 0269/1253] Expose `context::CheckLintNameResult` Clippy needs it --- src/librustc_lint/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 6e3382dee9aae..78e9d0f14f2de 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -76,7 +76,7 @@ use unused::*; /// Useful for other parts of the compiler / Clippy. pub use builtin::SoftLints; -pub use context::{EarlyContext, LateContext, LintContext, LintStore}; +pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; pub use early::check_ast_crate; pub use late::check_crate; pub use passes::{EarlyLintPass, LateLintPass}; From 82b90bd9938fb56452b8a10bd004ad84a0f81503 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 20:41:03 +1300 Subject: [PATCH 0270/1253] Update test benchmark file --- .../const-param-elided-lifetime.stderr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.stderr index 9f29dbf980a47..93133c507fe40 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.stderr +++ b/src/test/ui/const-generics/const-param-elided-lifetime.stderr @@ -1,35 +1,35 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:4:19 + --> $DIR/const-param-elided-lifetime.rs:9:19 | LL | struct A; | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:8:15 + --> $DIR/const-param-elided-lifetime.rs:13:15 | LL | impl A { | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:9:21 + --> $DIR/const-param-elided-lifetime.rs:14:21 | LL | fn foo(&self) {} | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:13:15 + --> $DIR/const-param-elided-lifetime.rs:18:15 | LL | impl B for A {} | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:16:17 + --> $DIR/const-param-elided-lifetime.rs:21:17 | LL | fn bar() {} | ^ explicit lifetime name needed here warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-param-elided-lifetime.rs:1:12 + --> $DIR/const-param-elided-lifetime.rs:6:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ From b3589292515b811400463409b5fd5afea2aef03b Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 5 Jan 2020 15:46:44 +0000 Subject: [PATCH 0271/1253] Split `rustc_mir::{build, hair, lints}` into their own crate --- Cargo.lock | 24 +- src/librustc/mir/mod.rs | 225 +----------------- src/librustc/mir/query.rs | 223 +++++++++++++++++ src/librustc/query/mod.rs | 9 + src/librustc/ty/query/keys.rs | 2 +- src/librustc_interface/Cargo.toml | 1 + src/librustc_interface/passes.rs | 2 + src/librustc_mir/Cargo.toml | 1 - src/librustc_mir/const_eval.rs | 29 ++- src/librustc_mir/lib.rs | 8 +- src/librustc_mir/transform/mod.rs | 11 +- src/librustc_mir_build/Cargo.toml | 28 +++ .../build/block.rs | 2 +- .../build/cfg.rs | 22 +- .../build/expr/as_constant.rs | 2 +- .../build/expr/as_operand.rs | 4 +- .../build/expr/as_place.rs | 12 +- .../build/expr/as_rvalue.rs | 4 +- .../build/expr/as_temp.rs | 2 +- .../build/expr/category.rs | 6 +- .../build/expr/into.rs | 2 +- .../build/expr/mod.rs | 0 .../build/expr/stmt.rs | 2 +- .../build/into.rs | 7 +- .../build/matches/mod.rs | 18 +- .../build/matches/simplify.rs | 2 +- .../build/matches/test.rs | 10 +- .../build/matches/util.rs | 8 +- .../build/misc.rs | 16 +- .../build/mod.rs | 14 +- .../build/scope.rs | 44 ++-- .../hair/constant.rs | 0 .../hair/cx/block.rs | 2 +- .../hair/cx/expr.rs | 6 +- .../hair/cx/mod.rs | 56 ++--- .../hair/cx/to_ref.rs | 2 +- .../hair/mod.rs | 92 +++---- .../hair/pattern/_match.rs | 62 +++-- .../hair/pattern/check_match.rs | 19 +- .../hair/pattern/const_to_pat.rs | 53 +++-- .../hair/pattern/mod.rs | 82 +++---- .../hair/util.rs | 0 src/librustc_mir_build/lib.rs | 26 ++ .../lints.rs | 4 +- src/test/ui/pattern/const-pat-ice.stderr | 2 +- 45 files changed, 621 insertions(+), 525 deletions(-) create mode 100644 src/librustc/mir/query.rs create mode 100644 src/librustc_mir_build/Cargo.toml rename src/{librustc_mir => librustc_mir_build}/build/block.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/cfg.rs (80%) rename src/{librustc_mir => librustc_mir_build}/build/expr/as_constant.rs (95%) rename src/{librustc_mir => librustc_mir_build}/build/expr/as_operand.rs (95%) rename src/{librustc_mir => librustc_mir_build}/build/expr/as_place.rs (98%) rename src/{librustc_mir => librustc_mir_build}/build/expr/as_rvalue.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/expr/as_temp.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/expr/category.rs (96%) rename src/{librustc_mir => librustc_mir_build}/build/expr/into.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/expr/mod.rs (100%) rename src/{librustc_mir => librustc_mir_build}/build/expr/stmt.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/into.rs (90%) rename src/{librustc_mir => librustc_mir_build}/build/matches/mod.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/matches/simplify.rs (98%) rename src/{librustc_mir => librustc_mir_build}/build/matches/test.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/matches/util.rs (94%) rename src/{librustc_mir => librustc_mir_build}/build/misc.rs (81%) rename src/{librustc_mir => librustc_mir_build}/build/mod.rs (99%) rename src/{librustc_mir => librustc_mir_build}/build/scope.rs (98%) rename src/{librustc_mir => librustc_mir_build}/hair/constant.rs (100%) rename src/{librustc_mir => librustc_mir_build}/hair/cx/block.rs (99%) rename src/{librustc_mir => librustc_mir_build}/hair/cx/expr.rs (99%) rename src/{librustc_mir => librustc_mir_build}/hair/cx/mod.rs (77%) rename src/{librustc_mir => librustc_mir_build}/hair/cx/to_ref.rs (98%) rename src/{librustc_mir => librustc_mir_build}/hair/mod.rs (86%) rename src/{librustc_mir => librustc_mir_build}/hair/pattern/_match.rs (98%) rename src/{librustc_mir => librustc_mir_build}/hair/pattern/check_match.rs (97%) rename src/{librustc_mir => librustc_mir_build}/hair/pattern/const_to_pat.rs (87%) rename src/{librustc_mir => librustc_mir_build}/hair/pattern/mod.rs (96%) rename src/{librustc_mir => librustc_mir_build}/hair/util.rs (100%) create mode 100644 src/librustc_mir_build/lib.rs rename src/{librustc_mir => librustc_mir_build}/lints.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..38e7f7c9fe92e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3633,6 +3633,7 @@ dependencies = [ "rustc_lint", "rustc_metadata", "rustc_mir", + "rustc_mir_build", "rustc_parse", "rustc_passes", "rustc_plugin_impl", @@ -3721,7 +3722,6 @@ dependencies = [ name = "rustc_mir" version = "0.0.0" dependencies = [ - "arena", "either", "graphviz", "itertools 0.8.0", @@ -3744,6 +3744,28 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_mir_build" +version = "0.0.0" +dependencies = [ + "arena", + "itertools 0.8.0", + "log", + "rustc", + "rustc_apfloat", + "rustc_data_structures", + "rustc_error_codes", + "rustc_errors", + "rustc_hir", + "rustc_index", + "rustc_macros", + "rustc_span", + "rustc_target", + "serialize", + "smallvec 1.0.0", + "syntax", +] + [[package]] name = "rustc_parse" version = "0.0.0" diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 281cf46bdc2dc..ccd2a968ded4c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! MIR datatypes and passes. See the [rustc guide] for more info. //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html @@ -23,14 +21,12 @@ use polonius_engine::Atom; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::{self, GraphSuccessors}; -use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::BitMatrix; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_serialize::{Decodable, Encodable}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; -use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::Index; @@ -39,13 +35,15 @@ use std::{iter, mem, option, u32}; pub use syntax::ast::Mutability; use syntax::ast::Name; -pub use crate::mir::cache::{BodyAndCache, ReadOnlyBodyAndCache}; -pub use crate::mir::interpret::AssertMessage; +pub use self::cache::{BodyAndCache, ReadOnlyBodyAndCache}; +pub use self::interpret::AssertMessage; +pub use self::query::*; pub use crate::read_only; mod cache; pub mod interpret; pub mod mono; +mod query; pub mod tcx; pub mod traversal; pub mod visit; @@ -2581,221 +2579,6 @@ impl Location { } } -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] -pub enum UnsafetyViolationKind { - General, - /// Permitted both in `const fn`s and regular `fn`s. - GeneralAndConstFn, - BorrowPacked(hir::HirId), -} - -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] -pub struct UnsafetyViolation { - pub source_info: SourceInfo, - pub description: Symbol, - pub details: Symbol, - pub kind: UnsafetyViolationKind, -} - -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub struct UnsafetyCheckResult { - /// Violations that are propagated *upwards* from this function. - pub violations: Lrc<[UnsafetyViolation]>, - /// `unsafe` blocks in this function, along with whether they are used. This is - /// used for the "unused_unsafe" lint. - pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>, -} - -rustc_index::newtype_index! { - pub struct GeneratorSavedLocal { - derive [HashStable] - DEBUG_FORMAT = "_{}", - } -} - -/// The layout of generator state. -#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct GeneratorLayout<'tcx> { - /// The type of every local stored inside the generator. - pub field_tys: IndexVec>, - - /// Which of the above fields are in each variant. Note that one field may - /// be stored in multiple variants. - pub variant_fields: IndexVec>, - - /// Which saved locals are storage-live at the same time. Locals that do not - /// have conflicts with each other are allowed to overlap in the computed - /// layout. - pub storage_conflicts: BitMatrix, -} - -#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub struct BorrowCheckResult<'tcx> { - pub closure_requirements: Option>, - pub used_mut_upvars: SmallVec<[Field; 8]>, -} - -/// The result of the `mir_const_qualif` query. -/// -/// Each field corresponds to an implementer of the `Qualif` trait in -/// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each -/// `Qualif`. -#[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)] -pub struct ConstQualifs { - pub has_mut_interior: bool, - pub needs_drop: bool, -} - -/// After we borrow check a closure, we are left with various -/// requirements that we have inferred between the free regions that -/// appear in the closure's signature or on its field types. These -/// requirements are then verified and proved by the closure's -/// creating function. This struct encodes those requirements. -/// -/// The requirements are listed as being between various -/// `RegionVid`. The 0th region refers to `'static`; subsequent region -/// vids refer to the free regions that appear in the closure (or -/// generator's) type, in order of appearance. (This numbering is -/// actually defined by the `UniversalRegions` struct in the NLL -/// region checker. See for example -/// `UniversalRegions::closure_mapping`.) Note that we treat the free -/// regions in the closure's type "as if" they were erased, so their -/// precise identity is not important, only their position. -/// -/// Example: If type check produces a closure with the closure substs: -/// -/// ```text -/// ClosureSubsts = [ -/// i8, // the "closure kind" -/// for<'x> fn(&'a &'x u32) -> &'x u32, // the "closure signature" -/// &'a String, // some upvar -/// ] -/// ``` -/// -/// here, there is one unique free region (`'a`) but it appears -/// twice. We would "renumber" each occurrence to a unique vid, as follows: -/// -/// ```text -/// ClosureSubsts = [ -/// i8, // the "closure kind" -/// for<'x> fn(&'1 &'x u32) -> &'x u32, // the "closure signature" -/// &'2 String, // some upvar -/// ] -/// ``` -/// -/// Now the code might impose a requirement like `'1: '2`. When an -/// instance of the closure is created, the corresponding free regions -/// can be extracted from its type and constrained to have the given -/// outlives relationship. -/// -/// In some cases, we have to record outlives requirements between -/// types and regions as well. In that case, if those types include -/// any regions, those regions are recorded as `ReClosureBound` -/// instances assigned one of these same indices. Those regions will -/// be substituted away by the creator. We use `ReClosureBound` in -/// that case because the regions must be allocated in the global -/// `TyCtxt`, and hence we cannot use `ReVar` (which is what we use -/// internally within the rest of the NLL code). -#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub struct ClosureRegionRequirements<'tcx> { - /// The number of external regions defined on the closure. In our - /// example above, it would be 3 -- one for `'static`, then `'1` - /// and `'2`. This is just used for a sanity check later on, to - /// make sure that the number of regions we see at the callsite - /// matches. - pub num_external_vids: usize, - - /// Requirements between the various free regions defined in - /// indices. - pub outlives_requirements: Vec>, -} - -/// Indicates an outlives-constraint between a type or between two -/// free regions declared on the closure. -#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub struct ClosureOutlivesRequirement<'tcx> { - // This region or type ... - pub subject: ClosureOutlivesSubject<'tcx>, - - // ... must outlive this one. - pub outlived_free_region: ty::RegionVid, - - // If not, report an error here ... - pub blame_span: Span, - - // ... due to this reason. - pub category: ConstraintCategory, -} - -/// Outlives-constraints can be categorized to determine whether and why they -/// are interesting (for error reporting). Order of variants indicates sort -/// order of the category, thereby influencing diagnostic output. -/// -/// See also [rustc_mir::borrow_check::nll::constraints]. -#[derive( - Copy, - Clone, - Debug, - Eq, - PartialEq, - PartialOrd, - Ord, - Hash, - RustcEncodable, - RustcDecodable, - HashStable -)] -pub enum ConstraintCategory { - Return, - Yield, - UseAsConst, - UseAsStatic, - TypeAnnotation, - Cast, - - /// A constraint that came from checking the body of a closure. - /// - /// We try to get the category that the closure used when reporting this. - ClosureBounds, - CallArgument, - CopyBound, - SizedBound, - Assignment, - OpaqueType, - - /// A "boring" constraint (caused by the given location) is one that - /// the user probably doesn't want to see described in diagnostics, - /// because it is kind of an artifact of the type system setup. - /// Example: `x = Foo { field: y }` technically creates - /// intermediate regions representing the "type of `Foo { field: y - /// }`", and data flows from `y` into those variables, but they - /// are not very interesting. The assignment into `x` on the other - /// hand might be. - Boring, - // Boring and applicable everywhere. - BoringNoLocation, - - /// A constraint that doesn't correspond to anything the user sees. - Internal, -} - -/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing -/// that must outlive some region. -#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub enum ClosureOutlivesSubject<'tcx> { - /// Subject is a type, typically a type parameter, but could also - /// be a projection. Indicates a requirement like `T: 'a` being - /// passed to the caller, where the type here is `T`. - /// - /// The type here is guaranteed not to contain any free regions at - /// present. - Ty(Ty<'tcx>), - - /// Subject is a free region from the closure. Indicates a requirement - /// like `'a: 'b` being passed to the caller; the region here is `'a`. - Region(ty::RegionVid), -} - /* * `TypeFoldable` implementations for MIR types */ diff --git a/src/librustc/mir/query.rs b/src/librustc/mir/query.rs new file mode 100644 index 0000000000000..34f58ab89b107 --- /dev/null +++ b/src/librustc/mir/query.rs @@ -0,0 +1,223 @@ +//! Values computed by queries that use MIR. + +use crate::ty::{self, Ty}; +use rustc_data_structures::sync::Lrc; +use rustc_hir as hir; +use rustc_index::bit_set::BitMatrix; +use rustc_index::vec::IndexVec; +use rustc_span::{Span, Symbol}; +use rustc_target::abi::VariantIdx; +use smallvec::SmallVec; + +use super::{Field, SourceInfo}; + +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] +pub enum UnsafetyViolationKind { + General, + /// Permitted both in `const fn`s and regular `fn`s. + GeneralAndConstFn, + BorrowPacked(hir::HirId), +} + +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)] +pub struct UnsafetyViolation { + pub source_info: SourceInfo, + pub description: Symbol, + pub details: Symbol, + pub kind: UnsafetyViolationKind, +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub struct UnsafetyCheckResult { + /// Violations that are propagated *upwards* from this function. + pub violations: Lrc<[UnsafetyViolation]>, + /// `unsafe` blocks in this function, along with whether they are used. This is + /// used for the "unused_unsafe" lint. + pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>, +} + +rustc_index::newtype_index! { + pub struct GeneratorSavedLocal { + derive [HashStable] + DEBUG_FORMAT = "_{}", + } +} + +/// The layout of generator state. +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct GeneratorLayout<'tcx> { + /// The type of every local stored inside the generator. + pub field_tys: IndexVec>, + + /// Which of the above fields are in each variant. Note that one field may + /// be stored in multiple variants. + pub variant_fields: IndexVec>, + + /// Which saved locals are storage-live at the same time. Locals that do not + /// have conflicts with each other are allowed to overlap in the computed + /// layout. + pub storage_conflicts: BitMatrix, +} + +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] +pub struct BorrowCheckResult<'tcx> { + pub closure_requirements: Option>, + pub used_mut_upvars: SmallVec<[Field; 8]>, +} + +/// The result of the `mir_const_qualif` query. +/// +/// Each field corresponds to an implementer of the `Qualif` trait in +/// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each +/// `Qualif`. +#[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)] +pub struct ConstQualifs { + pub has_mut_interior: bool, + pub needs_drop: bool, +} + +/// After we borrow check a closure, we are left with various +/// requirements that we have inferred between the free regions that +/// appear in the closure's signature or on its field types. These +/// requirements are then verified and proved by the closure's +/// creating function. This struct encodes those requirements. +/// +/// The requirements are listed as being between various +/// `RegionVid`. The 0th region refers to `'static`; subsequent region +/// vids refer to the free regions that appear in the closure (or +/// generator's) type, in order of appearance. (This numbering is +/// actually defined by the `UniversalRegions` struct in the NLL +/// region checker. See for example +/// `UniversalRegions::closure_mapping`.) Note that we treat the free +/// regions in the closure's type "as if" they were erased, so their +/// precise identity is not important, only their position. +/// +/// Example: If type check produces a closure with the closure substs: +/// +/// ```text +/// ClosureSubsts = [ +/// i8, // the "closure kind" +/// for<'x> fn(&'a &'x u32) -> &'x u32, // the "closure signature" +/// &'a String, // some upvar +/// ] +/// ``` +/// +/// here, there is one unique free region (`'a`) but it appears +/// twice. We would "renumber" each occurrence to a unique vid, as follows: +/// +/// ```text +/// ClosureSubsts = [ +/// i8, // the "closure kind" +/// for<'x> fn(&'1 &'x u32) -> &'x u32, // the "closure signature" +/// &'2 String, // some upvar +/// ] +/// ``` +/// +/// Now the code might impose a requirement like `'1: '2`. When an +/// instance of the closure is created, the corresponding free regions +/// can be extracted from its type and constrained to have the given +/// outlives relationship. +/// +/// In some cases, we have to record outlives requirements between +/// types and regions as well. In that case, if those types include +/// any regions, those regions are recorded as `ReClosureBound` +/// instances assigned one of these same indices. Those regions will +/// be substituted away by the creator. We use `ReClosureBound` in +/// that case because the regions must be allocated in the global +/// `TyCtxt`, and hence we cannot use `ReVar` (which is what we use +/// internally within the rest of the NLL code). +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] +pub struct ClosureRegionRequirements<'tcx> { + /// The number of external regions defined on the closure. In our + /// example above, it would be 3 -- one for `'static`, then `'1` + /// and `'2`. This is just used for a sanity check later on, to + /// make sure that the number of regions we see at the callsite + /// matches. + pub num_external_vids: usize, + + /// Requirements between the various free regions defined in + /// indices. + pub outlives_requirements: Vec>, +} + +/// Indicates an outlives-constraint between a type or between two +/// free regions declared on the closure. +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] +pub struct ClosureOutlivesRequirement<'tcx> { + // This region or type ... + pub subject: ClosureOutlivesSubject<'tcx>, + + // ... must outlive this one. + pub outlived_free_region: ty::RegionVid, + + // If not, report an error here ... + pub blame_span: Span, + + // ... due to this reason. + pub category: ConstraintCategory, +} + +/// Outlives-constraints can be categorized to determine whether and why they +/// are interesting (for error reporting). Order of variants indicates sort +/// order of the category, thereby influencing diagnostic output. +/// +/// See also [rustc_mir::borrow_check::nll::constraints]. +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] +pub enum ConstraintCategory { + Return, + Yield, + UseAsConst, + UseAsStatic, + TypeAnnotation, + Cast, + + /// A constraint that came from checking the body of a closure. + /// + /// We try to get the category that the closure used when reporting this. + ClosureBounds, + CallArgument, + CopyBound, + SizedBound, + Assignment, + OpaqueType, + + /// A "boring" constraint (caused by the given location) is one that + /// the user probably doesn't want to see described in diagnostics, + /// because it is kind of an artifact of the type system setup. + /// Example: `x = Foo { field: y }` technically creates + /// intermediate regions representing the "type of `Foo { field: y + /// }`", and data flows from `y` into those variables, but they + /// are not very interesting. The assignment into `x` on the other + /// hand might be. + Boring, + // Boring and applicable everywhere. + BoringNoLocation, + + /// A constraint that doesn't correspond to anything the user sees. + Internal, +} + +/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing +/// that must outlive some region. +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] +pub enum ClosureOutlivesSubject<'tcx> { + /// Subject is a type, typically a type parameter, but could also + /// be a projection. Indicates a requirement like `T: 'a` being + /// passed to the caller, where the type here is `T`. + /// + /// The type here is guaranteed not to contain any free regions at + /// present. + Ty(Ty<'tcx>), + + /// Subject is a free region from the closure. Indicates a requirement + /// like `'a: 'b` being passed to the caller; the region here is `'a`. + Region(ty::RegionVid), +} + +/// The constituent parts of an ADT or array. +#[derive(Copy, Clone, Debug, HashStable)] +pub struct DestructuredConst<'tcx> { + pub variant: VariantIdx, + pub fields: &'tcx [&'tcx ty::Const<'tcx>], +} diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 9de46f86200e1..a35b55ff129ce 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -505,6 +505,15 @@ rustc_queries! { desc { "extract field of const" } } + /// Destructure a constant ADT or array into its variant indent and its + /// field values. + query destructure_const( + key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>> + ) -> mir::DestructuredConst<'tcx> { + no_force + desc { "destructure constant" } + } + query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> &'tcx ty::Const<'tcx> { no_force desc { "get a &core::panic::Location referring to a span" } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 8a713e3b6a096..d64f27d9cc26c 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -142,7 +142,7 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> { } } -impl<'tcx> Key for ty::Const<'tcx> { +impl<'tcx> Key for &'tcx ty::Const<'tcx> { fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index eb0551c606548..98f7def7e36cb 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -32,6 +32,7 @@ rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true } rustc_hir = { path = "../librustc_hir" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } +rustc_mir_build = { path = "../librustc_mir_build" } rustc_passes = { path = "../librustc_passes" } rustc_typeck = { path = "../librustc_typeck" } rustc_lint = { path = "../librustc_lint" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..f40ad93e6797a 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -28,6 +28,7 @@ use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_incremental; use rustc_mir as mir; +use rustc_mir_build as mir_build; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; @@ -670,6 +671,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { plugin::build::provide(providers); rustc::hir::provide(providers); mir::provide(providers); + mir_build::provide(providers); rustc_privacy::provide(providers); typeck::provide(providers); ty::provide(providers); diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 9b6908dbbe789..f9b61b9e2c9d8 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -10,7 +10,6 @@ path = "lib.rs" doctest = false [dependencies] -arena = { path = "../libarena" } either = "1.5.0" dot = { path = "../libgraphviz", package = "graphviz" } itertools = "0.8" diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index eb89553b77036..aa7be3d80e1dc 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -61,15 +61,32 @@ pub(crate) fn const_caller_location<'tcx>( tcx.mk_const(loc_const) } -// this function uses `unwrap` copiously, because an already validated constant must have valid -// fields and can thus never fail outside of compiler bugs -pub(crate) fn const_variant_index<'tcx>( +// this function uses `unwrap` copiously, because an already validated constant +// must have valid fields and can thus never fail outside of compiler bugs +pub(crate) fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, val: &'tcx ty::Const<'tcx>, -) -> VariantIdx { - trace!("const_variant_index: {:?}", val); +) -> mir::DestructuredConst<'tcx> { + trace!("destructure_const: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); let op = ecx.eval_const_to_op(val, None).unwrap(); - ecx.read_discriminant(op).unwrap().1 + + let variant = ecx.read_discriminant(op).unwrap().1; + + let field_count = match val.ty.kind { + ty::Array(_, len) => len.eval_usize(tcx, param_env), + ty::Adt(def, _) => def.variants[variant].fields.len() as u64, + ty::Tuple(substs) => substs.len() as u64, + _ => bug!("cannot destructure constant {:?}", val), + }; + + let down = ecx.operand_downcast(op, variant).unwrap(); + let fields_iter = (0..field_count).map(|i| { + let field_op = ecx.operand_field(down, i).unwrap(); + op_to_const(&ecx, field_op) + }); + let fields = tcx.arena.alloc_from_iter(fields_iter); + + mir::DestructuredConst { variant, fields } } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index d2565bf9c63d4..1ff529181f705 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -36,12 +36,9 @@ extern crate log; extern crate rustc; mod borrow_check; -mod build; pub mod const_eval; pub mod dataflow; -mod hair; pub mod interpret; -mod lints; pub mod monomorphize; mod shim; pub mod transform; @@ -57,10 +54,13 @@ pub fn provide(providers: &mut Providers<'_>) { monomorphize::partitioning::provide(providers); providers.const_eval_validated = const_eval::const_eval_validated_provider; providers.const_eval_raw = const_eval::const_eval_raw_provider; - providers.check_match = hair::pattern::check_match; providers.const_caller_location = const_eval::const_caller_location; providers.const_field = |tcx, param_env_and_value| { let (param_env, (value, field)) = param_env_and_value.into_parts(); const_eval::const_field(tcx, param_env, None, field, value) }; + providers.destructure_const = |tcx, param_env_and_value| { + let (param_env, value) = param_env_and_value.into_parts(); + const_eval::destructure_const(tcx, param_env, value) + } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index a2f76042ea72b..22aed9a9e66bd 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,4 +1,4 @@ -use crate::{build, shim}; +use crate::{shim, util}; use rustc::hir::map::Map; use rustc::mir::{BodyAndCache, ConstQualifs, MirPhase, Promoted}; use rustc::ty::query::Providers; @@ -41,7 +41,6 @@ pub(crate) fn provide(providers: &mut Providers<'_>) { self::check_unsafety::provide(providers); *providers = Providers { mir_keys, - mir_built, mir_const, mir_const_qualif, mir_validated, @@ -98,11 +97,6 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { tcx.arena.alloc(set) } -fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { - let mir = build::mir_build(tcx, def_id); - tcx.alloc_steal_mir(mir) -} - /// Where a specific `mir::Body` comes from. #[derive(Debug, Copy, Clone)] pub struct MirSource<'tcx> { @@ -222,6 +216,9 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { let _ = tcx.unsafety_check_result(def_id); let mut body = tcx.mir_built(def_id).steal(); + + util::dump_mir(tcx, None, "mir_map", &0, MirSource::item(def_id), &body, |_, _| Ok(())); + run_passes( tcx, &mut body, diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml new file mode 100644 index 0000000000000..79c7303275597 --- /dev/null +++ b/src/librustc_mir_build/Cargo.toml @@ -0,0 +1,28 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_mir_build" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_mir_build" +path = "lib.rs" +doctest = false + +[dependencies] +arena = { path = "../libarena" } +itertools = "0.8" +log = "0.4" +rustc = { path = "../librustc" } +rustc_apfloat = { path = "../librustc_apfloat" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } +rustc_errors = { path = "../librustc_errors" } +rustc_hir = { path = "../librustc_hir" } +rustc_macros = { path = "../librustc_macros" } +rustc_serialize = { path = "../libserialize", package = "serialize" } +rustc_span = { path = "../librustc_span" } +rustc_target = { path = "../librustc_target" } +syntax = { path = "../libsyntax" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir_build/build/block.rs similarity index 99% rename from src/librustc_mir/build/block.rs rename to src/librustc_mir_build/build/block.rs index 2e133a035ee76..c517d3113c659 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir_build/build/block.rs @@ -7,7 +7,7 @@ use rustc_hir as hir; use rustc_span::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn ast_block( + crate fn ast_block( &mut self, destination: &Place<'tcx>, block: BasicBlock, diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs similarity index 80% rename from src/librustc_mir/build/cfg.rs rename to src/librustc_mir_build/build/cfg.rs index 553701c91eead..e1971102832b5 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir_build/build/cfg.rs @@ -4,33 +4,33 @@ use crate::build::CFG; use rustc::mir::*; impl<'tcx> CFG<'tcx> { - pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { + crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { &self.basic_blocks[blk] } - pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> { + crate fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> { &mut self.basic_blocks[blk] } // llvm.org/PR32488 makes this function use an excess of stack space. Mark // it as #[inline(never)] to keep rustc's stack use in check. #[inline(never)] - pub fn start_new_block(&mut self) -> BasicBlock { + crate fn start_new_block(&mut self) -> BasicBlock { self.basic_blocks.push(BasicBlockData::new(None)) } - pub fn start_new_cleanup_block(&mut self) -> BasicBlock { + crate fn start_new_cleanup_block(&mut self) -> BasicBlock { let bb = self.start_new_block(); self.block_data_mut(bb).is_cleanup = true; bb } - pub fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) { + crate fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) { debug!("push({:?}, {:?})", block, statement); self.block_data_mut(block).statements.push(statement); } - pub fn push_assign( + crate fn push_assign( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -43,7 +43,7 @@ impl<'tcx> CFG<'tcx> { ); } - pub fn push_assign_constant( + crate fn push_assign_constant( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -53,7 +53,7 @@ impl<'tcx> CFG<'tcx> { self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant))); } - pub fn push_assign_unit( + crate fn push_assign_unit( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -67,7 +67,7 @@ impl<'tcx> CFG<'tcx> { ); } - pub fn push_fake_read( + crate fn push_fake_read( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -79,7 +79,7 @@ impl<'tcx> CFG<'tcx> { self.push(block, stmt); } - pub fn terminate( + crate fn terminate( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -96,7 +96,7 @@ impl<'tcx> CFG<'tcx> { } /// In the `origin` block, push a `goto -> target` terminator. - pub fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) { + crate fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) { self.terminate(origin, source_info, TerminatorKind::Goto { target }) } } diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir_build/build/expr/as_constant.rs similarity index 95% rename from src/librustc_mir/build/expr/as_constant.rs rename to src/librustc_mir_build/build/expr/as_constant.rs index ceac2a0cd030f..e4856262975e7 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir_build/build/expr/as_constant.rs @@ -8,7 +8,7 @@ use rustc::ty::CanonicalUserTypeAnnotation; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! - pub fn as_constant(&mut self, expr: M) -> Constant<'tcx> + crate fn as_constant(&mut self, expr: M) -> Constant<'tcx> where M: Mirror<'tcx, Output = Expr<'tcx>>, { diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir_build/build/expr/as_operand.rs similarity index 95% rename from src/librustc_mir/build/expr/as_operand.rs rename to src/librustc_mir_build/build/expr/as_operand.rs index b969932a73646..efe328d2b3c1e 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir_build/build/expr/as_operand.rs @@ -13,7 +13,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// The operand returned from this function will *not be valid* after /// an ExprKind::Scope is passed, so please do *not* return it from /// functions to avoid bad miscompiles. - pub fn as_local_operand(&mut self, block: BasicBlock, expr: M) -> BlockAnd> + crate fn as_local_operand(&mut self, block: BasicBlock, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>>, { @@ -27,7 +27,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// this time. /// /// The operand is known to be live until the end of `scope`. - pub fn as_operand( + crate fn as_operand( &mut self, block: BasicBlock, scope: Option, diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir_build/build/expr/as_place.rs similarity index 98% rename from src/librustc_mir/build/expr/as_place.rs rename to src/librustc_mir_build/build/expr/as_place.rs index eb2e87f4a2d41..fd6882fa19fdf 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir_build/build/expr/as_place.rs @@ -24,7 +24,7 @@ struct PlaceBuilder<'tcx> { projection: Vec>, } -impl PlaceBuilder<'tcx> { +impl<'tcx> PlaceBuilder<'tcx> { fn into_place(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { Place { local: self.local, projection: tcx.intern_place_elems(&self.projection) } } @@ -47,7 +47,7 @@ impl PlaceBuilder<'tcx> { } } -impl From for PlaceBuilder<'tcx> { +impl<'tcx> From for PlaceBuilder<'tcx> { fn from(local: Local) -> Self { Self { local, projection: Vec::new() } } @@ -66,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Extra care is needed if any user code is allowed to run between calling /// this method and using it, as is the case for `match` and index /// expressions. - pub fn as_place(&mut self, mut block: BasicBlock, expr: M) -> BlockAnd> + crate fn as_place(&mut self, mut block: BasicBlock, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>>, { @@ -89,7 +89,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// place. The place itself may or may not be mutable: /// * If this expr is a place expr like a.b, then we will return that place. /// * Otherwise, a temporary is created: in that event, it will be an immutable temporary. - pub fn as_read_only_place(&mut self, mut block: BasicBlock, expr: M) -> BlockAnd> + crate fn as_read_only_place( + &mut self, + mut block: BasicBlock, + expr: M, + ) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>>, { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs similarity index 99% rename from src/librustc_mir/build/expr/as_rvalue.rs rename to src/librustc_mir_build/build/expr/as_rvalue.rs index 6f7b7258b5a1a..5959b85225674 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir_build/build/expr/as_rvalue.rs @@ -18,7 +18,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// The operand returned from this function will *not be valid* after /// an ExprKind::Scope is passed, so please do *not* return it from /// functions to avoid bad miscompiles. - pub fn as_local_rvalue(&mut self, block: BasicBlock, expr: M) -> BlockAnd> + crate fn as_local_rvalue(&mut self, block: BasicBlock, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>>, { @@ -276,7 +276,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn build_binary_op( + crate fn build_binary_op( &mut self, mut block: BasicBlock, op: BinOp, diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs similarity index 99% rename from src/librustc_mir/build/expr/as_temp.rs rename to src/librustc_mir_build/build/expr/as_temp.rs index 3f711044b154f..f47987c56174c 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir_build/build/expr/as_temp.rs @@ -11,7 +11,7 @@ use rustc_span::symbol::sym; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr` into a fresh temporary. This is used when building /// up rvalues so as to freeze the value that will be consumed. - pub fn as_temp( + crate fn as_temp( &mut self, block: BasicBlock, temp_lifetime: Option, diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir_build/build/expr/category.rs similarity index 96% rename from src/librustc_mir/build/expr/category.rs rename to src/librustc_mir_build/build/expr/category.rs index b35616c11fbd0..c4d340953c925 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir_build/build/expr/category.rs @@ -1,7 +1,7 @@ use crate::hair::*; #[derive(Debug, PartialEq)] -pub enum Category { +crate enum Category { // An assignable memory location like `x`, `x.f`, `foo()[3]`, that // sort of thing. Something that could appear on the LHS of an `=` // sign. @@ -19,7 +19,7 @@ pub enum Category { // Rvalues fall into different "styles" that will determine which fn // is best suited to generate them. #[derive(Debug, PartialEq)] -pub enum RvalueFunc { +crate enum RvalueFunc { // Best generated by `into`. This is generally exprs that // cause branching, like `match`, but also includes calls. Into, @@ -31,7 +31,7 @@ pub enum RvalueFunc { /// Determines the category for a given expression. Note that scope /// and paren expressions have no category. impl Category { - pub fn of(ek: &ExprKind<'_>) -> Option { + crate fn of(ek: &ExprKind<'_>) -> Option { match *ek { ExprKind::Scope { .. } => None, diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs similarity index 99% rename from src/librustc_mir/build/expr/into.rs rename to src/librustc_mir_build/build/expr/into.rs index 2cf2b21b65ace..503dfb6ef5b61 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -14,7 +14,7 @@ use rustc_target::spec::abi::Abi; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, storing the result into `destination`, which /// is assumed to be uninitialized. - pub fn into_expr( + crate fn into_expr( &mut self, destination: &Place<'tcx>, mut block: BasicBlock, diff --git a/src/librustc_mir/build/expr/mod.rs b/src/librustc_mir_build/build/expr/mod.rs similarity index 100% rename from src/librustc_mir/build/expr/mod.rs rename to src/librustc_mir_build/build/expr/mod.rs diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir_build/build/expr/stmt.rs similarity index 99% rename from src/librustc_mir/build/expr/stmt.rs rename to src/librustc_mir_build/build/expr/stmt.rs index ff7049278ed72..fd61cb833b1bc 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir_build/build/expr/stmt.rs @@ -10,7 +10,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the /// span of that statement (including its semicolon, if any). /// The scope is used if a statement temporary must be dropped. - pub fn stmt_expr( + crate fn stmt_expr( &mut self, mut block: BasicBlock, expr: Expr<'tcx>, diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir_build/build/into.rs similarity index 90% rename from src/librustc_mir/build/into.rs rename to src/librustc_mir_build/build/into.rs index 9c3ea5f7c5619..1a2a9d2bc05fc 100644 --- a/src/librustc_mir/build/into.rs +++ b/src/librustc_mir_build/build/into.rs @@ -18,7 +18,12 @@ pub(in crate::build) trait EvalInto<'tcx> { } impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn into(&mut self, destination: &Place<'tcx>, block: BasicBlock, expr: E) -> BlockAnd<()> + crate fn into( + &mut self, + destination: &Place<'tcx>, + block: BasicBlock, + expr: E, + ) -> BlockAnd<()> where E: EvalInto<'tcx>, { diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs similarity index 99% rename from src/librustc_mir/build/matches/mod.rs rename to src/librustc_mir_build/build/matches/mod.rs index 1dcd29d923244..f9f10b55495fa 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -81,7 +81,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// * From each prebinding block to the next prebinding block. /// * From each otherwise block to the next prebinding block. - pub fn match_expr( + crate fn match_expr( &mut self, destination: &Place<'tcx>, span: Span, @@ -417,7 +417,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn place_into_pattern( + crate fn place_into_pattern( &mut self, block: BasicBlock, irrefutable_pat: Pat<'tcx>, @@ -488,7 +488,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// scope for the bindings in these patterns, if such a scope had to be /// created. NOTE: Declaring the bindings should always be done in their /// drop scope. - pub fn declare_bindings( + crate fn declare_bindings( &mut self, mut visibility_scope: Option, scope_span: Span, @@ -525,7 +525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visibility_scope } - pub fn storage_live_binding( + crate fn storage_live_binding( &mut self, block: BasicBlock, var: HirId, @@ -540,7 +540,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Place::from(local_id) } - pub fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) { + crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) { let local_id = self.var_local_id(var, for_guard); let region_scope = self.hir.region_scope_tree.var_scope(var.local_id); self.schedule_drop(span, region_scope, local_id, DropKind::Value); @@ -641,7 +641,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } #[derive(Debug)] -pub struct Candidate<'pat, 'tcx> { +crate struct Candidate<'pat, 'tcx> { // span of the original pattern that gave rise to this candidate span: Span, @@ -685,7 +685,7 @@ struct Ascription<'tcx> { } #[derive(Clone, Debug)] -pub struct MatchPair<'pat, 'tcx> { +crate struct MatchPair<'pat, 'tcx> { // this place... place: Place<'tcx>, @@ -739,7 +739,7 @@ enum TestKind<'tcx> { } #[derive(Debug)] -pub struct Test<'tcx> { +crate struct Test<'tcx> { span: Span, kind: TestKind<'tcx>, } @@ -747,7 +747,7 @@ pub struct Test<'tcx> { /// ArmHasGuard is isomorphic to a boolean flag. It indicates whether /// a match arm has a guard expression attached to it. #[derive(Copy, Clone, Debug)] -pub(crate) struct ArmHasGuard(pub bool); +crate struct ArmHasGuard(crate bool); /////////////////////////////////////////////////////////////////////////// // Main matching algorithm diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs similarity index 98% rename from src/librustc_mir/build/matches/simplify.rs rename to src/librustc_mir_build/build/matches/simplify.rs index 9dbf8989cc5aa..a5f691add65c1 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -24,7 +24,7 @@ use syntax::attr::{SignedInt, UnsignedInt}; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) { + crate fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { let match_pairs = mem::take(&mut candidate.match_pairs); diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs similarity index 99% rename from src/librustc_mir/build/matches/test.rs rename to src/librustc_mir_build/build/matches/test.rs index afdb744a43a83..31fc0d121052a 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. /// /// It is a bug to call this with a simplifiable pattern. - pub fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { + crate fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { match *match_pair.pattern.kind { PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => Test { span: match_pair.pattern.span, @@ -85,7 +85,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn add_cases_to_switch<'pat>( + crate fn add_cases_to_switch<'pat>( &mut self, test_place: &Place<'tcx>, candidate: &Candidate<'pat, 'tcx>, @@ -129,7 +129,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn add_variants_to_switch<'pat>( + crate fn add_variants_to_switch<'pat>( &mut self, test_place: &Place<'tcx>, candidate: &Candidate<'pat, 'tcx>, @@ -156,7 +156,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn perform_test( + crate fn perform_test( &mut self, block: BasicBlock, place: &Place<'tcx>, @@ -507,7 +507,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// that it *doesn't* apply. For now, we return false, indicate that the /// test does not apply to this candidate, but it might be we can get /// tighter match code if we do something a bit different. - pub fn sort_candidate<'pat>( + crate fn sort_candidate<'pat>( &mut self, test_place: &Place<'tcx>, test: &Test<'tcx>, diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir_build/build/matches/util.rs similarity index 94% rename from src/librustc_mir/build/matches/util.rs rename to src/librustc_mir_build/build/matches/util.rs index b6e643a65105b..def8d1b2fd8ba 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir_build/build/matches/util.rs @@ -8,7 +8,7 @@ use std::convert::TryInto; use std::u32; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn field_match_pairs<'pat>( + crate fn field_match_pairs<'pat>( &mut self, place: Place<'tcx>, subpatterns: &'pat [FieldPat<'tcx>], @@ -26,7 +26,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect() } - pub fn prefix_slice_suffix<'pat>( + crate fn prefix_slice_suffix<'pat>( &mut self, match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>, place: &Place<'tcx>, @@ -77,7 +77,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Creates a false edge to `imaginary_target` and a real edge to /// real_target. If `imaginary_target` is none, or is the same as the real /// target, a Goto is generated instead to simplify the generated MIR. - pub fn false_edges( + crate fn false_edges( &mut self, from_block: BasicBlock, real_target: BasicBlock, @@ -98,7 +98,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { - pub fn new(place: Place<'tcx>, pattern: &'pat Pat<'tcx>) -> MatchPair<'pat, 'tcx> { + crate fn new(place: Place<'tcx>, pattern: &'pat Pat<'tcx>) -> MatchPair<'pat, 'tcx> { MatchPair { place, pattern } } } diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir_build/build/misc.rs similarity index 81% rename from src/librustc_mir/build/misc.rs rename to src/librustc_mir_build/build/misc.rs index 7c358fef7d102..3d5145b6960f5 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir_build/build/misc.rs @@ -14,7 +14,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// N.B., **No cleanup is scheduled for this temporary.** You should /// call `schedule_drop` once the temporary is initialized. - pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { + crate fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { let temp = self.local_decls.push(LocalDecl::new_temp(ty, span)); let place = Place::from(temp); debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty); @@ -23,24 +23,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Convenience function for creating a literal operand, one /// without any user type annotation. - pub fn literal_operand(&mut self, span: Span, literal: &'tcx ty::Const<'tcx>) -> Operand<'tcx> { + crate fn literal_operand( + &mut self, + span: Span, + literal: &'tcx ty::Const<'tcx>, + ) -> Operand<'tcx> { let constant = box Constant { span, user_ty: None, literal }; Operand::Constant(constant) } - pub fn unit_rvalue(&mut self) -> Rvalue<'tcx> { + crate fn unit_rvalue(&mut self) -> Rvalue<'tcx> { Rvalue::Aggregate(box AggregateKind::Tuple, vec![]) } // Returns a zero literal operand for the appropriate type, works for // bool, char and integers. - pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { + crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { let literal = ty::Const::from_bits(self.hir.tcx(), 0, ty::ParamEnv::empty().and(ty)); self.literal_operand(span, literal) } - pub fn push_usize( + crate fn push_usize( &mut self, block: BasicBlock, source_info: SourceInfo, @@ -61,7 +65,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { temp } - pub fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> { + crate fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> { let tcx = self.hir.tcx(); let ty = place.ty(&self.local_decls, tcx).ty; if !self.hir.type_is_copy_modulo_regions(ty, DUMMY_SP) { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir_build/build/mod.rs similarity index 99% rename from src/librustc_mir/build/mod.rs rename to src/librustc_mir_build/build/mod.rs index d4813d8ab68ca..6214453e64f78 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -2,8 +2,6 @@ use crate::build; use crate::build::scope::DropKind; use crate::hair::cx::Cx; use crate::hair::{BindingMode, LintLevel, PatKind}; -use crate::transform::MirSource; -use crate::util as mir_util; use rustc::middle::lang_items; use rustc::middle::region; use rustc::mir::*; @@ -22,8 +20,12 @@ use syntax::attr::{self, UnwindAttr}; use super::lints; +crate fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::steal::Steal> { + tcx.alloc_steal_mir(mir_build(tcx, def_id)) +} + /// Construct the MIR for a given `DefId`. -pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { +fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Figure out what primary body this item has. @@ -172,8 +174,6 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { build::construct_const(cx, body_id, return_ty, return_ty_span) }; - mir_util::dump_mir(tcx, None, "mir_map", &0, MirSource::item(def_id), &body, |_, _| Ok(())); - lints::check(tcx, &body, def_id); let mut body = BodyAndCache::new(body); @@ -202,7 +202,7 @@ fn liberated_closure_env_ty( } #[derive(Debug, PartialEq, Eq)] -pub enum BlockFrame { +enum BlockFrame { /// Evaluation is currently within a statement. /// /// Examples include: @@ -461,7 +461,7 @@ struct CFG<'tcx> { } rustc_index::newtype_index! { - pub struct ScopeId { .. } + struct ScopeId { .. } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir_build/build/scope.rs similarity index 98% rename from src/librustc_mir/build/scope.rs rename to src/librustc_mir_build/build/scope.rs index 0aa9773b39a3a..d994b870853c1 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir_build/build/scope.rs @@ -123,7 +123,7 @@ struct Scope { } #[derive(Debug, Default)] -pub struct Scopes<'tcx> { +crate struct Scopes<'tcx> { scopes: Vec, /// The current set of breakable scopes. See module comment for more details. breakable_scopes: Vec>, @@ -183,7 +183,7 @@ struct BreakableScope<'tcx> { /// The target of an expression that breaks out of a scope #[derive(Clone, Copy, Debug)] -pub enum BreakableTarget { +crate enum BreakableTarget { Continue(region::Scope), Break(region::Scope), Return, @@ -371,7 +371,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ========================== // Start a breakable scope, which tracks where `continue`, `break` and // `return` should branch to. - pub fn in_breakable_scope( + crate fn in_breakable_scope( &mut self, loop_block: Option, break_block: BasicBlock, @@ -395,7 +395,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { res } - pub fn in_opt_scope( + crate fn in_opt_scope( &mut self, opt_scope: Option<(region::Scope, SourceInfo)>, f: F, @@ -418,7 +418,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. - pub fn in_scope( + crate fn in_scope( &mut self, region_scope: (region::Scope, SourceInfo), lint_level: LintLevel, @@ -463,14 +463,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// scope and call `pop_scope` afterwards. Note that these two /// calls must be paired; using `in_scope` as a convenience /// wrapper maybe preferable. - pub fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo)) { + crate fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo)) { self.scopes.push_scope(region_scope, self.source_scope); } /// Pops a scope, which should have region scope `region_scope`, /// adding any drops onto the end of `block` that are needed. /// This must match 1-to-1 with `push_scope`. - pub fn pop_scope( + crate fn pop_scope( &mut self, region_scope: (region::Scope, SourceInfo), mut block: BasicBlock, @@ -500,7 +500,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.unit() } - pub fn break_scope( + crate fn break_scope( &mut self, mut block: BasicBlock, value: Option>, @@ -535,7 +535,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Branch out of `block` to `target`, exiting all scopes up to /// and including `region_scope`. This will insert whatever drops are /// needed. See module comment for details. - pub fn exit_scope( + crate fn exit_scope( &mut self, span: Span, region_scope: region::Scope, @@ -604,7 +604,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// This path terminates in GeneratorDrop. Returns the start of the path. /// None indicates there’s no cleanup to do at this point. - pub fn generator_drop_cleanup(&mut self) -> Option { + crate fn generator_drop_cleanup(&mut self) -> Option { // Fill in the cache for unwinds self.diverge_cleanup_gen(true); @@ -656,7 +656,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Creates a new source scope, nested in the current one. - pub fn new_source_scope( + crate fn new_source_scope( &mut self, span: Span, lint_level: LintLevel, @@ -689,7 +689,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Given a span and the current source scope, make a SourceInfo. - pub fn source_info(&self, span: Span) -> SourceInfo { + crate fn source_info(&self, span: Span) -> SourceInfo { SourceInfo { span, scope: self.source_scope } } @@ -717,7 +717,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// When building statics/constants, returns `None` since /// intermediate values do not have to be dropped in that case. - pub fn local_scope(&self) -> Option { + crate fn local_scope(&self) -> Option { match self.hir.body_owner_kind { hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => // No need to free storage in this context. @@ -729,7 +729,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Schedule an abort block - this is used for some ABIs that cannot unwind - pub fn schedule_abort(&mut self) -> BasicBlock { + crate fn schedule_abort(&mut self) -> BasicBlock { let source_info = self.scopes.source_info(self.scopes.len(), self.fn_span); let abortblk = self.cfg.start_new_cleanup_block(); self.cfg.terminate(abortblk, source_info, TerminatorKind::Abort); @@ -739,7 +739,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Scheduling drops // ================ - pub fn schedule_drop_storage_and_value( + crate fn schedule_drop_storage_and_value( &mut self, span: Span, region_scope: region::Scope, @@ -754,7 +754,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// When called with `DropKind::Storage`, `place` should be a local /// with an index higher than the current `self.arg_count`. - pub fn schedule_drop( + crate fn schedule_drop( &mut self, span: Span, region_scope: region::Scope, @@ -884,7 +884,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// spurious borrow-check errors -- the problem, ironically, is /// not the `DROP(_X)` itself, but the (spurious) unwind pathways /// that it creates. See #64391 for an example. - pub fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) { + crate fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) { let scope = match self.local_scope() { None => { // if there is no local scope, operands won't be dropped anyway @@ -921,7 +921,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// This is a special case because the temporary for the condition needs to /// be dropped on both the true and the false arm. - pub fn test_bool( + crate fn test_bool( &mut self, mut block: BasicBlock, condition: Expr<'tcx>, @@ -978,7 +978,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// This path terminates in Resume. Returns the start of the path. /// See module comment for more details. - pub fn diverge_cleanup(&mut self) -> BasicBlock { + crate fn diverge_cleanup(&mut self) -> BasicBlock { self.diverge_cleanup_gen(false) } @@ -1033,7 +1033,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Utility function for *non*-scope code to build their own drops - pub fn build_drop_and_replace( + crate fn build_drop_and_replace( &mut self, block: BasicBlock, span: Span, @@ -1059,7 +1059,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Creates an Assert terminator and return the success block. /// If the boolean condition operand is not the expected value, /// a runtime panic will be caused with the given message. - pub fn assert( + crate fn assert( &mut self, block: BasicBlock, cond: Operand<'tcx>, @@ -1293,7 +1293,7 @@ fn build_diverge_scope<'tcx>( target } -fn push_storage_deads( +fn push_storage_deads<'tcx>( cfg: &mut CFG<'tcx>, target: BasicBlock, storage_deads: &mut Vec>, diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs similarity index 100% rename from src/librustc_mir/hair/constant.rs rename to src/librustc_mir_build/hair/constant.rs diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir_build/hair/cx/block.rs similarity index 99% rename from src/librustc_mir/hair/cx/block.rs rename to src/librustc_mir_build/hair/cx/block.rs index 674c1489b9b68..a883b84f8fe2f 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir_build/hair/cx/block.rs @@ -101,7 +101,7 @@ fn mirror_stmts<'a, 'tcx>( return result; } -pub fn to_expr_ref<'a, 'tcx>( +crate fn to_expr_ref<'a, 'tcx>( cx: &mut Cx<'a, 'tcx>, block: &'tcx hir::Block<'tcx>, ) -> ExprRef<'tcx> { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs similarity index 99% rename from src/librustc_mir/hair/cx/expr.rs rename to src/librustc_mir_build/hair/cx/expr.rs index 471e09fc03b28..97e718118292d 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -577,8 +577,8 @@ fn make_mirror_unadjusted<'a, 'tcx>( Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind } } -fn user_substs_applied_to_res( - cx: &mut Cx<'a, 'tcx>, +fn user_substs_applied_to_res<'tcx>( + cx: &mut Cx<'_, 'tcx>, hir_id: hir::HirId, res: Res, ) -> Option> { @@ -775,7 +775,7 @@ fn convert_path_expr<'a, 'tcx>( } } -fn convert_var( +fn convert_var<'tcx>( cx: &mut Cx<'_, 'tcx>, expr: &'tcx hir::Expr<'tcx>, var_hir_id: hir::HirId, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs similarity index 77% rename from src/librustc_mir/hair/cx/mod.rs rename to src/librustc_mir_build/hair/cx/mod.rs index 2e5ab3343508c..5fc9a1ecad555 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir_build/hair/cx/mod.rs @@ -21,18 +21,18 @@ use syntax::ast; use syntax::attr; #[derive(Clone)] -pub struct Cx<'a, 'tcx> { +crate struct Cx<'a, 'tcx> { tcx: TyCtxt<'tcx>, infcx: &'a InferCtxt<'a, 'tcx>, - pub root_lint_level: hir::HirId, - pub param_env: ty::ParamEnv<'tcx>, + crate root_lint_level: hir::HirId, + crate param_env: ty::ParamEnv<'tcx>, /// Identity `InternalSubsts` for use with const-evaluation. - pub identity_substs: &'tcx InternalSubsts<'tcx>, + crate identity_substs: &'tcx InternalSubsts<'tcx>, - pub region_scope_tree: &'tcx region::ScopeTree, - pub tables: &'a ty::TypeckTables<'tcx>, + crate region_scope_tree: &'tcx region::ScopeTree, + crate tables: &'a ty::TypeckTables<'tcx>, /// This is `Constness::Const` if we are compiling a `static`, /// `const`, or the body of a `const fn`. @@ -42,7 +42,7 @@ pub struct Cx<'a, 'tcx> { body_owner: DefId, /// What kind of body is being compiled. - pub body_owner_kind: hir::BodyOwnerKind, + crate body_owner_kind: hir::BodyOwnerKind, /// Whether this constant/function needs overflow checks. check_overflow: bool, @@ -52,7 +52,7 @@ pub struct Cx<'a, 'tcx> { } impl<'a, 'tcx> Cx<'a, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> { + crate fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> { let tcx = infcx.tcx; let src_def_id = tcx.hir().local_def_id(src_id); let tables = tcx.typeck_tables_of(src_def_id); @@ -92,42 +92,42 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { } } - pub fn control_flow_destroyed(self) -> Vec<(Span, String)> { + crate fn control_flow_destroyed(self) -> Vec<(Span, String)> { self.control_flow_destroyed } } impl<'a, 'tcx> Cx<'a, 'tcx> { /// Normalizes `ast` into the appropriate "mirror" type. - pub fn mirror>(&mut self, ast: M) -> M::Output { + crate fn mirror>(&mut self, ast: M) -> M::Output { ast.make_mirror(self) } - pub fn usize_ty(&mut self) -> Ty<'tcx> { + crate fn usize_ty(&mut self) -> Ty<'tcx> { self.tcx.types.usize } - pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> { + crate fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> { ty::Const::from_usize(self.tcx, value) } - pub fn bool_ty(&mut self) -> Ty<'tcx> { + crate fn bool_ty(&mut self) -> Ty<'tcx> { self.tcx.types.bool } - pub fn unit_ty(&mut self) -> Ty<'tcx> { + crate fn unit_ty(&mut self) -> Ty<'tcx> { self.tcx.mk_unit() } - pub fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> { + crate fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> { ty::Const::from_bool(self.tcx, true) } - pub fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> { + crate fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> { ty::Const::from_bool(self.tcx, false) } - pub fn const_eval_literal( + crate fn const_eval_literal( &mut self, lit: &'tcx ast::LitKind, ty: Ty<'tcx>, @@ -151,15 +151,15 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { } } - pub fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { + crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, node => bug!("pattern became {:?}", node), }; - Pat::from_hir(self.tcx, self.param_env.and(self.identity_substs), self.tables(), p) + Pat::from_hir(self.tcx, self.param_env, self.tables(), p) } - pub fn trait_method( + crate fn trait_method( &mut self, trait_def_id: DefId, method_name: Symbol, @@ -168,6 +168,8 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { ) -> &'tcx ty::Const<'tcx> { let substs = self.tcx.mk_substs_trait(self_ty, params); for item in self.tcx.associated_items(trait_def_id) { + // The unhygienic comparison here is acceptable because this is only + // used on known traits. if item.kind == ty::AssocKind::Method && item.ident.name == method_name { let method_ty = self.tcx.type_of(item.def_id); let method_ty = method_ty.subst(self.tcx, substs); @@ -178,32 +180,32 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { bug!("found no method `{}` in `{:?}`", method_name, trait_def_id); } - pub fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec { + crate fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec { (0..adt_def.variants[variant_index].fields.len()).map(Field::new).collect() } - pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool { + crate fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool { ty.needs_drop(self.tcx, self.param_env) } - pub fn tcx(&self) -> TyCtxt<'tcx> { + crate fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } - pub fn tables(&self) -> &'a ty::TypeckTables<'tcx> { + crate fn tables(&self) -> &'a ty::TypeckTables<'tcx> { self.tables } - pub fn check_overflow(&self) -> bool { + crate fn check_overflow(&self) -> bool { self.check_overflow } - pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool { + crate fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool { self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) } } -impl UserAnnotatedTyHelpers<'tcx> for Cx<'_, 'tcx> { +impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx() } diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir_build/hair/cx/to_ref.rs similarity index 98% rename from src/librustc_mir/hair/cx/to_ref.rs rename to src/librustc_mir_build/hair/cx/to_ref.rs index d6859e356eef3..6cf8122e200db 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir_build/hair/cx/to_ref.rs @@ -2,7 +2,7 @@ use crate::hair::*; use rustc_hir as hir; -pub trait ToRef { +crate trait ToRef { type Output; fn to_ref(self) -> Self::Output; } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs similarity index 86% rename from src/librustc_mir/hair/mod.rs rename to src/librustc_mir_build/hair/mod.rs index cde91cc36cab2..3257f282dc1cb 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -17,33 +17,33 @@ use rustc_hir::def_id::DefId; use rustc_span::Span; mod constant; -pub mod cx; +crate mod cx; -pub mod pattern; -pub(crate) use self::pattern::PatTyProj; -pub use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; +crate mod pattern; +crate use self::pattern::PatTyProj; +crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; mod util; #[derive(Copy, Clone, Debug)] -pub enum LintLevel { +crate enum LintLevel { Inherited, Explicit(hir::HirId), } #[derive(Clone, Debug)] -pub struct Block<'tcx> { - pub targeted_by_break: bool, - pub region_scope: region::Scope, - pub opt_destruction_scope: Option, - pub span: Span, - pub stmts: Vec>, - pub expr: Option>, - pub safety_mode: BlockSafety, +crate struct Block<'tcx> { + crate targeted_by_break: bool, + crate region_scope: region::Scope, + crate opt_destruction_scope: Option, + crate span: Span, + crate stmts: Vec>, + crate expr: Option>, + crate safety_mode: BlockSafety, } #[derive(Copy, Clone, Debug)] -pub enum BlockSafety { +crate enum BlockSafety { Safe, ExplicitUnsafe(hir::HirId), PushUnsafe, @@ -51,18 +51,18 @@ pub enum BlockSafety { } #[derive(Clone, Debug)] -pub enum StmtRef<'tcx> { +crate enum StmtRef<'tcx> { Mirror(Box>), } #[derive(Clone, Debug)] -pub struct Stmt<'tcx> { - pub kind: StmtKind<'tcx>, - pub opt_destruction_scope: Option, +crate struct Stmt<'tcx> { + crate kind: StmtKind<'tcx>, + crate opt_destruction_scope: Option, } #[derive(Clone, Debug)] -pub enum StmtKind<'tcx> { +crate enum StmtKind<'tcx> { Expr { /// scope for this statement; may be used as lifetime of temporaries scope: region::Scope, @@ -112,23 +112,23 @@ rustc_data_structures::static_assert_size!(Expr<'_>, 168); /// example, method calls and overloaded operators are absent: they are /// expected to be converted into `Expr::Call` instances. #[derive(Clone, Debug)] -pub struct Expr<'tcx> { +crate struct Expr<'tcx> { /// type of this expression - pub ty: Ty<'tcx>, + crate ty: Ty<'tcx>, /// lifetime of this expression if it should be spilled into a /// temporary; should be None only if in a constant context - pub temp_lifetime: Option, + crate temp_lifetime: Option, /// span of the expression in the source - pub span: Span, + crate span: Span, /// kind of expression - pub kind: ExprKind<'tcx>, + crate kind: ExprKind<'tcx>, } #[derive(Clone, Debug)] -pub enum ExprKind<'tcx> { +crate enum ExprKind<'tcx> { Scope { region_scope: region::Scope, lint_level: LintLevel, @@ -288,37 +288,37 @@ pub enum ExprKind<'tcx> { } #[derive(Clone, Debug)] -pub enum ExprRef<'tcx> { +crate enum ExprRef<'tcx> { Hair(&'tcx hir::Expr<'tcx>), Mirror(Box>), } #[derive(Clone, Debug)] -pub struct FieldExprRef<'tcx> { - pub name: Field, - pub expr: ExprRef<'tcx>, +crate struct FieldExprRef<'tcx> { + crate name: Field, + crate expr: ExprRef<'tcx>, } #[derive(Clone, Debug)] -pub struct FruInfo<'tcx> { - pub base: ExprRef<'tcx>, - pub field_types: Vec>, +crate struct FruInfo<'tcx> { + crate base: ExprRef<'tcx>, + crate field_types: Vec>, } #[derive(Clone, Debug)] -pub struct Arm<'tcx> { - pub pattern: Pat<'tcx>, - pub guard: Option>, - pub body: ExprRef<'tcx>, - pub lint_level: LintLevel, - pub scope: region::Scope, - pub span: Span, +crate struct Arm<'tcx> { + crate pattern: Pat<'tcx>, + crate guard: Option>, + crate body: ExprRef<'tcx>, + crate lint_level: LintLevel, + crate scope: region::Scope, + crate span: Span, } -impl Arm<'tcx> { +impl<'tcx> Arm<'tcx> { // HACK(or_patterns; Centril | dlrobertson): Remove this and // correctly handle each case in which this method is used. - pub fn top_pats_hack(&self) -> &[Pat<'tcx>] { + crate fn top_pats_hack(&self) -> &[Pat<'tcx>] { match &*self.pattern.kind { PatKind::Or { pats } => pats, _ => std::slice::from_ref(&self.pattern), @@ -327,18 +327,18 @@ impl Arm<'tcx> { } #[derive(Clone, Debug)] -pub enum Guard<'tcx> { +crate enum Guard<'tcx> { If(ExprRef<'tcx>), } #[derive(Copy, Clone, Debug)] -pub enum LogicalOp { +crate enum LogicalOp { And, Or, } impl<'tcx> ExprRef<'tcx> { - pub fn span(&self) -> Span { + crate fn span(&self) -> Span { match self { ExprRef::Hair(expr) => expr.span, ExprRef::Mirror(expr) => expr.span, @@ -361,7 +361,7 @@ impl<'tcx> ExprRef<'tcx> { /// mirrored. This allows a single AST node from the compiler to /// expand into one or more Hair nodes, which lets the Hair nodes be /// simpler. -pub trait Mirror<'tcx> { +crate trait Mirror<'tcx> { type Output; fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Self::Output; @@ -378,7 +378,7 @@ impl<'tcx> Mirror<'tcx> for Expr<'tcx> { impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> { type Output = Expr<'tcx>; - fn make_mirror(self, hir: &mut Cx<'a, 'tcx>) -> Expr<'tcx> { + fn make_mirror(self, hir: &mut Cx<'_, 'tcx>) -> Expr<'tcx> { match self { ExprRef::Hair(h) => h.make_mirror(hir), ExprRef::Mirror(m) => *m, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs similarity index 98% rename from src/librustc_mir/hair/pattern/_match.rs rename to src/librustc_mir_build/hair/pattern/_match.rs index 2bf1efd4441e9..8fcaa1e8082fb 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -230,7 +230,6 @@ use self::Usefulness::*; use self::WitnessPreference::*; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::Idx; use super::{compare_const_vals, PatternFoldable, PatternFolder}; @@ -260,7 +259,7 @@ use std::iter::{FromIterator, IntoIterator}; use std::ops::RangeInclusive; use std::u128; -pub fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pat<'tcx>) -> Pat<'tcx> { +crate fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pat<'tcx>) -> Pat<'tcx> { LiteralExpander { tcx: cx.tcx, param_env: cx.param_env }.fold_pattern(&pat) } @@ -269,7 +268,7 @@ struct LiteralExpander<'tcx> { param_env: ty::ParamEnv<'tcx>, } -impl LiteralExpander<'tcx> { +impl<'tcx> LiteralExpander<'tcx> { /// Derefs `val` and potentially unsizes the value if `crty` is an array and `rty` a slice. /// /// `crty` and `rty` can differ because you can use array constants in the presence of slice @@ -323,7 +322,7 @@ impl LiteralExpander<'tcx> { } } -impl PatternFolder<'tcx> for LiteralExpander<'tcx> { +impl<'tcx> PatternFolder<'tcx> for LiteralExpander<'tcx> { fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> { debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.kind, pat.kind); match (&pat.ty.kind, &*pat.kind) { @@ -381,10 +380,10 @@ impl<'tcx> Pat<'tcx> { /// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]` /// works well. #[derive(Debug, Clone)] -pub struct PatStack<'p, 'tcx>(SmallVec<[&'p Pat<'tcx>; 2]>); +crate struct PatStack<'p, 'tcx>(SmallVec<[&'p Pat<'tcx>; 2]>); impl<'p, 'tcx> PatStack<'p, 'tcx> { - pub fn from_pattern(pat: &'p Pat<'tcx>) -> Self { + crate fn from_pattern(pat: &'p Pat<'tcx>) -> Self { PatStack(smallvec![pat]) } @@ -472,15 +471,15 @@ impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> { /// A 2D matrix. #[derive(Clone)] -pub struct Matrix<'p, 'tcx>(Vec>); +crate struct Matrix<'p, 'tcx>(Vec>); impl<'p, 'tcx> Matrix<'p, 'tcx> { - pub fn empty() -> Self { + crate fn empty() -> Self { Matrix(vec![]) } /// Pushes a new row to the matrix. If the row starts with an or-pattern, this expands it. - pub fn push(&mut self, row: PatStack<'p, 'tcx>) { + crate fn push(&mut self, row: PatStack<'p, 'tcx>) { if let Some(rows) = row.expand_or_pat() { self.0.extend(rows); } else { @@ -569,22 +568,21 @@ impl<'p, 'tcx> FromIterator> for Matrix<'p, 'tcx> { } } -pub struct MatchCheckCtxt<'a, 'tcx> { - pub tcx: TyCtxt<'tcx>, +crate struct MatchCheckCtxt<'a, 'tcx> { + crate tcx: TyCtxt<'tcx>, /// The module in which the match occurs. This is necessary for /// checking inhabited-ness of types because whether a type is (visibly) /// inhabited can depend on whether it was defined in the current module or /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty /// outside it's module and should not be matchable with an empty match /// statement. - pub module: DefId, + crate module: DefId, param_env: ty::ParamEnv<'tcx>, - pub pattern_arena: &'a TypedArena>, - pub byte_array_map: FxHashMap<*const Pat<'tcx>, Vec<&'a Pat<'tcx>>>, + crate pattern_arena: &'a TypedArena>, } impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { - pub fn create_and_enter( + crate fn create_and_enter( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, module: DefId, @@ -595,13 +593,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { { let pattern_arena = TypedArena::default(); - f(MatchCheckCtxt { - tcx, - param_env, - module, - pattern_arena: &pattern_arena, - byte_array_map: FxHashMap::default(), - }) + f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena }) } fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { @@ -613,7 +605,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } // Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`. - pub fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { + crate fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { match ty.kind { ty::Adt(def, ..) => { def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did.is_local() @@ -773,13 +765,13 @@ impl<'tcx> Constructor<'tcx> { cx: &MatchCheckCtxt<'a, 'tcx>, adt: &'tcx ty::AdtDef, ) -> VariantIdx { - match self { - Variant(id) => adt.variant_index_with_id(*id), + match *self { + Variant(id) => adt.variant_index_with_id(id), Single => { assert!(!adt.is_enum()); VariantIdx::new(0) } - ConstantValue(c) => crate::const_eval::const_variant_index(cx.tcx, cx.param_env, c), + ConstantValue(c) => cx.tcx.destructure_const(cx.param_env.and(c)).variant, _ => bug!("bad constructor {:?} for adt {:?}", self, adt), } } @@ -1058,7 +1050,7 @@ impl<'tcx> Constructor<'tcx> { } #[derive(Clone, Debug)] -pub enum Usefulness<'tcx, 'p> { +crate enum Usefulness<'tcx, 'p> { /// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns. Useful(Vec<&'p Pat<'tcx>>), /// Carries a list of witnesses of non-exhaustiveness. @@ -1146,7 +1138,7 @@ impl<'tcx, 'p> Usefulness<'tcx, 'p> { } #[derive(Copy, Clone, Debug)] -pub enum WitnessPreference { +crate enum WitnessPreference { ConstructWitness, LeaveOutWitness, } @@ -1190,10 +1182,10 @@ struct PatCtxt<'tcx> { /// /// The final `Pair(Some(_), true)` is then the resulting witness. #[derive(Clone, Debug)] -pub struct Witness<'tcx>(Vec>); +crate struct Witness<'tcx>(Vec>); impl<'tcx> Witness<'tcx> { - pub fn single_pattern(self) -> Pat<'tcx> { + crate fn single_pattern(self) -> Pat<'tcx> { assert_eq!(self.0.len(), 1); self.0.into_iter().next().unwrap() } @@ -1358,9 +1350,9 @@ fn all_constructors<'a, 'tcx>( /// around the (offset) space: i.e., `range.lo <= range.hi`. #[derive(Clone, Debug)] struct IntRange<'tcx> { - pub range: RangeInclusive, - pub ty: Ty<'tcx>, - pub span: Span, + range: RangeInclusive, + ty: Ty<'tcx>, + span: Span, } impl<'tcx> IntRange<'tcx> { @@ -1631,7 +1623,7 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> { /// relation to preceding patterns, it is not reachable) and exhaustiveness /// checking (if a wildcard pattern is useful in relation to a matrix, the /// matrix isn't exhaustive). -pub fn is_useful<'p, 'tcx>( +crate fn is_useful<'p, 'tcx>( cx: &mut MatchCheckCtxt<'p, 'tcx>, matrix: &Matrix<'p, 'tcx>, v: &PatStack<'p, 'tcx>, @@ -2238,7 +2230,7 @@ fn split_grouped_constructors<'p, 'tcx>( split_ctors } -fn lint_overlapping_patterns( +fn lint_overlapping_patterns<'tcx>( tcx: TyCtxt<'tcx>, hir_id: Option, ctor_range: IntRange<'tcx>, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs similarity index 97% rename from src/librustc_mir/hair/pattern/check_match.rs rename to src/librustc_mir_build/hair/pattern/check_match.rs index 0e9d16cfa56a8..84d57a89c983e 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -8,7 +8,6 @@ use rustc::hir::map::Map; use rustc::lint; use rustc::session::parse::feature_err; use rustc::session::Session; -use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_error_codes::*; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder}; @@ -29,12 +28,8 @@ crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) { Some(id) => tcx.hir().body_owned_by(id), }; - let mut visitor = MatchVisitor { - tcx, - tables: tcx.body_tables(body_id), - param_env: tcx.param_env(def_id), - identity_substs: InternalSubsts::identity_for_item(tcx, def_id), - }; + let mut visitor = + MatchVisitor { tcx, tables: tcx.body_tables(body_id), param_env: tcx.param_env(def_id) }; visitor.visit_body(tcx.hir().body(body_id)); } @@ -46,7 +41,6 @@ struct MatchVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, tables: &'a ty::TypeckTables<'tcx>, param_env: ty::ParamEnv<'tcx>, - identity_substs: SubstsRef<'tcx>, } impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { @@ -153,11 +147,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { let inlined_arms: Vec<_> = arms .iter() .map(|arm| { - let mut patcx = PatCtxt::new( - self.tcx, - self.param_env.and(self.identity_substs), - self.tables, - ); + let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables); patcx.include_lint_checks(); let pattern = patcx.lower_pattern(&arm.pat); let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern)); @@ -189,8 +179,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option) { let module = self.tcx.hir().get_module_parent(pat.hir_id); MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| { - let mut patcx = - PatCtxt::new(self.tcx, self.param_env.and(self.identity_substs), self.tables); + let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables); patcx.include_lint_checks(); let pattern = patcx.lower_pattern(pat); let pattern_ty = pattern.ty; diff --git a/src/librustc_mir/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs similarity index 87% rename from src/librustc_mir/hair/pattern/const_to_pat.rs rename to src/librustc_mir_build/hair/pattern/const_to_pat.rs index 75b25f03ca27b..a21a0ee8a1b20 100644 --- a/src/librustc_mir/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs @@ -1,5 +1,3 @@ -use crate::const_eval::const_variant_index; - use rustc::infer::InferCtxt; use rustc::lint; use rustc::mir::Field; @@ -167,18 +165,14 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { let tcx = self.tcx(); let param_env = self.param_env; - let adt_subpattern = |i, variant_opt| { - let field = Field::new(i); - let val = crate::const_eval::const_field(tcx, param_env, variant_opt, field, cv); - self.recur(val) - }; - let adt_subpatterns = |n, variant_opt| { - (0..n) - .map(|i| { - let field = Field::new(i); - FieldPat { field, pattern: adt_subpattern(i, variant_opt) } + let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| { + vals.iter() + .enumerate() + .map(|(idx, val)| { + let field = Field::new(idx); + FieldPat { field, pattern: self.recur(val) } }) - .collect::>() + .collect() }; let kind = match cv.ty.kind { @@ -235,21 +229,28 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { PatKind::Wild } ty::Adt(adt_def, substs) if adt_def.is_enum() => { - let variant_index = const_variant_index(tcx, self.param_env, cv); - let subpatterns = adt_subpatterns( - adt_def.variants[variant_index].fields.len(), - Some(variant_index), - ); - PatKind::Variant { adt_def, substs, variant_index, subpatterns } + let destructured = tcx.destructure_const(param_env.and(cv)); + PatKind::Variant { + adt_def, + substs, + variant_index: destructured.variant, + subpatterns: field_pats(destructured.fields), + } + } + ty::Adt(_, _) => { + let destructured = tcx.destructure_const(param_env.and(cv)); + PatKind::Leaf { subpatterns: field_pats(destructured.fields) } } - ty::Adt(adt_def, _) => { - let struct_var = adt_def.non_enum_variant(); - PatKind::Leaf { subpatterns: adt_subpatterns(struct_var.fields.len(), None) } + ty::Tuple(_) => { + let destructured = tcx.destructure_const(param_env.and(cv)); + PatKind::Leaf { subpatterns: field_pats(destructured.fields) } } - ty::Tuple(fields) => PatKind::Leaf { subpatterns: adt_subpatterns(fields.len(), None) }, - ty::Array(_, n) => PatKind::Array { - prefix: (0..n.eval_usize(tcx, self.param_env)) - .map(|i| adt_subpattern(i as usize, None)) + ty::Array(..) => PatKind::Array { + prefix: tcx + .destructure_const(param_env.and(cv)) + .fields + .iter() + .map(|val| self.recur(val)) .collect(), slice: None, suffix: Vec::new(), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs similarity index 96% rename from src/librustc_mir/hair/pattern/mod.rs rename to src/librustc_mir_build/hair/pattern/mod.rs index c7e26c6ea4fd4..9e00c4ea53a0f 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -31,7 +31,7 @@ use std::fmt; use rustc_error_codes::*; #[derive(Clone, Debug)] -pub enum PatternError { +crate enum PatternError { AssocConstInPattern(Span), StaticInPattern(Span), FloatBug, @@ -39,22 +39,22 @@ pub enum PatternError { } #[derive(Copy, Clone, Debug)] -pub enum BindingMode { +crate enum BindingMode { ByValue, ByRef(BorrowKind), } #[derive(Clone, Debug)] -pub struct FieldPat<'tcx> { - pub field: Field, - pub pattern: Pat<'tcx>, +crate struct FieldPat<'tcx> { + crate field: Field, + crate pattern: Pat<'tcx>, } #[derive(Clone, Debug)] -pub struct Pat<'tcx> { - pub ty: Ty<'tcx>, - pub span: Span, - pub kind: Box>, +crate struct Pat<'tcx> { + crate ty: Ty<'tcx>, + crate span: Span, + crate kind: Box>, } impl<'tcx> Pat<'tcx> { @@ -64,8 +64,8 @@ impl<'tcx> Pat<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -pub struct PatTyProj<'tcx> { - pub user_ty: CanonicalUserType<'tcx>, +crate struct PatTyProj<'tcx> { + crate user_ty: CanonicalUserType<'tcx>, } impl<'tcx> PatTyProj<'tcx> { @@ -91,8 +91,8 @@ impl<'tcx> PatTyProj<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -pub struct Ascription<'tcx> { - pub user_ty: PatTyProj<'tcx>, +crate struct Ascription<'tcx> { + crate user_ty: PatTyProj<'tcx>, /// Variance to use when relating the type `user_ty` to the **type of the value being /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must /// have a type that is some subtype of the ascribed type. @@ -111,12 +111,12 @@ pub struct Ascription<'tcx> { /// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior /// of the old type-check for now. See #57280 for details. - pub variance: ty::Variance, - pub user_ty_span: Span, + crate variance: ty::Variance, + crate user_ty_span: Span, } #[derive(Clone, Debug)] -pub enum PatKind<'tcx> { +crate enum PatKind<'tcx> { Wild, AscribeUserType { @@ -184,10 +184,10 @@ pub enum PatKind<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -pub struct PatRange<'tcx> { - pub lo: &'tcx ty::Const<'tcx>, - pub hi: &'tcx ty::Const<'tcx>, - pub end: RangeEnd, +crate struct PatRange<'tcx> { + crate lo: &'tcx ty::Const<'tcx>, + crate hi: &'tcx ty::Const<'tcx>, + crate end: RangeEnd, } impl<'tcx> fmt::Display for Pat<'tcx> { @@ -342,23 +342,22 @@ impl<'tcx> fmt::Display for Pat<'tcx> { } } -pub struct PatCtxt<'a, 'tcx> { - pub tcx: TyCtxt<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, - pub tables: &'a ty::TypeckTables<'tcx>, - pub substs: SubstsRef<'tcx>, - pub errors: Vec, +crate struct PatCtxt<'a, 'tcx> { + crate tcx: TyCtxt<'tcx>, + crate param_env: ty::ParamEnv<'tcx>, + crate tables: &'a ty::TypeckTables<'tcx>, + crate errors: Vec, include_lint_checks: bool, } impl<'a, 'tcx> Pat<'tcx> { - pub fn from_hir( + crate fn from_hir( tcx: TyCtxt<'tcx>, - param_env_and_substs: ty::ParamEnvAnd<'tcx, SubstsRef<'tcx>>, + param_env: ty::ParamEnv<'tcx>, tables: &'a ty::TypeckTables<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Self { - let mut pcx = PatCtxt::new(tcx, param_env_and_substs, tables); + let mut pcx = PatCtxt::new(tcx, param_env, tables); let result = pcx.lower_pattern(pat); if !pcx.errors.is_empty() { let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors); @@ -370,27 +369,20 @@ impl<'a, 'tcx> Pat<'tcx> { } impl<'a, 'tcx> PatCtxt<'a, 'tcx> { - pub fn new( + crate fn new( tcx: TyCtxt<'tcx>, - param_env_and_substs: ty::ParamEnvAnd<'tcx, SubstsRef<'tcx>>, + param_env: ty::ParamEnv<'tcx>, tables: &'a ty::TypeckTables<'tcx>, ) -> Self { - PatCtxt { - tcx, - param_env: param_env_and_substs.param_env, - tables, - substs: param_env_and_substs.value, - errors: vec![], - include_lint_checks: false, - } + PatCtxt { tcx, param_env, tables, errors: vec![], include_lint_checks: false } } - pub fn include_lint_checks(&mut self) -> &mut Self { + crate fn include_lint_checks(&mut self) -> &mut Self { self.include_lint_checks = true; self } - pub fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> { + crate fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> { // When implicit dereferences have been inserted in this pattern, the unadjusted lowered // pattern has the type that results *after* dereferencing. For example, in this code: // @@ -863,7 +855,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } } -impl UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> { +impl<'tcx> UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -873,7 +865,7 @@ impl UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> { } } -pub trait PatternFoldable<'tcx>: Sized { +crate trait PatternFoldable<'tcx>: Sized { fn fold_with>(&self, folder: &mut F) -> Self { self.super_fold_with(folder) } @@ -881,7 +873,7 @@ pub trait PatternFoldable<'tcx>: Sized { fn super_fold_with>(&self, folder: &mut F) -> Self; } -pub trait PatternFolder<'tcx>: Sized { +crate trait PatternFolder<'tcx>: Sized { fn fold_pattern(&mut self, pattern: &Pat<'tcx>) -> Pat<'tcx> { pattern.super_fold_with(self) } @@ -1009,7 +1001,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { } } -pub fn compare_const_vals<'tcx>( +crate fn compare_const_vals<'tcx>( tcx: TyCtxt<'tcx>, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir_build/hair/util.rs similarity index 100% rename from src/librustc_mir/hair/util.rs rename to src/librustc_mir_build/hair/util.rs diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs new file mode 100644 index 0000000000000..96032a732abd6 --- /dev/null +++ b/src/librustc_mir_build/lib.rs @@ -0,0 +1,26 @@ +//! Construction of MIR from HIR. +//! +//! This crate also contains the match exhaustiveness and usefulness checking. + +#![feature(box_patterns)] +#![feature(box_syntax)] +#![feature(crate_visibility_modifier)] +#![feature(slice_patterns)] +#![feature(bool_to_option)] +#![recursion_limit = "256"] + +#[macro_use] +extern crate log; +#[macro_use] +extern crate rustc; + +mod build; +mod hair; +mod lints; + +use rustc::ty::query::Providers; + +pub fn provide(providers: &mut Providers<'_>) { + providers.check_match = hair::pattern::check_match; + providers.mir_built = build::mir_built; +} diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir_build/lints.rs similarity index 97% rename from src/librustc_mir/lints.rs rename to src/librustc_mir_build/lints.rs index a58d17569ef71..4244e1b8d80a6 100644 --- a/src/librustc_mir/lints.rs +++ b/src/librustc_mir_build/lints.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::FnKind; use rustc_index::bit_set::BitSet; -pub fn check(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) { +crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) { @@ -15,7 +15,7 @@ pub fn check(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) { } } -fn check_fn_for_unconditional_recursion( +fn check_fn_for_unconditional_recursion<'tcx>( tcx: TyCtxt<'tcx>, fn_kind: FnKind<'_>, body: &Body<'tcx>, diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 7a0f14425b746..7217fe1b02f4e 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:LL:CC +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/hair/pattern/_match.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic From d2c509a3c6b06ba02807bf94c00fad4c4a9262a5 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sun, 12 Jan 2020 18:01:24 +0800 Subject: [PATCH 0272/1253] Address review comments. --- src/liballoc/collections/linked_list.rs | 26 +++++++++++++++++-- src/liballoc/collections/linked_list/tests.rs | 9 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 3524c6e9817e1..d7504b0b80bd9 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1132,7 +1132,7 @@ pub struct Cursor<'a, T: 'a> { #[unstable(feature = "linked_list_cursors", issue = "58533")] impl fmt::Debug for Cursor<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Cursor").field(&self.list).field(&self.index).finish() + f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish() } } @@ -1158,11 +1158,21 @@ pub struct CursorMut<'a, T: 'a> { #[unstable(feature = "linked_list_cursors", issue = "58533")] impl fmt::Debug for CursorMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("CursorMut").field(&self.list).field(&self.index).finish() + f.debug_tuple("CursorMut").field(&self.list).field(&self.index()).finish() } } impl<'a, T> Cursor<'a, T> { + /// Returns the cursor position index within the `LinkedList`. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn index(&self) -> Option { + let _ = self.current?; + Some(self.index) + } + /// Moves the cursor to the next element of the `LinkedList`. /// /// If the cursor is pointing to the "ghost" non-element then this will move it to @@ -1250,6 +1260,16 @@ impl<'a, T> Cursor<'a, T> { } impl<'a, T> CursorMut<'a, T> { + /// Returns the cursor position index within the `LinkedList`. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn index(&self) -> Option { + let _ = self.current?; + Some(self.index) + } + /// Moves the cursor to the next element of the `LinkedList`. /// /// If the cursor is pointing to the "ghost" non-element then this will move it to @@ -1456,6 +1476,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_after(self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; + // no need to update `self.index` because the cursor is consumed. unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } @@ -1468,6 +1489,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_before(self) -> LinkedList { let split_off_idx = self.index; + // no need to update `self.index` because the cursor is consumed. unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 29eb1b4abd732..d223752c7f7ec 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -313,15 +313,18 @@ fn test_cursor_move_peek() { assert_eq!(cursor.current(), Some(&1)); assert_eq!(cursor.peek_next(), Some(&2)); assert_eq!(cursor.peek_prev(), None); + assert_eq!(cursor.index(), Some(0)); cursor.move_prev(); assert_eq!(cursor.current(), None); assert_eq!(cursor.peek_next(), Some(&1)); assert_eq!(cursor.peek_prev(), Some(&6)); + assert_eq!(cursor.index(), None); cursor.move_next(); cursor.move_next(); assert_eq!(cursor.current(), Some(&2)); assert_eq!(cursor.peek_next(), Some(&3)); assert_eq!(cursor.peek_prev(), Some(&1)); + assert_eq!(cursor.index(), Some(1)); let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); @@ -329,20 +332,26 @@ fn test_cursor_move_peek() { assert_eq!(cursor.current(), Some(&mut 1)); assert_eq!(cursor.peek_next(), Some(&mut 2)); assert_eq!(cursor.peek_prev(), None); + assert_eq!(cursor.index(), Some(0)); cursor.move_prev(); assert_eq!(cursor.current(), None); assert_eq!(cursor.peek_next(), Some(&mut 1)); assert_eq!(cursor.peek_prev(), Some(&mut 6)); + assert_eq!(cursor.index(), None); cursor.move_next(); cursor.move_next(); assert_eq!(cursor.current(), Some(&mut 2)); assert_eq!(cursor.peek_next(), Some(&mut 3)); assert_eq!(cursor.peek_prev(), Some(&mut 1)); + assert_eq!(cursor.index(), Some(1)); let mut cursor2 = cursor.as_cursor(); assert_eq!(cursor2.current(), Some(&2)); + assert_eq!(cursor2.index(), Some(1)); cursor2.move_next(); assert_eq!(cursor2.current(), Some(&3)); + assert_eq!(cursor2.index(), Some(2)); assert_eq!(cursor.current(), Some(&mut 2)); + assert_eq!(cursor.index(), Some(1)); } #[test] From c32090c130273787b8f9fc8290357a6a9d3222b7 Mon Sep 17 00:00:00 2001 From: Till Arnold Date: Sun, 12 Jan 2020 12:01:37 +0100 Subject: [PATCH 0273/1253] Document behavior of set_nonblocking on UnixListener --- src/libstd/sys/unix/ext/net.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index e0e6e02a443e1..4c3cb67c9ee0f 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -902,6 +902,12 @@ impl UnixListener { /// Moves the socket into or out of nonblocking mode. /// + /// This will result in the `accept` operation becoming nonblocking, + /// i.e., immediately returning from their calls. If the IO operation is + /// successful, `Ok` is returned and no further action is required. If the + /// IO operation could not be completed and needs to be retried, an error + /// with kind [`io::ErrorKind::WouldBlock`] is returned. + /// /// # Examples /// /// ```no_run @@ -913,6 +919,8 @@ impl UnixListener { /// Ok(()) /// } /// ``` + /// + /// [`io::ErrorKind::WouldBlock`]: ../../../io/enum.ErrorKind.html#variant.WouldBlock #[stable(feature = "unix_socket", since = "1.10.0")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { self.0.set_nonblocking(nonblocking) From 3ada8aeed403157f6608b2daf9a6c88908298b25 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Sun, 12 Jan 2020 15:03:37 +0100 Subject: [PATCH 0274/1253] Add more BTreeMap/BTreeSet benchmarks regarding iteration --- src/liballoc/benches/btree/map.rs | 30 ++++++++++++++++++++ src/liballoc/benches/btree/set.rs | 47 +++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs index eb5f51d9adc58..ea69769279f12 100644 --- a/src/liballoc/benches/btree/map.rs +++ b/src/liballoc/benches/btree/map.rs @@ -146,6 +146,36 @@ pub fn iter_100000(b: &mut Bencher) { bench_iter(b, 100000); } +fn bench_iter_mut(b: &mut Bencher, size: i32) { + let mut map = BTreeMap::::new(); + let mut rng = thread_rng(); + + for _ in 0..size { + map.insert(rng.gen(), rng.gen()); + } + + b.iter(|| { + for kv in map.iter_mut() { + black_box(kv); + } + }); +} + +#[bench] +pub fn iter_mut_20(b: &mut Bencher) { + bench_iter_mut(b, 20); +} + +#[bench] +pub fn iter_mut_1000(b: &mut Bencher) { + bench_iter_mut(b, 1000); +} + +#[bench] +pub fn iter_mut_100000(b: &mut Bencher) { + bench_iter_mut(b, 100000); +} + fn bench_first_and_last(b: &mut Bencher, size: i32) { let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); b.iter(|| { diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs index 18502ded308c7..d7c1d95a45205 100644 --- a/src/liballoc/benches/btree/set.rs +++ b/src/liballoc/benches/btree/set.rs @@ -14,19 +14,13 @@ fn random(n: usize) -> BTreeSet { } fn neg(n: usize) -> BTreeSet { - let mut set = BTreeSet::new(); - for i in -(n as i32)..=-1 { - set.insert(i); - } + let set: BTreeSet = (-(n as i32)..=-1).collect(); assert_eq!(set.len(), n); set } fn pos(n: usize) -> BTreeSet { - let mut set = BTreeSet::new(); - for i in 1..=(n as i32) { - set.insert(i); - } + let set: BTreeSet = (1..=(n as i32)).collect(); assert_eq!(set.len(), n); set } @@ -56,6 +50,43 @@ macro_rules! set_bench { }; } +const BUILD_SET_SIZE: usize = 100; + +#[bench] +pub fn build_and_clear(b: &mut Bencher) { + b.iter(|| pos(BUILD_SET_SIZE).clear()) +} + +#[bench] +pub fn build_and_drop(b: &mut Bencher) { + b.iter(|| pos(BUILD_SET_SIZE)) +} + +#[bench] +pub fn build_and_into_iter(b: &mut Bencher) { + b.iter(|| pos(BUILD_SET_SIZE).into_iter().count()) +} + +#[bench] +pub fn build_and_pop_all(b: &mut Bencher) { + b.iter(|| { + let mut s = pos(BUILD_SET_SIZE); + while s.pop_first().is_some() {} + s + }); +} + +#[bench] +pub fn build_and_remove_all(b: &mut Bencher) { + b.iter(|| { + let mut s = pos(BUILD_SET_SIZE); + while let Some(elt) = s.iter().copied().next() { + s.remove(&elt); + } + s + }); +} + set_bench! {intersection_100_neg_vs_100_pos, intersection, count, [neg(100), pos(100)]} set_bench! {intersection_100_neg_vs_10k_pos, intersection, count, [neg(100), pos(10_000)]} set_bench! {intersection_100_pos_vs_100_neg, intersection, count, [pos(100), neg(100)]} From 0810210bcb2c1a50d815e8e71d6db3b6cb0aba7f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:13:05 +0000 Subject: [PATCH 0275/1253] Diagnostics should start lowercase --- src/librustc/traits/error_reporting.rs | 2 +- src/librustc_ast_passes/feature_gate.rs | 2 +- src/librustc_builtin_macros/test.rs | 2 +- src/librustc_lint/builtin.rs | 14 ++--- src/librustc_mir/borrow_check/nll.rs | 4 +- src/librustc_typeck/check/cast.rs | 2 +- src/test/ui/anon-params-deprecated.stderr | 6 +-- .../validate_uninhabited_zsts.stderr | 2 +- .../feature-gate-never_type.stderr | 10 ++-- .../ui/future-incompatible-lint-group.stderr | 2 +- src/test/ui/issues/issue-45730.stderr | 6 +-- src/test/ui/lint/uninitialized-zeroed.stderr | 54 +++++++++---------- .../escape-argument-callee.stderr | 4 +- .../escape-argument.stderr | 4 +- .../escape-upvar-nested.stderr | 6 +-- .../escape-upvar-ref.stderr | 4 +- ...pagate-approximated-fail-no-postdom.stderr | 4 +- .../propagate-approximated-ref.stderr | 4 +- ...er-to-static-comparing-against-free.stderr | 8 +-- ...oximated-shorter-to-static-no-bound.stderr | 4 +- ...mated-shorter-to-static-wrong-bound.stderr | 4 +- .../propagate-approximated-val.stderr | 4 +- .../propagate-despite-same-free-region.stderr | 4 +- ...ail-to-approximate-longer-no-bounds.stderr | 4 +- ...-to-approximate-longer-wrong-bounds.stderr | 4 +- .../propagate-from-trait-match.stderr | 4 +- .../return-wrong-bound-region.stderr | 4 +- .../projection-no-regions-closure.stderr | 16 +++--- .../projection-one-region-closure.stderr | 16 +++--- ...tion-one-region-trait-bound-closure.stderr | 20 +++---- ...e-region-trait-bound-static-closure.stderr | 20 +++---- ...tion-two-region-trait-bound-closure.stderr | 32 +++++------ ...ram-closure-approximate-lower-bound.stderr | 8 +-- ...m-closure-outlives-from-return-type.stderr | 4 +- ...-closure-outlives-from-where-clause.stderr | 16 +++--- .../ui/order-dependent-cast-inference.stderr | 2 +- .../test-attrs/test-should-panic-attr.stderr | 8 +-- .../ui/traits/trait-bounds-same-crate-name.rs | 2 +- .../trait-bounds-same-crate-name.stderr | 4 +- 39 files changed, 160 insertions(+), 160 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0c9a73d78a5eb..5440cb7bdf4e5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1156,7 +1156,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_help(impl_span, "trait impl with same name found"); let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); let crate_msg = format!( - "Perhaps two different versions of crate `{}` are being used?", + "perhaps two different versions of crate `{}` are being used?", trait_crate ); err.note(&crate_msg); diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index e6f4535a38dba..1e4b1ae077762 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -413,7 +413,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { self.check_extern(bare_fn_ty.ext); } ast::TyKind::Never => { - gate_feature_post!(&self, never_type, ty.span, "The `!` type is experimental"); + gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental"); } _ => {} } diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 0eee212108e85..07715cdbcb5e9 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -325,7 +325,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { `expected = \"error message\"`", ) .note( - "Errors in this attribute were erroneously \ + "errors in this attribute were erroneously \ allowed and will become a hard error in a \ future release.", ) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 15a8332a28492..7f55bcd4017ef 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -657,7 +657,7 @@ impl EarlyLintPass for AnonymousParameters { ) .span_suggestion( arg.pat.span, - "Try naming the parameter or explicitly \ + "try naming the parameter or explicitly \ ignoring it", format!("_: {}", ty_snip), appl, @@ -1934,21 +1934,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { use rustc::ty::TyKind::*; match ty.kind { // Primitive types that don't like 0 as a value. - Ref(..) => Some((format!("References must be non-null"), None)), + Ref(..) => Some((format!("references must be non-null"), None)), Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)), - FnPtr(..) => Some((format!("Function pointers must be non-null"), None)), - Never => Some((format!("The never type (`!`) has no valid value"), None)), + FnPtr(..) => Some((format!("function pointers must be non-null"), None)), + Never => Some((format!("the `!` type has no valid value"), None)), RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => // raw ptr to dyn Trait { - Some((format!("The vtable of a wide raw pointer must be non-null"), None)) + Some((format!("the vtable of a wide raw pointer must be non-null"), None)) } // Primitive types with other constraints. Bool if init == InitKind::Uninit => { - Some((format!("Booleans must be `true` or `false`"), None)) + Some((format!("booleans must be either `true` or `false`"), None)) } Char if init == InitKind::Uninit => { - Some((format!("Characters must be a valid unicode codepoint"), None)) + Some((format!("characters must be a valid Unicode codepoint"), None)) } // Recurse and checks for some compound types. Adt(adt_def, substs) if !adt_def.is_union() => { diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 151a2c4c19a7d..73718d58346f1 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -360,7 +360,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( // better. if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "External requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -379,7 +379,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( err.buffer(errors_buffer); } else { - let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "No external requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "no external requirements"); regioncx.annotate(tcx, &mut err); err.buffer(errors_buffer); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index ba5e5fd8ac188..cbbfe2d627895 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -381,7 +381,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { if unknown_cast_to { "to" } else { "from" } ); err.note( - "The type information given here is insufficient to check whether \ + "the type information given here is insufficient to check whether \ the pointer cast is valid", ); if unknown_cast_to { diff --git a/src/test/ui/anon-params-deprecated.stderr b/src/test/ui/anon-params-deprecated.stderr index e97dbc15f9cde..8e4fa70d342f2 100644 --- a/src/test/ui/anon-params-deprecated.stderr +++ b/src/test/ui/anon-params-deprecated.stderr @@ -2,7 +2,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:9:12 | LL | fn foo(i32); - | ^^^ help: Try naming the parameter or explicitly ignoring it: `_: i32` + | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | note: lint level defined here --> $DIR/anon-params-deprecated.rs:1:9 @@ -16,7 +16,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:30 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 @@ -25,7 +25,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:38 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index bde7f2536fac1..040c568beb324 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -34,7 +34,7 @@ LL | unsafe { std::mem::transmute(()) } | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | = note: `#[warn(invalid_value)]` on by default - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value warning: the type `Empty` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:17:35 diff --git a/src/test/ui/feature-gates/feature-gate-never_type.stderr b/src/test/ui/feature-gates/feature-gate-never_type.stderr index d86ab99b82bd5..216615731e56f 100644 --- a/src/test/ui/feature-gates/feature-gate-never_type.stderr +++ b/src/test/ui/feature-gates/feature-gate-never_type.stderr @@ -1,4 +1,4 @@ -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:7:17 | LL | type Ma = (u32, !, i32); @@ -7,7 +7,7 @@ LL | type Ma = (u32, !, i32); = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:8:20 | LL | type Meeshka = Vec; @@ -16,7 +16,7 @@ LL | type Meeshka = Vec; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:9:24 | LL | type Mow = &'static fn(!) -> !; @@ -25,7 +25,7 @@ LL | type Mow = &'static fn(!) -> !; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:10:27 | LL | type Skwoz = &'static mut !; @@ -34,7 +34,7 @@ LL | type Skwoz = &'static mut !; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:13:16 | LL | type Wub = !; diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 24e3a077ae6e3..1d958e5bfeb40 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -2,7 +2,7 @@ error: anonymous parameters are deprecated and will be removed in the next editi --> $DIR/future-incompatible-lint-group.rs:4:10 | LL | fn f(u8) {} - | ^^ help: Try naming the parameter or explicitly ignoring it: `_: u8` + | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | note: lint level defined here --> $DIR/future-incompatible-lint-group.rs:1:9 diff --git a/src/test/ui/issues/issue-45730.stderr b/src/test/ui/issues/issue-45730.stderr index 3c400d6eefaa8..d4ddba52df14a 100644 --- a/src/test/ui/issues/issue-45730.stderr +++ b/src/test/ui/issues/issue-45730.stderr @@ -6,7 +6,7 @@ LL | let x: *const _ = 0 as _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:5:23 @@ -16,7 +16,7 @@ LL | let x: *const _ = 0 as *const _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:8:13 @@ -26,7 +26,7 @@ LL | let x = 0 as *const i32 as *const _ as *mut _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index bdb5959953f50..d451b827598f4 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -12,7 +12,7 @@ note: lint level defined here | LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ - = note: References must be non-null + = note: references must be non-null error: the type `&'static T` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:30:32 @@ -23,7 +23,7 @@ LL | let _val: &'static T = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `Wrap<&'static T>` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:32:38 @@ -34,7 +34,7 @@ LL | let _val: Wrap<&'static T> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -49,7 +49,7 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -64,7 +64,7 @@ LL | let _val: ! = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `!` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:41:23 @@ -75,7 +75,7 @@ LL | let _val: ! = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `(i32, !)` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:43:30 @@ -86,7 +86,7 @@ LL | let _val: (i32, !) = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `(i32, !)` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:44:30 @@ -97,7 +97,7 @@ LL | let _val: (i32, !) = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `Void` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:46:26 @@ -130,7 +130,7 @@ LL | let _val: &'static i32 = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `&'static i32` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:50:34 @@ -141,7 +141,7 @@ LL | let _val: &'static i32 = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `Ref` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:52:25 @@ -152,7 +152,7 @@ LL | let _val: Ref = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:15:12 | LL | struct Ref(&'static i32); @@ -167,7 +167,7 @@ LL | let _val: Ref = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:15:12 | LL | struct Ref(&'static i32); @@ -182,7 +182,7 @@ LL | let _val: fn() = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Function pointers must be non-null + = note: function pointers must be non-null error: the type `fn()` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:56:26 @@ -193,7 +193,7 @@ LL | let _val: fn() = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Function pointers must be non-null + = note: function pointers must be non-null error: the type `Wrap` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:58:32 @@ -204,7 +204,7 @@ LL | let _val: Wrap = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this struct field) +note: function pointers must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -219,7 +219,7 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this struct field) +note: function pointers must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -234,7 +234,7 @@ LL | let _val: WrapEnum = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this enum field) +note: function pointers must be non-null (in this enum field) --> $DIR/uninitialized-zeroed.rs:19:28 | LL | enum WrapEnum { Wrapped(T) } @@ -249,7 +249,7 @@ LL | let _val: WrapEnum = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this enum field) +note: function pointers must be non-null (in this enum field) --> $DIR/uninitialized-zeroed.rs:19:28 | LL | enum WrapEnum { Wrapped(T) } @@ -264,7 +264,7 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:16:16 | LL | struct RefPair((&'static i32, i32)); @@ -279,7 +279,7 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:16:16 | LL | struct RefPair((&'static i32, i32)); @@ -316,7 +316,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The vtable of a wide raw pointer must be non-null + = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn std::marker::Send` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:71:37 @@ -327,7 +327,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The vtable of a wide raw pointer must be non-null + = note: the vtable of a wide raw pointer must be non-null error: the type `bool` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:75:26 @@ -338,7 +338,7 @@ LL | let _val: bool = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Booleans must be `true` or `false` + = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:78:32 @@ -349,7 +349,7 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Characters must be a valid unicode codepoint (in this struct field) +note: characters must be a valid Unicode codepoint (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -375,7 +375,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `&'static [i32]` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:85:36 @@ -386,7 +386,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `std::num::NonZeroU32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:86:32 @@ -430,7 +430,7 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Booleans must be `true` or `false` + = note: booleans must be either `true` or `false` error: aborting due to 35 previous errors diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 3d79ff0b706f5..b4e18c229fdfd 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/escape-argument-callee.rs:26:38 | LL | let mut closure = expect_sig(|p, y| *p = y); @@ -18,7 +18,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | | has type `&'1 i32` | has type `&'_#2r mut &'2 i32` -note: No external requirements +note: no external requirements --> $DIR/escape-argument-callee.rs:20:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index 37f04af6378d9..533a17bdd128b 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/escape-argument.rs:26:38 | LL | let mut closure = expect_sig(|p, y| *p = y); @@ -9,7 +9,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)), ] -note: No external requirements +note: no external requirements --> $DIR/escape-argument.rs:20:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index 810c0286cf218..60d02066e2676 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/escape-upvar-nested.rs:21:32 | LL | let mut closure1 = || p = &y; @@ -13,7 +13,7 @@ LL | let mut closure1 = || p = &y; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: External requirements +note: external requirements --> $DIR/escape-upvar-nested.rs:20:27 | LL | let mut closure = || { @@ -32,7 +32,7 @@ LL | | }; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/escape-upvar-nested.rs:13:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index bf042769a00e2..f64ccf14ac482 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/escape-upvar-ref.rs:23:27 | LL | let mut closure = || p = &y; @@ -13,7 +13,7 @@ LL | let mut closure = || p = &y; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/escape-upvar-ref.rs:17:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 4e3aa352fffdb..e1e0cdc153a6c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-fail-no-postdom.rs:43:9 | LL | / |_outlives1, _outlives2, _outlives3, x, y| { @@ -27,7 +27,7 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| { LL | demand_y(x, y, p) | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-fail-no-postdom.rs:38:1 | LL | / fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index cd61b8b5e555e..b6535024a4a76 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-ref.rs:43:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-ref.rs:42:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 259140c2e5a3d..708e50de570db 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:21:15 | LL | foo(cell, |cell_a, cell_x| { @@ -23,7 +23,7 @@ LL | foo(cell, |cell_a, cell_x| { LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure | ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1 | LL | / fn case1() { @@ -37,7 +37,7 @@ LL | | } | = note: defining type: case1 -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:35:15 | LL | foo(cell, |cell_a, cell_x| { @@ -53,7 +53,7 @@ LL | | }) = note: number of external vids: 2 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1 | LL | / fn case2() { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index b3dd682e4f0b7..17d33e82ba7e3 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { @@ -19,7 +19,7 @@ LL | | }); = note: number of external vids: 4 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:31:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index ab12d08f7b74e..5dce8d087d6cd 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -19,7 +19,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:34:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index b2209e9cab0c9..5c5d510805bdf 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-val.rs:36:45 | LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-val.rs:35:1 | LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index 55ee515a3a821..c111e651832ba 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-despite-same-free-region.rs:42:9 | LL | / |_outlives1, _outlives2, x, y| { @@ -16,7 +16,7 @@ LL | | }, = note: number of external vids: 4 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-despite-same-free-region.rs:39:1 | LL | / fn supply<'a>(cell_a: Cell<&'a u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 1c29af8c42210..52df46ed3453f 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:35:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { @@ -27,7 +27,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index afa0e9f619ddc..0270cc40de6fc 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:39:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -27,7 +27,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 0dbb530e698bb..5317bb6a1b13e 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-from-trait-match.rs:32:36 | LL | establish_relationships(value, |value| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 2 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/propagate-from-trait-match.rs:28:1 | LL | / fn supply<'a, T>(value: T) diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index ca794d92666f2..79ed1501524bd 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/return-wrong-bound-region.rs:11:16 | LL | expect_sig(|a, b| b); // ought to return `a` @@ -18,7 +18,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` | | has type `&'1 i32` | has type `&'2 i32` -note: No external requirements +note: no external requirements --> $DIR/return-wrong-bound-region.rs:10:1 | LL | / fn test() { diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index c825227cdad8e..bff8c662d0def 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:25:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -11,7 +11,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 3 = note: where ::Item: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:21:1 | LL | / fn no_region<'a, T>(x: Box) -> Box @@ -33,7 +33,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:34:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -46,7 +46,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 3 = note: where ::Item: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:30:1 | LL | / fn correct_region<'a, T>(x: Box) -> Box @@ -59,7 +59,7 @@ LL | | } | = note: defining type: correct_region::<'_#1r, T> -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:42:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -72,7 +72,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 4 = note: where ::Item: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:38:1 | LL | / fn wrong_region<'a, 'b, T>(x: Box) -> Box @@ -94,7 +94,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:52:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -107,7 +107,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 4 = note: where ::Item: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:47:1 | LL | / fn outlives_region<'a, 'b, T>(x: Box) -> Box diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 7226c520bf138..6d1fbcb8f5bfd 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:45:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -13,7 +13,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#2r = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:41:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -48,7 +48,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:56:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -62,7 +62,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#3r = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:51:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -97,7 +97,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:70:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -110,7 +110,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:62:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -124,7 +124,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:80:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -138,7 +138,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#3r = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:74:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index 655995c1b8029..59d8aa484bdac 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:37:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -12,7 +12,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:33:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -39,7 +39,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:47:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -52,7 +52,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:42:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -79,7 +79,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:60:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -92,7 +92,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:52:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -106,7 +106,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:69:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -119,7 +119,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:64:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -133,7 +133,7 @@ LL | | } | = note: defining type: elements_outlive::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:81:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -146,7 +146,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:73:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr index 2fb07b9279aa8..c3b924577ab47 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:36:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -10,7 +10,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); ] = note: late-bound region is '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:32:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -23,7 +23,7 @@ LL | | } | = note: defining type: no_relationships_late::<'_#1r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:45:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -34,7 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:40:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -48,7 +48,7 @@ LL | | } | = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:64:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -59,7 +59,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:49:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -73,7 +73,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:73:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -84,7 +84,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:68:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -98,7 +98,7 @@ LL | | } | = note: defining type: elements_outlive::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:85:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -109,7 +109,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:77:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 501a55e3105db..1bd97c1caa4ae 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:38:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -12,7 +12,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:34:1 | LL | / fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -34,7 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `>::AssocType: ReFree(DefId(0:17 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(DefId(0:18 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -47,7 +47,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:43:1 | LL | / fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -69,7 +69,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `>::AssocType: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:61:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -82,7 +82,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:53:1 | LL | / fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -96,7 +96,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:70:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -109,7 +109,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:65:1 | LL | / fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -123,7 +123,7 @@ LL | | } | = note: defining type: elements_outlive1::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:79:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -136,7 +136,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:74:1 | LL | / fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -150,7 +150,7 @@ LL | | } | = note: defining type: elements_outlive2::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -164,7 +164,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:83:1 | LL | / fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -191,7 +191,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:97:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -204,7 +204,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:92:1 | LL | / fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -218,7 +218,7 @@ LL | | } | = note: defining type: two_regions_outlive::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -231,7 +231,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where >::AssocType: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:101:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index db0bca1dec6f5..a213f423e3c8d 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:24:24 | LL | twice(cell, value, |a, b| invoke(a, b)); @@ -11,7 +11,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); = note: number of external vids: 2 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:22:1 | LL | / fn generic(value: T) { @@ -22,7 +22,7 @@ LL | | } | = note: defining type: generic:: -note: External requirements +note: external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24 | LL | twice(cell, value, |a, b| invoke(a, b)); @@ -36,7 +36,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); = note: number of external vids: 3 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:28:1 | LL | / fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) { diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 0021d730f85a1..a488637bbc5c2 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23 | LL | with_signature(x, |y| y) @@ -11,7 +11,7 @@ LL | with_signature(x, |y| y) = note: number of external vids: 3 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-return-type.rs:15:1 | LL | / fn no_region<'a, T>(x: Box) -> Box diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 46fef8ee5067b..62dfe94e38493 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26 | LL | with_signature(a, b, |x, y| { @@ -19,7 +19,7 @@ LL | | }) = note: number of external vids: 3 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:26:1 | LL | / fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { @@ -48,7 +48,7 @@ LL | | }) | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:11 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(DefId(0:12 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 | LL | with_signature(a, b, |x, y| { @@ -68,7 +68,7 @@ LL | | }) = note: number of external vids: 3 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:39:1 | LL | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T) @@ -82,7 +82,7 @@ LL | | } | = note: defining type: correct_region::<'_#1r, T> -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26 | LL | with_signature(a, b, |x, y| { @@ -101,7 +101,7 @@ LL | | }) = note: number of external vids: 4 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:60:1 | LL | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) @@ -128,7 +128,7 @@ LL | | }) | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:19 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(DefId(0:20 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 | LL | with_signature(a, b, |x, y| { @@ -145,7 +145,7 @@ LL | | }) = note: number of external vids: 4 = note: where T: '_#3r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1 | LL | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) diff --git a/src/test/ui/order-dependent-cast-inference.stderr b/src/test/ui/order-dependent-cast-inference.stderr index 081038c573acf..ad50b415869dd 100644 --- a/src/test/ui/order-dependent-cast-inference.stderr +++ b/src/test/ui/order-dependent-cast-inference.stderr @@ -6,7 +6,7 @@ LL | let mut y = 0 as *const _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error: aborting due to previous error diff --git a/src/test/ui/test-attrs/test-should-panic-attr.stderr b/src/test/ui/test-attrs/test-should-panic-attr.stderr index 4b032eba5f8d5..d7d0d84432ce6 100644 --- a/src/test/ui/test-attrs/test-should-panic-attr.stderr +++ b/src/test/ui/test-attrs/test-should-panic-attr.stderr @@ -4,7 +4,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:18:1 @@ -12,7 +12,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expect)] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:25:1 @@ -20,7 +20,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected(foo, bar))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:32:1 @@ -28,5 +28,5 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected = "foo", bar)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. diff --git a/src/test/ui/traits/trait-bounds-same-crate-name.rs b/src/test/ui/traits/trait-bounds-same-crate-name.rs index af720ecfdc063..1012edb109336 100644 --- a/src/test/ui/traits/trait-bounds-same-crate-name.rs +++ b/src/test/ui/traits/trait-bounds-same-crate-name.rs @@ -31,7 +31,7 @@ fn main() { a::try_foo(foo); //~^ ERROR E0277 //~| trait impl with same name found - //~| Perhaps two different versions of crate `crate_a2` + //~| perhaps two different versions of crate `crate_a2` // We don't want to see the "version mismatch" help message here // because `implements_no_traits` has no impl for `Foo` diff --git a/src/test/ui/traits/trait-bounds-same-crate-name.stderr b/src/test/ui/traits/trait-bounds-same-crate-name.stderr index 8fd0bd13e54b3..8a6e059604d2b 100644 --- a/src/test/ui/traits/trait-bounds-same-crate-name.stderr +++ b/src/test/ui/traits/trait-bounds-same-crate-name.stderr @@ -14,7 +14,7 @@ help: trait impl with same name found | LL | impl Bar for Foo {} | ^^^^^^^^^^^^^^^^^^^ - = note: Perhaps two different versions of crate `crate_a2` are being used? + = note: perhaps two different versions of crate `crate_a2` are being used? error[E0277]: the trait bound `main::a::DoesNotImplementTrait: main::a::Bar` is not satisfied --> $DIR/trait-bounds-same-crate-name.rs:38:20 @@ -43,7 +43,7 @@ help: trait impl with same name found | LL | impl Bar for ImplementsWrongTraitConditionally {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: Perhaps two different versions of crate `crate_a2` are being used? + = note: perhaps two different versions of crate `crate_a2` are being used? error[E0277]: the trait bound `main::a::ImplementsTraitForUsize: main::a::Bar` is not satisfied --> $DIR/trait-bounds-same-crate-name.rs:51:20 From 8461fa51198ad5db1d070620fe4186aaec648438 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:36:22 +0000 Subject: [PATCH 0276/1253] Diagnostics should not end with a full stop --- src/libcore/lib.rs | 2 +- src/librustc/middle/lang_items.rs | 6 +++--- src/librustc_passes/diagnostic_items.rs | 2 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/libstd/panicking.rs | 2 +- src/test/compile-fail/panic-handler-twice.rs | 2 +- .../mutually-recursive-async-impl-trait-type.stderr | 4 ++-- .../ui/async-await/recursive-async-impl-trait-type.stderr | 2 +- src/test/ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- .../ui/consts/miri_unleashed/mutable_references_ice.stderr | 2 +- src/test/ui/duplicate_entry_error.rs | 2 +- src/test/ui/duplicate_entry_error.stderr | 4 ++-- src/test/ui/error-codes/E0152.stderr | 4 ++-- src/test/ui/keyword/keyword-super-as-identifier.rs | 2 +- src/test/ui/keyword/keyword-super-as-identifier.stderr | 4 ++-- src/test/ui/keyword/keyword-super.rs | 2 +- src/test/ui/keyword/keyword-super.stderr | 4 ++-- src/test/ui/multi-panic.rs | 2 +- src/test/ui/panic-handler/panic-handler-duplicate.rs | 2 +- src/test/ui/panic-handler/panic-handler-duplicate.stderr | 4 ++-- src/test/ui/panic-handler/panic-handler-std.rs | 2 +- src/test/ui/panic-handler/panic-handler-std.stderr | 4 ++-- src/test/ui/pattern/const-pat-ice.stderr | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.rs | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.stderr | 4 ++-- src/test/ui/super-at-top-level.rs | 2 +- src/test/ui/super-at-top-level.stderr | 4 ++-- src/test/ui/test-panic-abort.run.stdout | 2 +- 29 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 95ffe4f438f5f..15720ddcfc677 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -44,7 +44,7 @@ // Here we explicitly #[cfg]-out this whole crate when testing. If we don't do // this, both the generated test artifact and the linked libtest (which // transitively includes libcore) will both define the same set of lang items, -// and this will cause the E0152 "duplicate lang item found" error. See +// and this will cause the E0152 "found duplicate lang item" error. See // discussion in #50466 for details. // // This cfg won't affect doc tests. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 42fc3e030e7bb..643359f098b4d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -184,7 +184,7 @@ impl LanguageItemCollector<'tcx> { self.tcx.sess, span, E0152, - "duplicate lang item found: `{}`.", + "found duplicate lang item `{}`", name ), None => { @@ -206,12 +206,12 @@ impl LanguageItemCollector<'tcx> { }, }; if let Some(span) = self.tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here."); + err.span_note(span, "first defined here"); } else { match self.tcx.extern_crate(original_def_id) { Some(ExternCrate {dependency_of, ..}) => { err.note(&format!( - "first defined in crate `{}` (which `{}` depends on).", + "first defined in crate `{}` (which `{}` depends on)", self.tcx.crate_name(original_def_id.krate), self.tcx.crate_name(*dependency_of))); }, diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs index c083830b730cc..8d220a3f695f2 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/src/librustc_passes/diagnostic_items.rs @@ -73,7 +73,7 @@ fn collect_item( )), }; if let Some(span) = tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here."); + err.span_note(span, "first defined here"); } else { err.note(&format!( "first defined in crate `{}`.", diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8e4630cf7d696..8d5afb194a175 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2006,7 +2006,7 @@ impl<'a> Resolver<'a> { continue; } } - let msg = "there are too many initial `super`s.".to_string(); + let msg = "there are too many leading `super` keywords".to_string(); return PathResult::Failed { span: ident.span, label: msg, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 92a7e18a8600f..baf9ae1ac2911 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1664,7 +1664,7 @@ fn check_opaque_for_cycles<'tcx>( if let hir::OpaqueTyOrigin::AsyncFn = origin { struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",) .span_label(span, "recursive `async fn`") - .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.") + .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") .emit(); } else { let mut err = diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 599ccc809be1f..f773a8276e354 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -199,7 +199,7 @@ fn default_hook(info: &PanicInfo<'_>) { let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace." + environment variable to display a backtrace" ); } } diff --git a/src/test/compile-fail/panic-handler-twice.rs b/src/test/compile-fail/panic-handler-twice.rs index c0f2c51397ed9..0c5359b9bd8c6 100644 --- a/src/test/compile-fail/panic-handler-twice.rs +++ b/src/test/compile-fail/panic-handler-twice.rs @@ -10,7 +10,7 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - //~^ error duplicate lang item found: `panic_impl` + //~^ ERROR found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr index 9249308936e54..f6e4c8be29260 100644 --- a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr @@ -4,7 +4,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn rec_1() { | ^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error[E0733]: recursion in an `async fn` requires boxing --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18 @@ -12,7 +12,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn rec_2() { | ^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr index 9ee014021804e..892d91e3a4992 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr @@ -4,7 +4,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn recursive_async_function() -> () { | ^^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 88418e57acdda..655c31763ef44 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -11,7 +11,7 @@ LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *m | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr index c148842bcbc66..c292fcef7f660 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr @@ -7,7 +7,7 @@ LL | x: &UnsafeCell::new(42), thread 'rustc' panicked at 'assertion failed: `(left != right)` left: `Const`, right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites could observe that mutation.', src/librustc_mir/interpret/intern.rs:LL:CC -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/duplicate_entry_error.rs b/src/test/ui/duplicate_entry_error.rs index 62df42b1a6890..b8d98a8999b9d 100644 --- a/src/test/ui/duplicate_entry_error.rs +++ b/src/test/ui/duplicate_entry_error.rs @@ -8,7 +8,7 @@ use std::panic::PanicInfo; #[lang = "panic_impl"] fn panic_impl(info: &PanicInfo) -> ! { -//~^ ERROR: duplicate lang item found: `panic_impl`. +//~^ ERROR: found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr index 02be11d1fd0e5..46b137b2cf9c0 100644 --- a/src/test/ui/duplicate_entry_error.stderr +++ b/src/test/ui/duplicate_entry_error.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/duplicate_entry_error.rs:10:1 | LL | / fn panic_impl(info: &PanicInfo) -> ! { @@ -7,7 +7,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `duplicate_entry_error` depends on). + = note: first defined in crate `std` (which `duplicate_entry_error` depends on) error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index d4b59a1148e60..c41a0430150a4 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -1,10 +1,10 @@ -error[E0152]: duplicate lang item found: `arc`. +error[E0152]: found duplicate lang item `arc` --> $DIR/E0152.rs:4:1 | LL | struct Foo; | ^^^^^^^^^^^ | - = note: first defined in crate `alloc` (which `std` depends on). + = note: first defined in crate `alloc` (which `std` depends on) error: aborting due to previous error diff --git a/src/test/ui/keyword/keyword-super-as-identifier.rs b/src/test/ui/keyword/keyword-super-as-identifier.rs index d728b4fe3e241..02c1b27b08a96 100644 --- a/src/test/ui/keyword/keyword-super-as-identifier.rs +++ b/src/test/ui/keyword/keyword-super-as-identifier.rs @@ -1,3 +1,3 @@ fn main() { - let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s + let super = 22; //~ ERROR failed to resolve: there are too many leading `super` keywords } diff --git a/src/test/ui/keyword/keyword-super-as-identifier.stderr b/src/test/ui/keyword/keyword-super-as-identifier.stderr index bbeaed9428795..1f64f3b73d6cd 100644 --- a/src/test/ui/keyword/keyword-super-as-identifier.stderr +++ b/src/test/ui/keyword/keyword-super-as-identifier.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/keyword-super-as-identifier.rs:2:9 | LL | let super = 22; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/keyword/keyword-super.rs b/src/test/ui/keyword/keyword-super.rs index a43e1e39b6797..c121a6c1050ea 100644 --- a/src/test/ui/keyword/keyword-super.rs +++ b/src/test/ui/keyword/keyword-super.rs @@ -1,3 +1,3 @@ fn main() { - let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s + let super: isize; //~ ERROR failed to resolve: there are too many leading `super` keywords } diff --git a/src/test/ui/keyword/keyword-super.stderr b/src/test/ui/keyword/keyword-super.stderr index 63394c7852a5d..0e0d67cb97b1f 100644 --- a/src/test/ui/keyword/keyword-super.stderr +++ b/src/test/ui/keyword/keyword-super.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/keyword-super.rs:2:9 | LL | let super: isize; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/multi-panic.rs b/src/test/ui/multi-panic.rs index e4b41e4180664..0f8bddf27fe08 100644 --- a/src/test/ui/multi-panic.rs +++ b/src/test/ui/multi-panic.rs @@ -10,7 +10,7 @@ fn check_for_no_backtrace(test: std::process::Output) { assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace.")); + environment variable to display a backtrace")); assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); assert_eq!(it.next(), None); } diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.rs b/src/test/ui/panic-handler/panic-handler-duplicate.rs index caa130ef460f1..bd99af999c797 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.rs +++ b/src/test/ui/panic-handler/panic-handler-duplicate.rs @@ -12,6 +12,6 @@ fn panic(info: &PanicInfo) -> ! { } #[lang = "panic_impl"] -fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`. +fn panic2(info: &PanicInfo) -> ! { //~ ERROR found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.stderr b/src/test/ui/panic-handler/panic-handler-duplicate.stderr index e9b1945364372..9999e3276469d 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.stderr +++ b/src/test/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-duplicate.rs:15:1 | LL | / fn panic2(info: &PanicInfo) -> ! { @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | -note: first defined here. +note: first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | LL | / fn panic(info: &PanicInfo) -> ! { diff --git a/src/test/ui/panic-handler/panic-handler-std.rs b/src/test/ui/panic-handler/panic-handler-std.rs index fffb5977871d8..0acc2722cb21f 100644 --- a/src/test/ui/panic-handler/panic-handler-std.rs +++ b/src/test/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -// error-pattern: duplicate lang item found: `panic_impl`. +// error-pattern: found duplicate lang item `panic_impl` use std::panic::PanicInfo; diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index e6d24348ca825..ac56513fd4706 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-std.rs:7:1 | LL | / fn panic(info: PanicInfo) -> ! { @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `panic_handler_std` depends on). + = note: first defined in crate `std` (which `panic_handler_std` depends on) error: argument should be `&PanicInfo` --> $DIR/panic-handler-std.rs:7:16 diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 7217fe1b02f4e..d0018cef5f033 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,5 +1,5 @@ thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/hair/pattern/_match.rs:LL:CC -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.rs b/src/test/ui/resolve/impl-items-vis-unresolved.rs index 9b4fe498239b6..a124b4eff8f69 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.rs +++ b/src/test/ui/resolve/impl-items-vis-unresolved.rs @@ -18,7 +18,7 @@ mod state { pub struct RawFloatState; impl RawFloatState { perftools_inline! { - pub(super) fn new() {} //~ ERROR failed to resolve: there are too many initial `super`s + pub(super) fn new() {} //~ ERROR failed to resolve: there are too many leading `super` keywords } } diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.stderr b/src/test/ui/resolve/impl-items-vis-unresolved.stderr index 8e285e5312400..62cffe55f9fb6 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.stderr +++ b/src/test/ui/resolve/impl-items-vis-unresolved.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords. error: aborting due to previous error diff --git a/src/test/ui/super-at-top-level.rs b/src/test/ui/super-at-top-level.rs index 41360df77994e..e4d587bc9effa 100644 --- a/src/test/ui/super-at-top-level.rs +++ b/src/test/ui/super-at-top-level.rs @@ -1,4 +1,4 @@ -use super::f; //~ ERROR there are too many initial `super`s +use super::f; //~ ERROR there are too many leading `super` keywords fn main() { } diff --git a/src/test/ui/super-at-top-level.stderr b/src/test/ui/super-at-top-level.stderr index d04ce384fe886..23613df6752fb 100644 --- a/src/test/ui/super-at-top-level.stderr +++ b/src/test/ui/super-at-top-level.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/super-at-top-level.rs:1:5 | LL | use super::f; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/test-panic-abort.run.stdout b/src/test/ui/test-panic-abort.run.stdout index 0c8bc5020871b..46adcfbc2eb4a 100644 --- a/src/test/ui/test-panic-abort.run.stdout +++ b/src/test/ui/test-panic-abort.run.stdout @@ -18,7 +18,7 @@ testing321 thread 'main' panicked at 'assertion failed: `(left == right)` left: `2`, right: `5`', $DIR/test-panic-abort.rs:31:5 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failures: From e84248921b44c9fdf3d6638c170ffde733074ff8 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:57:36 +0000 Subject: [PATCH 0277/1253] Add backticks in appropriate places --- src/librustc_lint/builtin.rs | 9 ++-- src/librustc_parse/parser/attr.rs | 4 +- src/librustc_resolve/build_reduced_graph.rs | 6 +-- src/librustc_typeck/check/method/suggest.rs | 2 +- .../validate_uninhabited_zsts.stderr | 2 +- .../deprecated-macro_escape-inner.rs | 2 +- .../deprecated-macro_escape-inner.stderr | 2 +- .../ui/deprecation/deprecated-macro_escape.rs | 8 ++-- .../deprecated-macro_escape.stderr | 2 +- .../issue-43106-gating-of-builtin-attrs.rs | 4 +- ...issue-43106-gating-of-builtin-attrs.stderr | 4 +- .../issue-43106-gating-of-macro_escape.rs | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- .../issue-43106-gating-of-macro_use.rs | 6 +-- .../issue-43106-gating-of-macro_use.stderr | 6 +-- .../extern-crate-self-fail.rs | 2 +- .../extern-crate-self-fail.stderr | 2 +- src/test/ui/issues/issue-29124.stderr | 4 +- src/test/ui/issues/issue-57362-1.stderr | 2 +- src/test/ui/lint/uninitialized-zeroed.stderr | 16 +++---- .../malformed/malformed-interpolated.stderr | 2 +- src/test/ui/module-macro_use-arguments.rs | 2 +- src/test/ui/module-macro_use-arguments.stderr | 2 +- src/test/ui/suffixed-literal-meta.stderr | 48 +++++++++---------- ...ed-closures-static-call-wrong-trait.stderr | 2 +- 25 files changed, 72 insertions(+), 71 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7f55bcd4017ef..fea0b012f91b3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1959,13 +1959,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { // return `Bound::Excluded`. (And we have tests checking that we // handle the attribute correctly.) (Bound::Included(lo), _) if lo > 0 => { - return Some((format!("{} must be non-null", ty), None)); + return Some((format!("`{}` must be non-null", ty), None)); } (Bound::Included(_), _) | (_, Bound::Included(_)) if init == InitKind::Uninit => { return Some(( - format!("{} must be initialized inside its custom valid range", ty), + format!( + "`{}` must be initialized inside its custom valid range", + ty, + ), None, )); } @@ -1973,7 +1976,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { } // Now, recurse. match adt_def.variants.len() { - 0 => Some((format!("0-variant enums have no valid value"), None)), + 0 => Some((format!("enums with no variants have no valid value"), None)), 1 => { // Struct, or enum with exactly one variant. // Proceed recursively, check all fields. diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 81f31b2eda1d4..3d40b91a7bdc8 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -236,8 +236,8 @@ impl<'a> Parser<'a> { self.struct_span_err(lit.span, msg) .help( "instead of using a suffixed literal \ - (1u8, 1.0f32, etc.), use an unsuffixed version \ - (1, 1.0, etc.).", + (`1u8`, `1.0f32`, etc.), use an unsuffixed version \ + (`1`, `1.0`, etc.)", ) .emit() } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 291386413d647..9c80df367c09c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -963,7 +963,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .session .struct_span_err( attr.span, - "`macro_use` is not supported on `extern crate self`", + "`#[macro_use]` is not supported on `extern crate self`", ) .emit(); } @@ -1054,7 +1054,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool { for attr in attrs { if attr.check_name(sym::macro_escape) { - let msg = "macro_escape is a deprecated synonym for macro_use"; + let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`"; let mut err = self.r.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { err.help("consider an outer attribute, `#[macro_use]` mod ...").emit(); @@ -1066,7 +1066,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } if !attr.is_word() { - self.r.session.span_err(attr.span, "arguments to macro_use are not allowed here"); + self.r.session.span_err(attr.span, "arguments to `macro_use` are not allowed here"); } return true; } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b84e1d37b06ff..d6c0d9c77b495 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { macro_rules! report_function { ($span:expr, $name:expr) => { err.note(&format!( - "{} is a function, perhaps you wish to call it", + "`{}` is a function, perhaps you wish to call it", $name )); }; diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 040c568beb324..51e80bb8b118b 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -45,7 +45,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.rs b/src/test/ui/deprecation/deprecated-macro_escape-inner.rs index 957e839013ec7..e2957c422f6d5 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.rs +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.rs @@ -1,7 +1,7 @@ // run-pass mod foo { - #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use + #![macro_escape] //~ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` } fn main() { diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr index 1b69270d624f4..65db62ce26355 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/deprecated-macro_escape-inner.rs:4:5 | LL | #![macro_escape] diff --git a/src/test/ui/deprecation/deprecated-macro_escape.rs b/src/test/ui/deprecation/deprecated-macro_escape.rs index 1b82a99f42eab..4a89b40625e68 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape.rs +++ b/src/test/ui/deprecation/deprecated-macro_escape.rs @@ -1,8 +1,6 @@ // run-pass -#[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use -mod foo { -} +#[macro_escape] //~ WARNING `#[macro_escape]` is a deprecated synonym for `#[macro_use]` +mod foo {} -fn main() { -} +fn main() {} diff --git a/src/test/ui/deprecation/deprecated-macro_escape.stderr b/src/test/ui/deprecation/deprecated-macro_escape.stderr index b76d6d73d972b..70094083d4b34 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/deprecated-macro_escape.rs:3:1 | LL | #[macro_escape] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 0d804f012bcc3..8609108831e7c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -464,10 +464,10 @@ mod reexport_test_harness_main { // Cannot feed "2700" to `#[macro_escape]` without signaling an error. #[macro_escape] -//~^ WARN macro_escape is a deprecated synonym for macro_use +//~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` mod macro_escape { mod inner { #![macro_escape] } - //~^ WARN macro_escape is a deprecated synonym for macro_use + //~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` #[macro_escape] fn f() { } //~^ WARN unused attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 9ce90d89d22d2..6063aabd565bc 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -172,13 +172,13 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:17 | LL | mod inner { #![macro_escape] } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs index 75a3d9124ebae..de00bc4cbac07 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -6,6 +6,6 @@ // check-pass #![macro_escape] -//~^ WARN macro_escape is a deprecated synonym for macro_use +//~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index 8575c1660c5a1..f2cc2f74e53e4 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-macro_escape.rs:8:1 | LL | #![macro_escape] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs index 4ced941aad5d0..6a7ef793924a4 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs @@ -4,13 +4,13 @@ // get that warning; see issue-43106-gating-of-builtin-attrs.rs #![macro_use(my_macro)] -//~^ ERROR arguments to macro_use are not allowed here +//~^ ERROR arguments to `macro_use` are not allowed here #[macro_use(my_macro)] -//~^ ERROR arguments to macro_use are not allowed here +//~^ ERROR arguments to `macro_use` are not allowed here mod macro_escape { mod inner { #![macro_use(my_macro)] } - //~^ ERROR arguments to macro_use are not allowed here + //~^ ERROR arguments to `macro_use` are not allowed here #[macro_use = "2700"] struct S; //~^ ERROR malformed `macro_use` attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr index 3181d62298cad..52a682e4bfa87 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr @@ -1,16 +1,16 @@ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:6:1 | LL | #![macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:9:1 | LL | #[macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:12:17 | LL | mod inner { #![macro_use(my_macro)] } diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs index defa0e294bd74..1c0d3b4b964d6 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs @@ -1,6 +1,6 @@ extern crate self; //~ ERROR `extern crate self;` requires renaming -#[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self` +#[macro_use] //~ ERROR `#[macro_use]` is not supported on `extern crate self` extern crate self as foo; fn main() {} diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr index f26bb2f5a0ec4..8f369f1b03831 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr @@ -4,7 +4,7 @@ error: `extern crate self;` requires renaming LL | extern crate self; | ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;` -error: `macro_use` is not supported on `extern crate self` +error: `#[macro_use]` is not supported on `extern crate self` --> $DIR/extern-crate-self-fail.rs:3:1 | LL | #[macro_use] diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index fff20248b70d5..42d89cd01a48e 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in LL | Obj::func.x(); | ^ method not found in `fn() -> Ret {Obj::func}` | - = note: Obj::func is a function, perhaps you wish to call it + = note: `Obj::func` is a function, perhaps you wish to call it error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope --> $DIR/issue-29124.rs:17:10 @@ -12,7 +12,7 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the LL | func.x(); | ^ method not found in `fn() -> Ret {func}` | - = note: func is a function, perhaps you wish to call it + = note: `func` is a function, perhaps you wish to call it error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index e762b7bc0c899..ad596db13ccfd 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current LL | a.f(); | ^ method not found in `fn(&u8)` | - = note: a is a function, perhaps you wish to call it + = note: `a` is a function, perhaps you wish to call it = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `f`, perhaps you need to implement it: candidate #1: `Trait` diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index d451b827598f4..169e77c8fa05d 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -108,7 +108,7 @@ LL | let _val: Void = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: the type `Void` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:47:26 @@ -119,7 +119,7 @@ LL | let _val: Void = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: the type `&'static i32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:49:34 @@ -294,7 +294,7 @@ LL | let _val: NonNull = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `std::ptr::NonNull` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:68:34 @@ -305,7 +305,7 @@ LL | let _val: NonNull = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `*const dyn std::marker::Send` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:70:37 @@ -364,7 +364,7 @@ LL | let _val: NonBig = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: NonBig must be initialized inside its custom valid range + = note: `NonBig` must be initialized inside its custom valid range error: the type `&'static i32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:84:34 @@ -397,7 +397,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::num::NonZeroU32 must be non-null + = note: `std::num::NonZeroU32` must be non-null error: the type `std::ptr::NonNull` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:89:34 @@ -408,7 +408,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `std::ptr::NonNull` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:90:34 @@ -419,7 +419,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:91:26 diff --git a/src/test/ui/malformed/malformed-interpolated.stderr b/src/test/ui/malformed/malformed-interpolated.stderr index bcd2ef545d815..6f6ad4508be01 100644 --- a/src/test/ui/malformed/malformed-interpolated.stderr +++ b/src/test/ui/malformed/malformed-interpolated.stderr @@ -4,7 +4,7 @@ error: suffixed literals are not allowed in attributes LL | check!(0u8); | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: unexpected token: `-0` --> $DIR/malformed-interpolated.rs:5:25 diff --git a/src/test/ui/module-macro_use-arguments.rs b/src/test/ui/module-macro_use-arguments.rs index 6627b48eb6a2c..121b492e25437 100644 --- a/src/test/ui/module-macro_use-arguments.rs +++ b/src/test/ui/module-macro_use-arguments.rs @@ -1,4 +1,4 @@ -#[macro_use(foo, bar)] //~ ERROR arguments to macro_use are not allowed here +#[macro_use(foo, bar)] //~ ERROR arguments to `macro_use` are not allowed here mod foo { } diff --git a/src/test/ui/module-macro_use-arguments.stderr b/src/test/ui/module-macro_use-arguments.stderr index 2a75736a2c69f..af799cb6ddf3e 100644 --- a/src/test/ui/module-macro_use-arguments.stderr +++ b/src/test/ui/module-macro_use-arguments.stderr @@ -1,4 +1,4 @@ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/module-macro_use-arguments.rs:1:1 | LL | #[macro_use(foo, bar)] diff --git a/src/test/ui/suffixed-literal-meta.stderr b/src/test/ui/suffixed-literal-meta.stderr index ee35b53abe111..84fe91d662a8b 100644 --- a/src/test/ui/suffixed-literal-meta.stderr +++ b/src/test/ui/suffixed-literal-meta.stderr @@ -4,7 +4,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1usize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:5:17 @@ -12,7 +12,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:7:17 @@ -20,7 +20,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:9:17 @@ -28,7 +28,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:11:17 @@ -36,7 +36,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:13:17 @@ -44,7 +44,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1isize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:15:17 @@ -52,7 +52,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:17:17 @@ -60,7 +60,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:19:17 @@ -68,7 +68,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:21:17 @@ -76,7 +76,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:23:17 @@ -84,7 +84,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f32] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:25:17 @@ -92,7 +92,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f64] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:3:17 @@ -100,7 +100,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1usize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:5:17 @@ -108,7 +108,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:7:17 @@ -116,7 +116,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:9:17 @@ -124,7 +124,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:11:17 @@ -132,7 +132,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:13:17 @@ -140,7 +140,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1isize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:15:17 @@ -148,7 +148,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:17:17 @@ -156,7 +156,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:19:17 @@ -164,7 +164,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:21:17 @@ -172,7 +172,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:23:17 @@ -180,7 +180,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f32] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:25:17 @@ -188,7 +188,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f64] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: aborting due to 24 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr index 2d058521e4ef6..0b6d94e71f0c7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-cl LL | mut_.call((0, )); | ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` | - = note: mut_ is a function, perhaps you wish to call it + = note: `mut_` is a function, perhaps you wish to call it error: aborting due to previous error From 3de9b8a3b7963b2eb03d570b54055b0a895662f1 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 15:13:56 +0000 Subject: [PATCH 0278/1253] Fix formatting ellipses at the end of some diagnostics --- src/librustc_parse/parser/pat.rs | 4 ++-- src/librustc_resolve/build_reduced_graph.rs | 2 +- .../deprecated-macro_escape-inner.stderr | 2 +- ...92-tuple-destructure-missing-parens.stderr | 24 +++++++++---------- ...issue-43106-gating-of-builtin-attrs.stderr | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 0c2cfc20daf0f..549acf67d3824 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -209,13 +209,13 @@ impl<'a> Parser<'a> { if let Ok(seq_snippet) = self.span_to_snippet(seq_span) { err.span_suggestion( seq_span, - "try adding parentheses to match on a tuple..", + "try adding parentheses to match on a tuple...", format!("({})", seq_snippet), Applicability::MachineApplicable, ) .span_suggestion( seq_span, - "..or a vertical bar to match on multiple alternatives", + "...or a vertical bar to match on multiple alternatives", format!("{}", seq_snippet.replace(",", " |")), Applicability::MachineApplicable, ); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9c80df367c09c..e8ed64a18702d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1057,7 +1057,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`"; let mut err = self.r.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { - err.help("consider an outer attribute, `#[macro_use]` mod ...").emit(); + err.help("try an outer attribute: `#[macro_use]`").emit(); } else { err.emit(); } diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr index 65db62ce26355..4b0fc07463a99 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr @@ -4,5 +4,5 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` diff --git a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr index 705c90985d547..d05d6d120b084 100644 --- a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr +++ b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr @@ -4,11 +4,11 @@ error: unexpected `,` in pattern LL | while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | while let (b1, b2, b3) = reading_frame.next().expect("there should be a start codon") { | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | while let b1 | b2 | b3 = reading_frame.next().expect("there should be a start codon") { | ^^^^^^^^^^^^ @@ -19,11 +19,11 @@ error: unexpected `,` in pattern LL | if let b1, b2, b3 = reading_frame.next().unwrap() { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | if let (b1, b2, b3) = reading_frame.next().unwrap() { | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | if let b1 | b2 | b3 = reading_frame.next().unwrap() { | ^^^^^^^^^^^^ @@ -34,11 +34,11 @@ error: unexpected `,` in pattern LL | Nucleotide::Adenine, Nucleotide::Cytosine, _ => true | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | (Nucleotide::Adenine, Nucleotide::Cytosine, _) => true | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | Nucleotide::Adenine | Nucleotide::Cytosine | _ => true | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,11 +49,11 @@ error: unexpected `,` in pattern LL | for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | for (x, _barr_body) in women.iter().map(|woman| woman.allosomes.clone()) { | ^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | for x | _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { | ^^^^^^^^^^^^^^ @@ -64,11 +64,11 @@ error: unexpected `,` in pattern LL | for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | for (x, y @ Allosome::Y(_)) in men.iter().map(|man| man.allosomes.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | for x | y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -79,11 +79,11 @@ error: unexpected `,` in pattern LL | let women, men: (Vec, Vec) = genomes.iter().cloned() | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | let (women, men): (Vec, Vec) = genomes.iter().cloned() | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | let women | men: (Vec, Vec) = genomes.iter().cloned() | ^^^^^^^^^^^ diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 6063aabd565bc..da7d8f9bee5c5 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -184,7 +184,7 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:17 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index f2cc2f74e53e4..402dc4e540925 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -4,5 +4,5 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` From 117443ec0ad7aefabbc20c3f23f90e14b2b43c05 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 16:27:37 +0000 Subject: [PATCH 0279/1253] Appease tidy --- src/test/ui/resolve/impl-items-vis-unresolved.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.rs b/src/test/ui/resolve/impl-items-vis-unresolved.rs index a124b4eff8f69..1494c1cf96800 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.rs +++ b/src/test/ui/resolve/impl-items-vis-unresolved.rs @@ -18,7 +18,8 @@ mod state { pub struct RawFloatState; impl RawFloatState { perftools_inline! { - pub(super) fn new() {} //~ ERROR failed to resolve: there are too many leading `super` keywords + pub(super) fn new() {} + //~^ ERROR failed to resolve: there are too many leading `super` keywords } } From 1faa05daac8069503a0ffbba735db3b259424296 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 18:24:34 +0000 Subject: [PATCH 0280/1253] Update `output-default.json` and rustdoc test --- src/test/run-make-fulldeps/libtest-json/output-default.json | 2 +- .../run-make-fulldeps/libtest-json/output-stdout-success.json | 2 +- src/test/rustdoc-ui/failed-doctest-output.stdout | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json index 8046d72221703..0cd9ab79e32f3 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-default.json +++ b/src/test/run-make-fulldeps/libtest-json/output-default.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json index 303316278d8ab..dfaf005052e55 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json +++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 9887d07a3eb6e..ee79ae1a690ec 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -27,7 +27,7 @@ stderr: stderr 1 stderr 2 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:7:1 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.stderr b/src/test/ui/resolve/impl-items-vis-unresolved.stderr index 62cffe55f9fb6..f2293d28ea151 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.stderr +++ b/src/test/ui/resolve/impl-items-vis-unresolved.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} - | ^^^^^ there are too many leading `super` keywords. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error From 27b99d405092ac775efe99e520f0f969902906a3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 13 Jan 2020 00:51:15 +0900 Subject: [PATCH 0281/1253] Fix crate paths in comments --- src/librustc_feature/lib.rs | 3 ++- src/librustc_lint/builtin.rs | 2 +- .../ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_feature/lib.rs b/src/librustc_feature/lib.rs index 71a464279253b..01546f7825774 100644 --- a/src/librustc_feature/lib.rs +++ b/src/librustc_feature/lib.rs @@ -1,7 +1,8 @@ //! # Feature gates //! //! This crate declares the set of past and present unstable features in the compiler. -//! Feature gate checking itself is done in `libsyntax/feature_gate/check.rs` at the moment. +//! Feature gate checking itself is done in `librustc_ast_passes/feature_gate.rs` +//! at the moment. //! //! Features are enabled in programs via the crate-level attributes of //! `#![feature(...)]` with a comma-separated list of features. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 15a8332a28492..6aa809a706ebc 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1812,7 +1812,7 @@ declare_lint! { } declare_lint_pass!( - /// Check for used feature gates in `INCOMPLETE_FEATURES` in `feature_gate.rs`. + /// Check for used feature gates in `INCOMPLETE_FEATURES` in `librustc_feature/active.rs`. IncompleteFeatures => [INCOMPLETE_FEATURES] ); diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 0d804f012bcc3..92c5c2025022e 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -12,7 +12,7 @@ // the change when it happens. // // At the time of authoring, the attributes here are listed in the -// order that they occur in libsyntax/feature_gate.rs. +// order that they occur in `librustc_feature`. // // Any builtin attributes that: // From 5b7d64e9473216dc8650ca5f910100389ab91726 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Jan 2020 01:41:25 +0100 Subject: [PATCH 0282/1253] Fix error codes explanation' code examples --- src/librustc_error_codes/error_codes/E0445.md | 4 +++ src/librustc_error_codes/error_codes/E0446.md | 4 +++ src/librustc_error_codes/error_codes/E0491.md | 36 ++++++++++--------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0445.md b/src/librustc_error_codes/error_codes/E0445.md index 9cc62b2ba6d0a..e6a28a9c2c460 100644 --- a/src/librustc_error_codes/error_codes/E0445.md +++ b/src/librustc_error_codes/error_codes/E0445.md @@ -12,6 +12,8 @@ trait Foo { pub trait Bar : Foo {} // error: private trait in public interface pub struct Bar2(pub T); // same error pub fn foo (t: T) {} // same error + +fn main() {} ``` To solve this error, please ensure that the trait is also public. The trait @@ -26,4 +28,6 @@ pub trait Foo { // we set the Foo trait public pub trait Bar : Foo {} // ok! pub struct Bar2(pub T); // ok! pub fn foo (t: T) {} // ok! + +fn main() {} ``` diff --git a/src/librustc_error_codes/error_codes/E0446.md b/src/librustc_error_codes/error_codes/E0446.md index d0144478dbfe0..77a1834ece42f 100644 --- a/src/librustc_error_codes/error_codes/E0446.md +++ b/src/librustc_error_codes/error_codes/E0446.md @@ -12,6 +12,8 @@ mod Foo { Bar(0) } } + +fn main() {} ``` To solve this error, please ensure that the type is also public. The type @@ -27,4 +29,6 @@ mod Foo { Bar(0) } } + +fn main() {} ``` diff --git a/src/librustc_error_codes/error_codes/E0491.md b/src/librustc_error_codes/error_codes/E0491.md index 1ccaf71257b8b..d45663f3a5347 100644 --- a/src/librustc_error_codes/error_codes/E0491.md +++ b/src/librustc_error_codes/error_codes/E0491.md @@ -3,30 +3,34 @@ A reference has a longer lifetime than the data it references. Erroneous code example: ```compile_fail,E0491 -trait SomeTrait<'a> { - type Output; +struct Foo<'a> { + x: fn(&'a i32), } -impl<'a, T> SomeTrait<'a> for T { - type Output = &'a T; // compile error E0491 +trait Trait<'a, 'b> { + type Out; +} + +impl<'a, 'b> Trait<'a, 'b> for usize { + type Out = &'a Foo<'b>; // error! } ``` -Here, the problem is that a reference type like `&'a T` is only valid -if all the data in T outlives the lifetime `'a`. But this impl as written -is applicable to any lifetime `'a` and any type `T` -- we have no guarantee -that `T` outlives `'a`. To fix this, you can add a where clause like -`where T: 'a`. +Here, the problem is that the compiler cannot be sure that the `'b` lifetime +will live longer than `'a`, which should be mandatory in order to be sure that +`Trait::Out` will always have a reference pointing to an existing type. So in +this case, we just need to tell the compiler than `'b` must outlive `'a`: ``` -trait SomeTrait<'a> { - type Output; +struct Foo<'a> { + x: fn(&'a i32), +} + +trait Trait<'a, 'b> { + type Out; } -impl<'a, T> SomeTrait<'a> for T -where - T: 'a, -{ - type Output = &'a T; // compile error E0491 +impl<'a, 'b: 'a> Trait<'a, 'b> for usize { // we added the lifetime enforcement + type Out = &'a Foo<'b>; // it now works! } ``` From 34186ef642f1c48e6a27693ad16a3e0fcfd0fddc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 12 Jan 2020 17:50:14 +0100 Subject: [PATCH 0283/1253] Clean up E0186 explanation --- src/librustc_error_codes/error_codes/E0186.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0186.md b/src/librustc_error_codes/error_codes/E0186.md index 9135d5c1d5e9a..7db1e84332387 100644 --- a/src/librustc_error_codes/error_codes/E0186.md +++ b/src/librustc_error_codes/error_codes/E0186.md @@ -2,7 +2,7 @@ An associated function for a trait was defined to be a method (i.e., to take a `self` parameter), but an implementation of the trait declared the same function to be static. -Here's an example of this error: +Erroneous code example: ```compile_fail,E0186 trait Foo { @@ -17,3 +17,19 @@ impl Foo for Bar { fn foo() {} } ``` + +When a type implements a trait's associated function, it has to use the same +signature. So in this case, since `Foo::foo` takes `self` as argument and +does not return anything, its implementation on `Bar` should be the same: + +``` +trait Foo { + fn foo(&self); +} + +struct Bar; + +impl Foo for Bar { + fn foo(&self) {} // ok! +} +``` From 8f60db8da8f7f159dbe93ce481a4608633c4c1bf Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 12 Jan 2020 16:59:44 +0000 Subject: [PATCH 0284/1253] Don't include __rust_drop_panic when testing libstd --- src/libstd/panicking.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 43c2965f2315a..bfadeafb7c773 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -58,6 +58,7 @@ extern "C" { /// This function is called by the panic runtime if FFI code catches a Rust /// panic but doesn't rethrow it. We don't support this case since it messes /// with our panic count. +#[cfg(not(test))] #[rustc_std_internal_symbol] extern "C" fn __rust_drop_panic() -> ! { rtabort!("Rust panics must be rethrown"); From 827ee7a70adf923c3202c714b81a3a8b6c9ea29c Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sun, 12 Jan 2020 21:24:31 +0100 Subject: [PATCH 0285/1253] Fix system call docs for time::Instant The link for UNIX was pointing to the Cloud ABI docs. It should have been pointing to the clock_gettime docs instead. The table is repeated in the docs for SystemTime, but there the UNIX entry was already correct. --- src/libstd/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 0dce8f810eb13..0b6e728dceb1d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -67,7 +67,7 @@ pub use core::time::Duration; /// |:---------:|:--------------------------------------------------------------------:| /// | Cloud ABI | [clock_time_get (Monotonic Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | -/// | UNIX | [clock_time_get (Monotonic Clock)] | +/// | UNIX | [clock_gettime (Monotonic Clock)] | /// | Darwin | [mach_absolute_time] | /// | VXWorks | [clock_gettime (Monotonic Clock)] | /// | WASI | [__wasi_clock_time_get (Monotonic Clock)] | From 6a7a69bde9813ac2868f36a01567c633ed6cd023 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Jan 2020 14:07:31 -0800 Subject: [PATCH 0286/1253] Add {leading,trailing}_ones to primitive int types --- src/libcore/num/mod.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 072966abf2c40..77fae26953f09 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -393,6 +393,48 @@ $EndFeature, " } } + doc_comment! { + concat!("Returns the number of leading ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = -1", stringify!($SelfT), "; + +assert_eq!(n.leading_ones(), ", stringify!($BITS), ");", +$EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn leading_ones(self) -> u32 { + (self as $UnsignedT).leading_ones() + } + } + + doc_comment! { + concat!("Returns the number of trailing ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = 3", stringify!($SelfT), "; + +assert_eq!(n.trailing_ones(), 2);", +$EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn trailing_ones(self) -> u32 { + (self as $UnsignedT).trailing_ones() + } + } + doc_comment! { concat!("Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits to the end of the resulting integer. @@ -2485,6 +2527,47 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " } } + doc_comment! { + concat!("Returns the number of leading ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = !(", stringify!($SelfT), "::max_value() >> 2); + +assert_eq!(n.leading_ones(), 2);", $EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn leading_ones(self) -> u32 { + (!self).leading_zeros() + } + } + + doc_comment! { + concat!("Returns the number of trailing ones in the binary representation +of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = 0b1010111", stringify!($SelfT), "; + +assert_eq!(n.trailing_ones(), 3);", $EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn trailing_ones(self) -> u32 { + (!self).trailing_zeros() + } + } + doc_comment! { concat!("Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits to the end of the resulting integer. From 2330e325ccee2e91d7aec6c0d4068748619bf588 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Jan 2020 14:50:00 -0800 Subject: [PATCH 0287/1253] Tests for leading_trailing_ones --- src/libcore/tests/lib.rs | 1 + src/libcore/tests/num/int_macros.rs | 27 +++++++++++++++++++++++++++ src/libcore/tests/num/uint_macros.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 86cf6fc104c83..36476cf01c08c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -41,6 +41,7 @@ #![feature(const_raw_ptr_deref)] #![feature(never_type)] #![feature(unwrap_infallible)] +#![feature(leading_trailing_ones)] extern crate test; diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 4a44b5f24b910..48a49073b2cf5 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -89,6 +89,33 @@ macro_rules! int_module { assert_eq!(C.count_zeros(), bits as u32 - 5); } + #[test] + fn test_leading_trailing_ones() { + let bits = (mem::size_of::<$T>() * 8) as u32; + + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), bits - 7); + + assert_eq!(a.reverse_bits().leading_ones(), 5); + + assert_eq!(_1.leading_ones(), bits); + assert_eq!(_1.trailing_ones(), bits); + + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!(MAX.leading_ones(), 0); + + assert_eq!((_1 << 1).leading_ones(), bits - 1); + assert_eq!(MAX.trailing_ones(), bits - 1); + + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); + + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } + #[test] fn test_rotate() { assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs index f94b2f56bbbec..8f1ca8e6fac2c 100644 --- a/src/libcore/tests/num/uint_macros.rs +++ b/src/libcore/tests/num/uint_macros.rs @@ -53,6 +53,33 @@ macro_rules! uint_module { assert!(C.count_zeros() == bits as u32 - 5); } + #[test] + fn test_leading_trailing_ones() { + let bits = (mem::size_of::<$T>() * 8) as u32; + + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), bits - 7); + + assert_eq!(a.reverse_bits().leading_ones(), 5); + + assert_eq!(_1.leading_ones(), bits); + assert_eq!(_1.trailing_ones(), bits); + + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!((_1 >> 1).leading_ones(), 0); + + assert_eq!((_1 << 1).leading_ones(), bits - 1); + assert_eq!((_1 >> 1).trailing_ones(), bits - 1); + + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); + + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } + #[test] fn test_rotate() { assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); From 79f59fa82093a9706470038ef5d87e348686dad5 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 12 Jan 2020 23:37:47 +0000 Subject: [PATCH 0288/1253] rustdoc: HTML escape arrows on help popup --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8ccb74d6f15d3..809d38a7ead8f 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2663,8 +2663,8 @@ function getSearchElement() { "Accepted types are: fn, mod, struct, \ enum, trait, type, macro, \ and const.", - "Search functions by type signature (e.g., vec -> usize or \ - * -> vec)", + "Search functions by type signature (e.g., vec -> usize or \ + * -> vec)", "Search multiple things at once by splitting your query with comma (e.g., \ str,u8 or String,struct:Vec,test)", "You can look for items with an exact name by putting double quotes around \ From 4f163afed621adb51d0dfc7dd00c23cf38010d14 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Mon, 13 Jan 2020 00:39:41 +0000 Subject: [PATCH 0289/1253] Fix destructor return value in emcc.rs --- src/libpanic_unwind/emcc.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 268bafd240930..0f93140238bc4 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -76,12 +76,20 @@ pub unsafe fn panic(data: Box) -> u32 { } ptr::write(exception, Exception { data: Some(data) }); __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup); +} - extern "C" fn exception_cleanup(ptr: *mut libc::c_void) { - unsafe { - ptr::drop_in_place(ptr as *mut Exception); - super::__rust_drop_panic(); - } +// On WASM and ARM, the destructor returns the pointer to the object. +cfg_if::cfg_if! { + if #[cfg(any(target_arch = "arm", target_arch = "wasm32"))] { + type DestructorRet = *mut libc::c_void; + } else { + type DestructorRet = (); + } +} +extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> DestructorRet { + unsafe { + ptr::drop_in_place(ptr as *mut Exception); + super::__rust_drop_panic(); } } @@ -104,7 +112,7 @@ extern "C" { fn __cxa_throw( thrown_exception: *mut libc::c_void, tinfo: *const TypeInfo, - dest: extern "C" fn(*mut libc::c_void), + dest: extern "C" fn(*mut libc::c_void) -> DestructorRet, ) -> !; fn __gxx_personality_v0( version: c_int, From 109c30f3d4783f569eb4d9350e6045a1e96af80d Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:09:42 -0600 Subject: [PATCH 0290/1253] More separation of error reporting from region inference --- .../borrow_check/diagnostics/region_errors.rs | 33 +++----- src/librustc_mir/borrow_check/mod.rs | 77 ++++++++++--------- .../borrow_check/region_infer/mod.rs | 64 ++++++--------- .../borrow_check/region_infer/values.rs | 2 +- 4 files changed, 77 insertions(+), 99 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index dc63fa80275e1..bf4a12b12a5c2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,8 +1,7 @@ //! Error reporting machinery for lifetime errors. use rustc::infer::{ - error_reporting::nice_region_error::NiceRegionError, region_constraints::GenericKind, - InferCtxt, NLLRegionVariableOrigin, + error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, }; use rustc::mir::{Body, ConstraintCategory, Location}; use rustc::ty::{self, RegionVid, Ty}; @@ -16,8 +15,11 @@ use std::collections::VecDeque; use crate::util::borrowck_errors; use crate::borrow_check::{ - constraints::OutlivesConstraint, nll::ConstraintDescription, - region_infer::RegionInferenceContext, type_check::Locations, universal_regions::DefiningTy, + constraints::OutlivesConstraint, + nll::ConstraintDescription, + region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, + type_check::Locations, + universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -62,23 +64,8 @@ crate type RegionErrors<'tcx> = Vec>; #[derive(Clone, Debug)] crate enum RegionErrorKind<'tcx> { - /// An error for a type test: `T: 'a` does not live long enough. - TypeTestDoesNotLiveLongEnough { - /// The span of the type test. - span: Span, - /// The generic type of the type test. - generic: GenericKind<'tcx>, - }, - - /// A generic bound failure for a type test. - TypeTestGenericBoundError { - /// The span of the type test. - span: Span, - /// The generic type of the type test. - generic: GenericKind<'tcx>, - /// The lower bound region. - lower_bound_region: ty::Region<'tcx>, - }, + /// A generic bound failure for a type test (`T: 'a`). + TypeTestError { type_test: TypeTest<'tcx> }, /// An unexpected hidden region for an opaque type. UnexpectedHiddenRegion { @@ -94,8 +81,8 @@ crate enum RegionErrorKind<'tcx> { BoundUniversalRegionError { /// The placeholder free region. longer_fr: RegionVid, - /// The region that erroneously must be outlived by `longer_fr`. - error_region: RegionVid, + /// The region element that erroneously must be outlived by `longer_fr`. + error_element: RegionElement, /// The origin of the placeholder region. fr_origin: NLLRegionVariableOrigin, }, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 7b0a103fd0038..fc1b723c27120 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -631,7 +631,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx debug!( "visit_terminator_drop \ - loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", + loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", loc, term, drop_place, drop_place_ty, span ); @@ -1477,38 +1477,42 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for nll_error in nll_errors.into_iter() { match nll_error { - RegionErrorKind::TypeTestDoesNotLiveLongEnough { span, generic } => { - // FIXME. We should handle this case better. It - // indicates that we have e.g., some region variable - // whose value is like `'a+'b` where `'a` and `'b` are - // distinct unrelated univesal regions that are not - // known to outlive one another. It'd be nice to have - // some examples where this arises to decide how best - // to report it; we could probably handle it by - // iterating over the universal regions and reporting - // an error that multiple bounds are required. - self.infcx - .tcx - .sess - .struct_span_err(span, &format!("`{}` does not live long enough", generic)) - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::TypeTestGenericBoundError { - span, - generic, - lower_bound_region, - } => { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - self.infcx - .construct_generic_bound_failure( - region_scope_tree, - span, - None, - generic, - lower_bound_region, - ) - .buffer(&mut self.errors_buffer); + RegionErrorKind::TypeTestError { type_test } => { + // Try to convert the lower-bound region into something named we can print for the user. + let lower_bound_region = + self.nonlexical_regioncx.to_error_region(type_test.lower_bound); + + // Skip duplicate-ish errors. + let type_test_span = type_test.locations.span(&self.body); + + if let Some(lower_bound_region) = lower_bound_region { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + self.infcx + .construct_generic_bound_failure( + region_scope_tree, + type_test_span, + None, + type_test.generic_kind, + lower_bound_region, + ) + .buffer(&mut self.errors_buffer); + } else { + // FIXME. We should handle this case better. It indicates that we have + // e.g., some region variable whose value is like `'a+'b` where `'a` and + // `'b` are distinct unrelated univesal regions that are not known to + // outlive one another. It'd be nice to have some examples where this + // arises to decide how best to report it; we could probably handle it by + // iterating over the universal regions and reporting an error that + // multiple bounds are required. + self.infcx + .tcx + .sess + .struct_span_err( + type_test_span, + &format!("`{}` does not live long enough", type_test.generic_kind), + ) + .buffer(&mut self.errors_buffer); + } } RegionErrorKind::UnexpectedHiddenRegion { @@ -1530,8 +1534,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { RegionErrorKind::BoundUniversalRegionError { longer_fr, fr_origin, - error_region, + error_element, } => { + let error_region = + self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( &self.body, @@ -2225,7 +2232,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let upvar = &self.upvars[field.index()]; debug!( "upvar.mutability={:?} local_mutation_is_allowed={:?} \ - place={:?}", + place={:?}", upvar, is_local_mutation_allowed, place ); match (upvar.mutability, is_local_mutation_allowed) { diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 7d2384f8a7de7..baa1c5b617dca 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -838,39 +838,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { } // Type-test failed. Report the error. - - // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = self.to_error_region(type_test.lower_bound); - - // Skip duplicate-ish errors. - let type_test_span = type_test.locations.span(body); - let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind); - if !deduplicate_errors.insert(( + let erased_generic_kind = infcx.tcx.erase_regions(&type_test.generic_kind); + if deduplicate_errors.insert(( erased_generic_kind, - lower_bound_region, + type_test.lower_bound, type_test.locations, )) { - continue; - } else { debug!( "check_type_test: reporting error for erased_generic_kind={:?}, \ lower_bound_region={:?}, \ type_test.locations={:?}", - erased_generic_kind, lower_bound_region, type_test.locations, + erased_generic_kind, type_test.lower_bound, type_test.locations, ); - } - if let Some(lower_bound_region) = lower_bound_region { - errors_buffer.push(RegionErrorKind::TypeTestGenericBoundError { - span: type_test_span, - generic: type_test.generic_kind, - lower_bound_region, - }); - } else { - errors_buffer.push(RegionErrorKind::TypeTestDoesNotLiveLongEnough { - span: type_test_span, - generic: type_test.generic_kind, - }); + errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); } } } @@ -1355,7 +1336,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { for (longer_fr, shorter_fr) in subset_errors.into_iter() { debug!( "check_polonius_subset_errors: subset_error longer_fr={:?},\ - shorter_fr={:?}", + shorter_fr={:?}", longer_fr, shorter_fr ); @@ -1572,23 +1553,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("check_bound_universal_region: error_element = {:?}", error_element); // Find the region that introduced this `error_element`. - let error_region = match error_element { - RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), - RegionElement::RootUniversalRegion(r) => r, - RegionElement::PlaceholderRegion(error_placeholder) => self - .definitions - .iter_enumerated() - .filter_map(|(r, definition)| match definition.origin { - NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), - _ => None, - }) - .next() - .unwrap(), - }; - errors_buffer.push(RegionErrorKind::BoundUniversalRegionError { longer_fr, - error_region, + error_element, fr_origin: NLLRegionVariableOrigin::Placeholder(placeholder), }); } @@ -1628,6 +1595,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } } + + /// Get the region outlived by `longer_fr` and live at `element`. + crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { + match element { + RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), + RegionElement::RootUniversalRegion(r) => r, + RegionElement::PlaceholderRegion(error_placeholder) => self + .definitions + .iter_enumerated() + .filter_map(|(r, definition)| match definition.origin { + NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), + _ => None, + }) + .next() + .unwrap(), + } + } } impl<'tcx> RegionDefinition<'tcx> { diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs index e17efebfef824..3126d44014b4e 100644 --- a/src/librustc_mir/borrow_check/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/region_infer/values.rs @@ -114,7 +114,7 @@ rustc_index::newtype_index! { /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. -#[derive(Debug)] +#[derive(Debug, Clone)] crate enum RegionElement { /// A point in the control-flow graph. Location(Location), From c3e74f347e44e3a54f6ff094ef8b741589d69ab5 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:25:57 -0600 Subject: [PATCH 0291/1253] Move some methods to region_infer/mod.rs --- .../diagnostics/explain_borrow.rs | 45 +- .../borrow_check/diagnostics/region_errors.rs | 431 +----------------- .../borrow_check/region_infer/mod.rs | 395 ++++++++++++++++ 3 files changed, 440 insertions(+), 431 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index 9a0c99b07e6f1..afccf8a0922a7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -2,12 +2,13 @@ use std::collections::VecDeque; +use rustc::infer::NLLRegionVariableOrigin; use rustc::mir::{ Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc::ty::adjustment::PointerCast; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_index::vec::IndexVec; @@ -15,8 +16,8 @@ use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::borrow_check::{ - borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, - WriteKind, + borrow_set::BorrowData, diagnostics::RegionErrorNamingCtx, nll::ConstraintDescription, + region_infer::Cause, MirBorrowckCtxt, WriteKind, }; use super::{find_use, RegionName, UseSpans}; @@ -254,6 +255,32 @@ impl BorrowExplanation { } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { + fn free_region_constraint_info( + &self, + borrow_region: RegionVid, + outlived_region: RegionVid, + ) -> (ConstraintCategory, bool, Span, Option) { + let (category, from_closure, span) = self.nonlexical_regioncx.best_blame_constraint( + &self.body, + borrow_region, + NLLRegionVariableOrigin::FreeRegion, + |r| { + self.nonlexical_regioncx.provides_universal_region( + r, + borrow_region, + outlived_region, + ) + }, + ); + + let mut renctx = RegionErrorNamingCtx::new(); + let outlived_fr_name = + self.nonlexical_regioncx.give_region_a_name(self, &mut renctx, outlived_region); + // TODO(mark-i-m): just return the region and let the caller name it + + (category, from_closure, span, outlived_fr_name) + } + /// Returns structured explanation for *why* the borrow contains the /// point from `location`. This is key for the "3-point errors" /// [described in the NLL RFC][d]. @@ -285,7 +312,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_region_vid = borrow.region; debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); - let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, location); + let region_sub = + self.nonlexical_regioncx.find_sub_region_live_at(borrow_region_vid, location); debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { @@ -330,9 +358,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None => { if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) { - let (category, from_closure, span, region_name) = self - .nonlexical_regioncx - .free_region_constraint_info(self, borrow_region_vid, region); + let (category, from_closure, span, region_name) = + self.free_region_constraint_info(borrow_region_vid, region); if let Some(region_name) = region_name { let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { @@ -345,14 +372,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { debug!( "explain_why_borrow_contains_point: \ - Could not generate a region name" + Could not generate a region name" ); BorrowExplanation::Unexplained } } else { debug!( "explain_why_borrow_contains_point: \ - Could not generate an error region vid" + Could not generate an error region vid" ); BorrowExplanation::Unexplained } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index bf4a12b12a5c2..f9ec4ccb52a09 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -3,22 +3,18 @@ use rustc::infer::{ error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, }; -use rustc::mir::{Body, ConstraintCategory, Location}; +use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; use rustc_span::symbol::kw; use rustc_span::Span; -use std::collections::VecDeque; use crate::util::borrowck_errors; use crate::borrow_check::{ - constraints::OutlivesConstraint, nll::ConstraintDescription, region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, - type_check::Locations, universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -48,13 +44,6 @@ impl ConstraintDescription for ConstraintCategory { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum Trace { - StartRegion, - FromOutlivesConstraint(OutlivesConstraint), - NotVisited, -} - /// A collection of errors encountered during region inference. This is needed to efficiently /// report errors after borrow checking. /// @@ -142,270 +131,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Tries to find the best constraint to blame for the fact that - /// `R: from_region`, where `R` is some region that meets - /// `target_test`. This works by following the constraint graph, - /// creating a constraint path that forces `R` to outlive - /// `from_region`, and then finding the best choices within that - /// path to blame. - fn best_blame_constraint( - &self, - body: &Body<'tcx>, - from_region: RegionVid, - from_region_origin: NLLRegionVariableOrigin, - target_test: impl Fn(RegionVid) -> bool, - ) -> (ConstraintCategory, bool, Span) { - debug!( - "best_blame_constraint(from_region={:?}, from_region_origin={:?})", - from_region, from_region_origin - ); - - // Find all paths - let (path, target_region) = - self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); - debug!( - "best_blame_constraint: path={:#?}", - path.iter() - .map(|&c| format!( - "{:?} ({:?}: {:?})", - c, - self.constraint_sccs.scc(c.sup), - self.constraint_sccs.scc(c.sub), - )) - .collect::>() - ); - - // Classify each of the constraints along the path. - let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path - .iter() - .map(|constraint| { - if constraint.category == ConstraintCategory::ClosureBounds { - self.retrieve_closure_constraint_info(body, &constraint) - } else { - (constraint.category, false, constraint.locations.span(body)) - } - }) - .collect(); - debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); - - // To find the best span to cite, we first try to look for the - // final constraint that is interesting and where the `sup` is - // not unified with the ultimate target region. The reason - // for this is that we have a chain of constraints that lead - // from the source to the target region, something like: - // - // '0: '1 ('0 is the source) - // '1: '2 - // '2: '3 - // '3: '4 - // '4: '5 - // '5: '6 ('6 is the target) - // - // Some of those regions are unified with `'6` (in the same - // SCC). We want to screen those out. After that point, the - // "closest" constraint we have to the end is going to be the - // most likely to be the point where the value escapes -- but - // we still want to screen for an "interesting" point to - // highlight (e.g., a call site or something). - let target_scc = self.constraint_sccs.scc(target_region); - let mut range = 0..path.len(); - - // As noted above, when reporting an error, there is typically a chain of constraints - // leading from some "source" region which must outlive some "target" region. - // In most cases, we prefer to "blame" the constraints closer to the target -- - // but there is one exception. When constraints arise from higher-ranked subtyping, - // we generally prefer to blame the source value, - // as the "target" in this case tends to be some type annotation that the user gave. - // Therefore, if we find that the region origin is some instantiation - // of a higher-ranked region, we start our search from the "source" point - // rather than the "target", and we also tweak a few other things. - // - // An example might be this bit of Rust code: - // - // ```rust - // let x: fn(&'static ()) = |_| {}; - // let y: for<'a> fn(&'a ()) = x; - // ``` - // - // In MIR, this will be converted into a combination of assignments and type ascriptions. - // In particular, the 'static is imposed through a type ascription: - // - // ```rust - // x = ...; - // AscribeUserType(x, fn(&'static ()) - // y = x; - // ``` - // - // We wind up ultimately with constraints like - // - // ```rust - // !a: 'temp1 // from the `y = x` statement - // 'temp1: 'temp2 - // 'temp2: 'static // from the AscribeUserType - // ``` - // - // and here we prefer to blame the source (the y = x statement). - let blame_source = match from_region_origin { - NLLRegionVariableOrigin::FreeRegion - | NLLRegionVariableOrigin::Existential { from_forall: false } => true, - NLLRegionVariableOrigin::Placeholder(_) - | NLLRegionVariableOrigin::Existential { from_forall: true } => false, - }; - - let find_region = |i: &usize| { - let constraint = path[*i]; - - let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); - - if blame_source { - match categorized_path[*i].0 { - ConstraintCategory::OpaqueType - | ConstraintCategory::Boring - | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => false, - ConstraintCategory::TypeAnnotation - | ConstraintCategory::Return - | ConstraintCategory::Yield => true, - _ => constraint_sup_scc != target_scc, - } - } else { - match categorized_path[*i].0 { - ConstraintCategory::OpaqueType - | ConstraintCategory::Boring - | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => false, - _ => true, - } - } - }; - - let best_choice = - if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - - debug!( - "best_blame_constraint: best_choice={:?} blame_source={}", - best_choice, blame_source - ); - - if let Some(i) = best_choice { - if let Some(next) = categorized_path.get(i + 1) { - if categorized_path[i].0 == ConstraintCategory::Return - && next.0 == ConstraintCategory::OpaqueType - { - // The return expression is being influenced by the return type being - // impl Trait, point at the return type and not the return expr. - return *next; - } - } - return categorized_path[i]; - } - - // If that search fails, that is.. unusual. Maybe everything - // is in the same SCC or something. In that case, find what - // appears to be the most interesting point to report to the - // user via an even more ad-hoc guess. - categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0)); - debug!("`: sorted_path={:#?}", categorized_path); - - *categorized_path.first().unwrap() - } - - /// Walks the graph of constraints (where `'a: 'b` is considered - /// an edge `'a -> 'b`) to find all paths from `from_region` to - /// `to_region`. The paths are accumulated into the vector - /// `results`. The paths are stored as a series of - /// `ConstraintIndex` values -- in other words, a list of *edges*. - /// - /// Returns: a series of constraints as well as the region `R` - /// that passed the target test. - fn find_constraint_paths_between_regions( - &self, - from_region: RegionVid, - target_test: impl Fn(RegionVid) -> bool, - ) -> Option<(Vec, RegionVid)> { - let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions); - context[from_region] = Trace::StartRegion; - - // Use a deque so that we do a breadth-first search. We will - // stop at the first match, which ought to be the shortest - // path (fewest constraints). - let mut deque = VecDeque::new(); - deque.push_back(from_region); - - while let Some(r) = deque.pop_front() { - debug!( - "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}", - from_region, - r, - self.region_value_str(r), - ); - - // Check if we reached the region we were looking for. If so, - // we can reconstruct the path that led to it and return it. - if target_test(r) { - let mut result = vec![]; - let mut p = r; - loop { - match context[p] { - Trace::NotVisited => { - bug!("found unvisited region {:?} on path to {:?}", p, r) - } - - Trace::FromOutlivesConstraint(c) => { - result.push(c); - p = c.sup; - } - - Trace::StartRegion => { - result.reverse(); - return Some((result, r)); - } - } - } - } - - // Otherwise, walk over the outgoing constraints and - // enqueue any regions we find, keeping track of how we - // reached them. - - // A constraint like `'r: 'x` can come from our constraint - // graph. - let fr_static = self.universal_regions.fr_static; - let outgoing_edges_from_graph = - self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); - - // Always inline this closure because it can be hot. - let mut handle_constraint = #[inline(always)] - |constraint: OutlivesConstraint| { - debug_assert_eq!(constraint.sup, r); - let sub_region = constraint.sub; - if let Trace::NotVisited = context[sub_region] { - context[sub_region] = Trace::FromOutlivesConstraint(constraint); - deque.push_back(sub_region); + /// Returns `true` if a closure is inferred to be an `FnMut` closure. + crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { + if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { + if let ty::BoundRegion::BrEnv = free_region.bound_region { + if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { + let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); + return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); } - }; - - // This loop can be hot. - for constraint in outgoing_edges_from_graph { - handle_constraint(constraint); - } - - // Member constraints can also give rise to `'r: 'x` edges that - // were not part of the graph initially, so watch out for those. - // (But they are extremely rare; this loop is very cold.) - for constraint in self.applied_member_constraints(r) { - let p_c = &self.member_constraints[constraint.member_constraint_index]; - let constraint = OutlivesConstraint { - sup: r, - sub: constraint.min_choice, - locations: Locations::All(p_c.definition_span), - category: ConstraintCategory::OpaqueType, - }; - handle_constraint(constraint); } } - None + false } /// Report an error because the universal region `fr` was required to outlive @@ -484,30 +221,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// We have a constraint `fr1: fr2` that is not satisfied, where - /// `fr2` represents some universal region. Here, `r` is some - /// region where we know that `fr1: r` and this function has the - /// job of determining whether `r` is "to blame" for the fact that - /// `fr1: fr2` is required. - /// - /// This is true under two conditions: - /// - /// - `r == fr2` - /// - `fr2` is `'static` and `r` is some placeholder in a universe - /// that cannot be named by `fr1`; in that case, we will require - /// that `fr1: 'static` because it is the only way to `fr1: r` to - /// be satisfied. (See `add_incompatible_universe`.) - fn provides_universal_region(&self, r: RegionVid, fr1: RegionVid, fr2: RegionVid) -> bool { - debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); - let result = { - r == fr2 || { - fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) - } - }; - debug!("provides_universal_region: result = {:?}", result); - result - } - /// Report a specialized error when `FnMut` closures return a reference to a captured variable. /// This function expects `fr` to be local and `outlived_fr` to not be local. /// @@ -817,130 +530,4 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } } - - crate fn free_region_constraint_info( - &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, - borrow_region: RegionVid, - outlived_region: RegionVid, - ) -> (ConstraintCategory, bool, Span, Option) { - let (category, from_closure, span) = self.best_blame_constraint( - &mbcx.body, - borrow_region, - NLLRegionVariableOrigin::FreeRegion, - |r| self.provides_universal_region(r, borrow_region, outlived_region), - ); - - let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = self.give_region_a_name(mbcx, &mut renctx, outlived_region); - - (category, from_closure, span, outlived_fr_name) - } - - // Finds some region R such that `fr1: R` and `R` is live at - // `elem`. - crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { - debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); - self.find_constraint_paths_between_regions(fr1, |r| { - // First look for some `r` such that `fr1: r` and `r` is live at `elem` - debug!( - "find_sub_region_live_at: liveness_constraints for {:?} are {:?}", - r, - self.liveness_constraints.region_value_str(r), - ); - self.liveness_constraints.contains(r, elem) - }) - .or_else(|| { - // If we fail to find that, we may find some `r` such that - // `fr1: r` and `r` is a placeholder from some universe - // `fr1` cannot name. This would force `fr1` to be - // `'static`. - self.find_constraint_paths_between_regions(fr1, |r| { - self.cannot_name_placeholder(fr1, r) - }) - }) - .or_else(|| { - // If we fail to find THAT, it may be that `fr1` is a - // placeholder that cannot "fit" into its SCC. In that - // case, there should be some `r` where `fr1: r`, both - // `fr1` and `r` are in the same SCC, and `fr1` is a - // placeholder that `r` cannot name. We can blame that - // edge. - self.find_constraint_paths_between_regions(fr1, |r| { - self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) - && self.cannot_name_placeholder(r, fr1) - }) - }) - .map(|(_path, r)| r) - .unwrap() - } - - // Finds a good span to blame for the fact that `fr1` outlives `fr2`. - crate fn find_outlives_blame_span( - &self, - body: &Body<'tcx>, - fr1: RegionVid, - fr1_origin: NLLRegionVariableOrigin, - fr2: RegionVid, - ) -> (ConstraintCategory, Span) { - let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| { - self.provides_universal_region(r, fr1, fr2) - }); - (category, span) - } - - fn retrieve_closure_constraint_info( - &self, - body: &Body<'tcx>, - constraint: &OutlivesConstraint, - ) -> (ConstraintCategory, bool, Span) { - let loc = match constraint.locations { - Locations::All(span) => return (constraint.category, false, span), - Locations::Single(loc) => loc, - }; - - let opt_span_category = - self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)); - opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or(( - constraint.category, - false, - body.source_info(loc).span, - )) - } - - /// Returns `true` if a closure is inferred to be an `FnMut` closure. - crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { - if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { - if let ty::BoundRegion::BrEnv = free_region.bound_region { - if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); - return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); - } - } - } - - false - } - - /// If `r2` represents a placeholder region, then this returns - /// `true` if `r1` cannot name that placeholder in its - /// value; otherwise, returns `false`. - fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { - debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); - - match self.definitions[r2].origin { - NLLRegionVariableOrigin::Placeholder(placeholder) => { - let universe1 = self.definitions[r1].universe; - debug!( - "cannot_name_value_of: universe1={:?} placeholder={:?}", - universe1, placeholder - ); - universe1.cannot_name(placeholder.universe) - } - - NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => { - false - } - } - } } diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index baa1c5b617dca..406b28e1e3256 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -1,3 +1,4 @@ +use std::collections::VecDeque; use std::rc::Rc; use rustc::infer::canonical::QueryOutlivesConstraint; @@ -225,6 +226,13 @@ enum RegionRelationCheckResult { Error, } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum Trace { + StartRegion, + FromOutlivesConstraint(OutlivesConstraint), + NotVisited, +} + impl<'tcx> RegionInferenceContext<'tcx> { /// Creates a new region inference context with a total of /// `num_region_variables` valid inference variables; the first N @@ -1612,6 +1620,393 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap(), } } + + /// We have a constraint `fr1: fr2` that is not satisfied, where + /// `fr2` represents some universal region. Here, `r` is some + /// region where we know that `fr1: r` and this function has the + /// job of determining whether `r` is "to blame" for the fact that + /// `fr1: fr2` is required. + /// + /// This is true under two conditions: + /// + /// - `r == fr2` + /// - `fr2` is `'static` and `r` is some placeholder in a universe + /// that cannot be named by `fr1`; in that case, we will require + /// that `fr1: 'static` because it is the only way to `fr1: r` to + /// be satisfied. (See `add_incompatible_universe`.) + crate fn provides_universal_region( + &self, + r: RegionVid, + fr1: RegionVid, + fr2: RegionVid, + ) -> bool { + debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); + let result = { + r == fr2 || { + fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) + } + }; + debug!("provides_universal_region: result = {:?}", result); + result + } + + /// If `r2` represents a placeholder region, then this returns + /// `true` if `r1` cannot name that placeholder in its + /// value; otherwise, returns `false`. + crate fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { + debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); + + match self.definitions[r2].origin { + NLLRegionVariableOrigin::Placeholder(placeholder) => { + let universe1 = self.definitions[r1].universe; + debug!( + "cannot_name_value_of: universe1={:?} placeholder={:?}", + universe1, placeholder + ); + universe1.cannot_name(placeholder.universe) + } + + NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => { + false + } + } + } + + crate fn retrieve_closure_constraint_info( + &self, + body: &Body<'tcx>, + constraint: &OutlivesConstraint, + ) -> (ConstraintCategory, bool, Span) { + let loc = match constraint.locations { + Locations::All(span) => return (constraint.category, false, span), + Locations::Single(loc) => loc, + }; + + let opt_span_category = + self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)); + opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or(( + constraint.category, + false, + body.source_info(loc).span, + )) + } + + /// Finds a good span to blame for the fact that `fr1` outlives `fr2`. + crate fn find_outlives_blame_span( + &self, + body: &Body<'tcx>, + fr1: RegionVid, + fr1_origin: NLLRegionVariableOrigin, + fr2: RegionVid, + ) -> (ConstraintCategory, Span) { + let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| { + self.provides_universal_region(r, fr1, fr2) + }); + (category, span) + } + + /// Walks the graph of constraints (where `'a: 'b` is considered + /// an edge `'a -> 'b`) to find all paths from `from_region` to + /// `to_region`. The paths are accumulated into the vector + /// `results`. The paths are stored as a series of + /// `ConstraintIndex` values -- in other words, a list of *edges*. + /// + /// Returns: a series of constraints as well as the region `R` + /// that passed the target test. + crate fn find_constraint_paths_between_regions( + &self, + from_region: RegionVid, + target_test: impl Fn(RegionVid) -> bool, + ) -> Option<(Vec, RegionVid)> { + let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions); + context[from_region] = Trace::StartRegion; + + // Use a deque so that we do a breadth-first search. We will + // stop at the first match, which ought to be the shortest + // path (fewest constraints). + let mut deque = VecDeque::new(); + deque.push_back(from_region); + + while let Some(r) = deque.pop_front() { + debug!( + "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}", + from_region, + r, + self.region_value_str(r), + ); + + // Check if we reached the region we were looking for. If so, + // we can reconstruct the path that led to it and return it. + if target_test(r) { + let mut result = vec![]; + let mut p = r; + loop { + match context[p] { + Trace::NotVisited => { + bug!("found unvisited region {:?} on path to {:?}", p, r) + } + + Trace::FromOutlivesConstraint(c) => { + result.push(c); + p = c.sup; + } + + Trace::StartRegion => { + result.reverse(); + return Some((result, r)); + } + } + } + } + + // Otherwise, walk over the outgoing constraints and + // enqueue any regions we find, keeping track of how we + // reached them. + + // A constraint like `'r: 'x` can come from our constraint + // graph. + let fr_static = self.universal_regions.fr_static; + let outgoing_edges_from_graph = + self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); + + // Always inline this closure because it can be hot. + let mut handle_constraint = #[inline(always)] + |constraint: OutlivesConstraint| { + debug_assert_eq!(constraint.sup, r); + let sub_region = constraint.sub; + if let Trace::NotVisited = context[sub_region] { + context[sub_region] = Trace::FromOutlivesConstraint(constraint); + deque.push_back(sub_region); + } + }; + + // This loop can be hot. + for constraint in outgoing_edges_from_graph { + handle_constraint(constraint); + } + + // Member constraints can also give rise to `'r: 'x` edges that + // were not part of the graph initially, so watch out for those. + // (But they are extremely rare; this loop is very cold.) + for constraint in self.applied_member_constraints(r) { + let p_c = &self.member_constraints[constraint.member_constraint_index]; + let constraint = OutlivesConstraint { + sup: r, + sub: constraint.min_choice, + locations: Locations::All(p_c.definition_span), + category: ConstraintCategory::OpaqueType, + }; + handle_constraint(constraint); + } + } + + None + } + + /// Finds some region R such that `fr1: R` and `R` is live at `elem`. + crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { + debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); + self.find_constraint_paths_between_regions(fr1, |r| { + // First look for some `r` such that `fr1: r` and `r` is live at `elem` + debug!( + "find_sub_region_live_at: liveness_constraints for {:?} are {:?}", + r, + self.liveness_constraints.region_value_str(r), + ); + self.liveness_constraints.contains(r, elem) + }) + .or_else(|| { + // If we fail to find that, we may find some `r` such that + // `fr1: r` and `r` is a placeholder from some universe + // `fr1` cannot name. This would force `fr1` to be + // `'static`. + self.find_constraint_paths_between_regions(fr1, |r| { + self.cannot_name_placeholder(fr1, r) + }) + }) + .or_else(|| { + // If we fail to find THAT, it may be that `fr1` is a + // placeholder that cannot "fit" into its SCC. In that + // case, there should be some `r` where `fr1: r`, both + // `fr1` and `r` are in the same SCC, and `fr1` is a + // placeholder that `r` cannot name. We can blame that + // edge. + self.find_constraint_paths_between_regions(fr1, |r| { + self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) + && self.cannot_name_placeholder(r, fr1) + }) + }) + .map(|(_path, r)| r) + .unwrap() + } + + /// Tries to find the best constraint to blame for the fact that + /// `R: from_region`, where `R` is some region that meets + /// `target_test`. This works by following the constraint graph, + /// creating a constraint path that forces `R` to outlive + /// `from_region`, and then finding the best choices within that + /// path to blame. + crate fn best_blame_constraint( + &self, + body: &Body<'tcx>, + from_region: RegionVid, + from_region_origin: NLLRegionVariableOrigin, + target_test: impl Fn(RegionVid) -> bool, + ) -> (ConstraintCategory, bool, Span) { + debug!( + "best_blame_constraint(from_region={:?}, from_region_origin={:?})", + from_region, from_region_origin + ); + + // Find all paths + let (path, target_region) = + self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); + debug!( + "best_blame_constraint: path={:#?}", + path.iter() + .map(|&c| format!( + "{:?} ({:?}: {:?})", + c, + self.constraint_sccs.scc(c.sup), + self.constraint_sccs.scc(c.sub), + )) + .collect::>() + ); + + // Classify each of the constraints along the path. + let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path + .iter() + .map(|constraint| { + if constraint.category == ConstraintCategory::ClosureBounds { + self.retrieve_closure_constraint_info(body, &constraint) + } else { + (constraint.category, false, constraint.locations.span(body)) + } + }) + .collect(); + debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); + + // To find the best span to cite, we first try to look for the + // final constraint that is interesting and where the `sup` is + // not unified with the ultimate target region. The reason + // for this is that we have a chain of constraints that lead + // from the source to the target region, something like: + // + // '0: '1 ('0 is the source) + // '1: '2 + // '2: '3 + // '3: '4 + // '4: '5 + // '5: '6 ('6 is the target) + // + // Some of those regions are unified with `'6` (in the same + // SCC). We want to screen those out. After that point, the + // "closest" constraint we have to the end is going to be the + // most likely to be the point where the value escapes -- but + // we still want to screen for an "interesting" point to + // highlight (e.g., a call site or something). + let target_scc = self.constraint_sccs.scc(target_region); + let mut range = 0..path.len(); + + // As noted above, when reporting an error, there is typically a chain of constraints + // leading from some "source" region which must outlive some "target" region. + // In most cases, we prefer to "blame" the constraints closer to the target -- + // but there is one exception. When constraints arise from higher-ranked subtyping, + // we generally prefer to blame the source value, + // as the "target" in this case tends to be some type annotation that the user gave. + // Therefore, if we find that the region origin is some instantiation + // of a higher-ranked region, we start our search from the "source" point + // rather than the "target", and we also tweak a few other things. + // + // An example might be this bit of Rust code: + // + // ```rust + // let x: fn(&'static ()) = |_| {}; + // let y: for<'a> fn(&'a ()) = x; + // ``` + // + // In MIR, this will be converted into a combination of assignments and type ascriptions. + // In particular, the 'static is imposed through a type ascription: + // + // ```rust + // x = ...; + // AscribeUserType(x, fn(&'static ()) + // y = x; + // ``` + // + // We wind up ultimately with constraints like + // + // ```rust + // !a: 'temp1 // from the `y = x` statement + // 'temp1: 'temp2 + // 'temp2: 'static // from the AscribeUserType + // ``` + // + // and here we prefer to blame the source (the y = x statement). + let blame_source = match from_region_origin { + NLLRegionVariableOrigin::FreeRegion + | NLLRegionVariableOrigin::Existential { from_forall: false } => true, + NLLRegionVariableOrigin::Placeholder(_) + | NLLRegionVariableOrigin::Existential { from_forall: true } => false, + }; + + let find_region = |i: &usize| { + let constraint = path[*i]; + + let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); + + if blame_source { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + ConstraintCategory::TypeAnnotation + | ConstraintCategory::Return + | ConstraintCategory::Yield => true, + _ => constraint_sup_scc != target_scc, + } + } else { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + _ => true, + } + } + }; + + let best_choice = + if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; + + debug!( + "best_blame_constraint: best_choice={:?} blame_source={}", + best_choice, blame_source + ); + + if let Some(i) = best_choice { + if let Some(next) = categorized_path.get(i + 1) { + if categorized_path[i].0 == ConstraintCategory::Return + && next.0 == ConstraintCategory::OpaqueType + { + // The return expression is being influenced by the return type being + // impl Trait, point at the return type and not the return expr. + return *next; + } + } + return categorized_path[i]; + } + + // If that search fails, that is.. unusual. Maybe everything + // is in the same SCC or something. In that case, find what + // appears to be the most interesting point to report to the + // user via an even more ad-hoc guess. + categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0)); + debug!("`: sorted_path={:#?}", categorized_path); + + *categorized_path.first().unwrap() + } } impl<'tcx> RegionDefinition<'tcx> { From 736348ac41b00657bd8d5d6b8acae1eeef9985c7 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 20 Dec 2019 23:59:31 -0600 Subject: [PATCH 0292/1253] Move a bunch of methods to inherent impl MirBorrowckCtxt --- .../diagnostics/explain_borrow.rs | 6 +- .../diagnostics/outlives_suggestion.rs | 4 +- .../borrow_check/diagnostics/region_errors.rs | 144 +++++++++--------- .../borrow_check/diagnostics/region_name.rs | 111 +++++++------- src/librustc_mir/borrow_check/mod.rs | 10 +- 5 files changed, 130 insertions(+), 145 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index afccf8a0922a7..45c6c845cd156 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -274,9 +274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = - self.nonlexical_regioncx.give_region_a_name(self, &mut renctx, outlived_region); - // TODO(mark-i-m): just return the region and let the caller name it + let outlived_fr_name = self.give_region_a_name(&mut renctx, outlived_region); (category, from_closure, span, outlived_fr_name) } @@ -357,7 +355,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } None => { - if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) { + if let Some(region) = self.to_error_region_vid(borrow_region_vid) { let (category, from_closure, span, region_name) = self.free_region_constraint_info(borrow_region_vid, region); if let Some(region_name) = region_name { diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index 1425c22e461cf..be067fcf4f261 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -80,9 +80,7 @@ impl OutlivesSuggestionBuilder { renctx: &mut RegionErrorNamingCtx, region: RegionVid, ) -> Option { - mbcx.nonlexical_regioncx - .give_region_a_name(mbcx, renctx, region) - .filter(Self::region_name_is_suggestable) + mbcx.give_region_a_name(renctx, region).filter(Self::region_name_is_suggestable) } /// Compiles a list of all suggestions to be printed in the final big suggestion. diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index f9ec4ccb52a09..b0be82164d876 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,8 +1,6 @@ //! Error reporting machinery for lifetime errors. -use rustc::infer::{ - error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, -}; +use rustc::infer::{error_reporting::nice_region_error::NiceRegionError, NLLRegionVariableOrigin}; use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; @@ -14,7 +12,7 @@ use crate::util::borrowck_errors; use crate::borrow_check::{ nll::ConstraintDescription, - region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, + region_infer::{values::RegionElement, TypeTest}, universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -104,26 +102,28 @@ pub struct ErrorConstraintInfo { pub(super) span: Span, } -impl<'tcx> RegionInferenceContext<'tcx> { +impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is /// existentially bound, then we check its inferred value and try /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). - pub fn to_error_region(&self, r: RegionVid) -> Option> { - self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name) + // TODO(mark-i-m): make this private when we move report_region_errors here... + crate fn to_error_region(&self, r: RegionVid) -> Option> { + self.to_error_region_vid(r) + .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) } - /// Returns the [RegionVid] corresponding to the region returned by + /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. - pub fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.universal_regions.is_universal_region(r) { + pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { + if self.nonlexical_regioncx.universal_regions.is_universal_region(r) { Some(r) } else { - let r_scc = self.constraint_sccs.scc(r); - let upper_bound = self.universal_upper_bound(r); - if self.scc_values.contains(r_scc, upper_bound) { + let r_scc = self.nonlexical_regioncx.constraint_sccs.scc(r); + let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); + if self.nonlexical_regioncx.scc_values.contains(r_scc, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -132,11 +132,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns `true` if a closure is inferred to be an `FnMut` closure. - crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { + fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { - if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); + if let DefiningTy::Closure(def_id, substs) = + self.nonlexical_regioncx.universal_regions.defining_ty + { + let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); } } @@ -153,34 +155,35 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` /// /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`. - pub(in crate::borrow_check) fn report_error<'a>( - &'a self, - mbcx: &MirBorrowckCtxt<'a, 'tcx>, + pub(in crate::borrow_check) fn report_error( + &mut self, fr: RegionVid, fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'a> { + ) { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - let (category, _, span) = self.best_blame_constraint(&mbcx.body, fr, fr_origin, |r| { - self.provides_universal_region(r, fr, outlived_fr) - }); + let (category, _, span) = + self.nonlexical_regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { + self.nonlexical_regioncx.provides_universal_region(r, fr, outlived_fr) + }); debug!("report_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - let tables = mbcx.infcx.tcx.typeck_tables_of(mbcx.mir_def_id); - let nice = NiceRegionError::new_from_span(mbcx.infcx, span, o, f, Some(tables)); + let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id); + let nice = NiceRegionError::new_from_span(self.infcx, span, o, f, Some(tables)); if let Some(diag) = nice.try_report_from_nll() { - return diag; + diag.buffer(&mut self.errors_buffer); + return; } } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.universal_regions.is_local_free_region(fr), - self.universal_regions.is_local_free_region(outlived_fr), + self.nonlexical_regioncx.universal_regions.is_local_free_region(fr), + self.nonlexical_regioncx.universal_regions.is_local_free_region(outlived_fr), ); debug!( @@ -197,28 +200,30 @@ impl<'tcx> RegionInferenceContext<'tcx> { span, }; - match (category, fr_is_local, outlived_fr_is_local) { - (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(mbcx.infcx, fr) => { - self.report_fnmut_error(mbcx, &errci, renctx) + let diag = match (category, fr_is_local, outlived_fr_is_local) { + (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => { + self.report_fnmut_error(&errci, renctx) } (ConstraintCategory::Assignment, true, false) | (ConstraintCategory::CallArgument, true, false) => { - let mut db = self.report_escaping_data_error(mbcx, &errci, renctx); + let mut db = self.report_escaping_data_error(&errci, renctx); - outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } _ => { - let mut db = self.report_general_error(mbcx, &errci, renctx); + let mut db = self.report_general_error(&errci, renctx); - outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } - } + }; + + diag.buffer(&mut self.errors_buffer); } /// Report a specialized error when `FnMut` closures return a reference to a captured variable. @@ -239,13 +244,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_fnmut_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; - let mut diag = mbcx + let mut diag = self .infcx .tcx .sess @@ -253,7 +257,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. - let return_type_is_closure = self.universal_regions.unnormalized_output_ty.is_closure(); + let return_type_is_closure = + self.nonlexical_regioncx.universal_regions.unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -263,7 +268,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.span_label(*span, message); - match self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap().source { + match self.give_region_a_name(renctx, *outlived_fr).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -300,28 +305,27 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_escaping_data_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; - let fr_name_and_span = self.get_var_name_and_span_for_region( - mbcx.infcx.tcx, - &mbcx.body, - &mbcx.local_names, - &mbcx.upvars, + let fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + self.infcx.tcx, + &self.body, + &self.local_names, + &self.upvars, errci.fr, ); - let outlived_fr_name_and_span = self.get_var_name_and_span_for_region( - mbcx.infcx.tcx, - &mbcx.body, - &mbcx.local_names, - &mbcx.upvars, + let outlived_fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + self.infcx.tcx, + &self.body, + &self.local_names, + &self.upvars, errci.outlived_fr, ); - let escapes_from = match self.universal_regions.defining_ty { + let escapes_from = match self.nonlexical_regioncx.universal_regions.defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", @@ -335,14 +339,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { || escapes_from == "const" { return self.report_general_error( - mbcx, &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, renctx, ); } let mut diag = - borrowck_errors::borrowed_data_escapes_closure(mbcx.infcx.tcx, *span, escapes_from); + borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( @@ -386,10 +389,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_general_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { fr, fr_is_local, @@ -401,14 +403,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { } = errci; let mut diag = - mbcx.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); + self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); let mir_def_name = - if mbcx.infcx.tcx.is_closure(mbcx.mir_def_id) { "closure" } else { "function" }; + if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; - let fr_name = self.give_region_a_name(mbcx, renctx, *fr).unwrap(); + let fr_name = self.give_region_a_name(renctx, *fr).unwrap(); fr_name.highlight_region_name(&mut diag); - let outlived_fr_name = self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap(); + let outlived_fr_name = self.give_region_a_name(renctx, *outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); match (category, outlived_fr_is_local, fr_is_local) { @@ -435,7 +437,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - self.add_static_impl_trait_suggestion(mbcx.infcx, &mut diag, *fr, fr_name, *outlived_fr); + self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); diag } @@ -451,8 +453,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn add_static_impl_trait_suggestion( &self, - infcx: &InferCtxt<'_, 'tcx>, - diag: &mut DiagnosticBuilder<'_>, + diag: &mut DiagnosticBuilder<'tcx>, fr: RegionVid, // We need to pass `fr_name` - computing it again will label it twice. fr_name: RegionName, @@ -461,11 +462,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let (Some(f), Some(ty::RegionKind::ReStatic)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = infcx + if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = self + .infcx .tcx .is_suitable_region(f) .map(|r| r.def_id) - .map(|id| infcx.tcx.return_type_impl_trait(id)) + .map(|id| self.infcx.tcx.return_type_impl_trait(id)) .unwrap_or(None) { // Check whether or not the impl trait return type is intended to capture @@ -473,8 +475,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // // eg. check for `impl Trait + 'static` instead of `impl Trait`. let has_static_predicate = { - let predicates_of = infcx.tcx.predicates_of(*did); - let bounds = predicates_of.instantiate(infcx.tcx, substs); + let predicates_of = self.infcx.tcx.predicates_of(*did); + let bounds = predicates_of.instantiate(self.infcx.tcx, substs); let mut found = false; for predicate in bounds.predicates { @@ -502,8 +504,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.help(&format!("consider replacing `{}` with `{}`", fr_name, static_str)); } else { // Otherwise, we should suggest adding a constraint on the return type. - let span = infcx.tcx.def_span(*did); - if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(span) { + let span = self.infcx.tcx.def_span(*did); + if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { let suggestable_fr_name = if fr_name.was_named() { fr_name.to_string() } else { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 734e3861c62de..e5dfb0f70eee2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display}; use rustc::ty::print::RegionHighlightMode; use rustc::ty::subst::{GenericArgKind, SubstsRef}; -use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc::ty::{self, RegionVid, Ty}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; @@ -10,10 +10,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_span::symbol::kw; use rustc_span::{symbol::Symbol, Span, DUMMY_SP}; -use crate::borrow_check::{ - nll::ToRegionVid, region_infer::RegionInferenceContext, universal_regions::DefiningTy, - MirBorrowckCtxt, -}; +use crate::borrow_check::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. @@ -161,7 +158,7 @@ impl Display for RegionName { } } -impl<'tcx> RegionInferenceContext<'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// Maps from an internal MIR region vid to something that we can /// report to the user. In some cases, the region vids will map /// directly to lifetimes that the user has a name for (e.g., @@ -189,24 +186,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// and then return the name `'1` for us to use. crate fn give_region_a_name( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, renctx: &mut RegionErrorNamingCtx, fr: RegionVid, ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.universal_regions.is_universal_region(fr)); + assert!(self.nonlexical_regioncx.universal_regions.is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); } let value = self - .give_name_from_error_region(mbcx, fr, renctx) - .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_output(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(mbcx, fr, renctx)); + .give_name_from_error_region(fr, renctx) + .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr, renctx)); if let Some(ref value) = value { renctx.insert(fr, value.clone()); @@ -222,13 +218,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// named variants. fn give_name_from_error_region( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { let error_region = self.to_error_region(fr)?; - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; debug!("give_region_a_name: error_region = {:?}", error_region); match error_region { @@ -276,13 +271,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } ty::BoundRegion::BrEnv => { - let mir_hir_id = mbcx + let mir_hir_id = self .infcx .tcx .hir() - .as_local_hir_id(mbcx.mir_def_id) + .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.universal_regions.defining_ty; + let def_ty = self.nonlexical_regioncx.universal_regions.defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -346,38 +341,34 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_arguments( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); - let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, fr)?; - - let arg_ty = - self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index]; - if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument( - mbcx, - fr, - arg_ty, - argument_index, - renctx, - ) { + let implicit_inputs = + self.nonlexical_regioncx.universal_regions.defining_ty.implicit_inputs(); + let argument_index = + self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; + + let arg_ty = self.nonlexical_regioncx.universal_regions.unnormalized_input_tys + [implicit_inputs + argument_index]; + if let Some(region_name) = + self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) + { return Some(region_name); } - self.give_name_if_we_cannot_match_hir_ty(mbcx, fr, arg_ty, renctx) + self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty, renctx) } fn give_name_if_we_can_match_hir_ty_from_argument( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_index: usize, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let mir_hir_id = mbcx.infcx.tcx.hir().as_local_hir_id(mbcx.mir_def_id)?; - let fn_decl = mbcx.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; + let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?; + let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like @@ -388,7 +379,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { hir::TyKind::Infer => None, _ => self.give_name_if_we_can_match_hir_ty( - mbcx.infcx.tcx, needle_fr, argument_ty, argument_hir_ty, @@ -410,7 +400,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_we_cannot_match_hir_ty( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, renctx: &mut RegionErrorNamingCtx, @@ -418,7 +407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let counter = renctx.counter; let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); - let type_name = mbcx.infcx.extract_type_name(&argument_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0; debug!( "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", @@ -426,10 +415,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, needle_fr)?; - let (_, span) = self.get_argument_name_and_span_for_region( - &mbcx.body, - &mbcx.local_names, + let argument_index = self + .nonlexical_regioncx + .get_argument_index_for_region(self.infcx.tcx, needle_fr)?; + let (_, span) = self.nonlexical_regioncx.get_argument_name_and_span_for_region( + &self.body, + &self.local_names, argument_index, ); @@ -470,7 +461,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// to highlighting that closest type instead. fn give_name_if_we_can_match_hir_ty( &self, - tcx: TyCtxt<'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_hir_ty: &hir::Ty<'_>, @@ -495,7 +485,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let region_name = renctx.synthesize_region_name(); // Just grab the first character, the `&`. - let source_map = tcx.sess.source_map(); + let source_map = self.infcx.tcx.sess.source_map(); let ampersand_span = source_map.start_point(hir_ty.span); return Some(RegionName { @@ -665,13 +655,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_upvars( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let upvar_index = self.get_upvar_index_for_region(mbcx.infcx.tcx, fr)?; - let (upvar_name, upvar_span) = - self.get_upvar_name_and_span_for_region(mbcx.infcx.tcx, &mbcx.upvars, upvar_index); + let upvar_index = + self.nonlexical_regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; + let (upvar_name, upvar_span) = self.nonlexical_regioncx.get_upvar_name_and_span_for_region( + self.infcx.tcx, + &self.upvars, + upvar_index, + ); let region_name = renctx.synthesize_region_name(); Some(RegionName { @@ -686,13 +679,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// or be early bound (named, not in argument). fn give_name_if_anonymous_region_appears_in_output( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; - let return_ty = self.universal_regions.unnormalized_output_ty; + let return_ty = self.nonlexical_regioncx.universal_regions.unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -700,9 +692,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = mbcx.infcx.extract_type_name(&return_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); let (return_span, mir_description) = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { @@ -719,7 +711,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { kind: hir::ImplItemKind::Method(method_sig, _), .. }) => (method_sig.decl.output.span(), ""), - _ => (mbcx.body.span, ""), + _ => (self.body.span, ""), }; Some(RegionName { @@ -737,16 +729,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_anonymous_region_appears_in_yield_ty( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.universal_regions.yield_ty?; + let yield_ty = self.nonlexical_regioncx.universal_regions.yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { return None; @@ -754,15 +745,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = mbcx.infcx.extract_type_name(&yield_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); let yield_span = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, _, span, _), .. }) => (tcx.sess.source_map().end_point(*span)), - _ => mbcx.body.span, + _ => self.body.span, }; debug!( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index fc1b723c27120..209df021ba0d1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1471,7 +1471,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are // buffered in the `MirBorrowckCtxt`. - // FIXME(mark-i-m): Would be great to get rid of the naming context. + // TODO(mark-i-m): Would be great to get rid of the naming context. let mut region_naming = RegionErrorNamingCtx::new(); let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); @@ -1479,8 +1479,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match nll_error { RegionErrorKind::TypeTestError { type_test } => { // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = - self.nonlexical_regioncx.to_error_region(type_test.lower_bound); + let lower_bound_region = self.to_error_region(type_test.lower_bound); // Skip duplicate-ish errors. let type_test_span = type_test.locations.span(&self.body); @@ -1557,16 +1556,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { if is_reported { - let db = self.nonlexical_regioncx.report_error( - self, + self.report_error( longer_fr, fr_origin, shorter_fr, &mut outlives_suggestion, &mut region_naming, ); - - db.buffer(&mut self.errors_buffer); } else { // We only report the first error, so as not to overwhelm the user. See // `RegRegionErrorKind` docs. From 786db7399fa8214aa2412fbeb18033524bfa8b34 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:28:50 -0600 Subject: [PATCH 0293/1253] Move report_region_errors to region_errors.rs --- .../borrow_check/diagnostics/region_errors.rs | 126 +++++++++++++++++- src/librustc_mir/borrow_check/mod.rs | 123 +---------------- 2 files changed, 125 insertions(+), 124 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index b0be82164d876..5980ff0073253 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,6 +1,8 @@ //! Error reporting machinery for lifetime errors. -use rustc::infer::{error_reporting::nice_region_error::NiceRegionError, NLLRegionVariableOrigin}; +use rustc::infer::{ + error_reporting::nice_region_error::NiceRegionError, opaque_types, NLLRegionVariableOrigin, +}; use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; @@ -109,8 +111,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// existentially bound, then we check its inferred value and try /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). - // TODO(mark-i-m): make this private when we move report_region_errors here... - crate fn to_error_region(&self, r: RegionVid) -> Option> { + pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { self.to_error_region_vid(r) .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) } @@ -147,6 +148,125 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { false } + /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`. + pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) { + // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are + // buffered in the `MirBorrowckCtxt`. + + // TODO(mark-i-m): Would be great to get rid of the naming context. + let mut region_naming = RegionErrorNamingCtx::new(); + let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); + + for nll_error in nll_errors.into_iter() { + match nll_error { + RegionErrorKind::TypeTestError { type_test } => { + // Try to convert the lower-bound region into something named we can print for the user. + let lower_bound_region = self.to_error_region(type_test.lower_bound); + + // Skip duplicate-ish errors. + let type_test_span = type_test.locations.span(&self.body); + + if let Some(lower_bound_region) = lower_bound_region { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + self.infcx + .construct_generic_bound_failure( + region_scope_tree, + type_test_span, + None, + type_test.generic_kind, + lower_bound_region, + ) + .buffer(&mut self.errors_buffer); + } else { + // FIXME. We should handle this case better. It + // indicates that we have e.g., some region variable + // whose value is like `'a+'b` where `'a` and `'b` are + // distinct unrelated univesal regions that are not + // known to outlive one another. It'd be nice to have + // some examples where this arises to decide how best + // to report it; we could probably handle it by + // iterating over the universal regions and reporting + // an error that multiple bounds are required. + self.infcx + .tcx + .sess + .struct_span_err( + type_test_span, + &format!("`{}` does not live long enough", type_test.generic_kind), + ) + .buffer(&mut self.errors_buffer); + } + } + + RegionErrorKind::UnexpectedHiddenRegion { + opaque_type_def_id, + hidden_ty, + member_region, + } => { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + opaque_types::unexpected_hidden_region_diagnostic( + self.infcx.tcx, + Some(region_scope_tree), + opaque_type_def_id, + hidden_ty, + member_region, + ) + .buffer(&mut self.errors_buffer); + } + + RegionErrorKind::BoundUniversalRegionError { + longer_fr, + fr_origin, + error_element, + } => { + let error_region = + self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + + // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. + let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( + &self.body, + longer_fr, + fr_origin, + error_region, + ); + + // FIXME: improve this error message + self.infcx + .tcx + .sess + .struct_span_err(span, "higher-ranked subtype error") + .buffer(&mut self.errors_buffer); + } + + RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { + if is_reported { + self.report_error( + longer_fr, + fr_origin, + shorter_fr, + &mut outlives_suggestion, + &mut region_naming, + ); + } else { + // We only report the first error, so as not to overwhelm the user. See + // `RegRegionErrorKind` docs. + // + // FIXME: currently we do nothing with these, but perhaps we can do better? + // FIXME: try collecting these constraints on the outlives suggestion + // builder. Does it make the suggestions any better? + debug!( + "Unreported region error: can't prove that {:?}: {:?}", + longer_fr, shorter_fr + ); + } + } + } + } + + // Emit one outlives suggestions for each MIR def we borrowck + outlives_suggestion.add_suggestion(self, &mut region_naming); + } + /// Report an error because the universal region `fr` was required to outlive /// `outlived_fr` but it is not known to do so. For example: /// diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 209df021ba0d1..22037ac6c81b2 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1,6 +1,6 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use rustc::infer::{opaque_types, InferCtxt}; +use rustc::infer::InferCtxt; use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ @@ -39,9 +39,7 @@ use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::MirSource; -use self::diagnostics::{ - AccessKind, OutlivesSuggestionBuilder, RegionErrorKind, RegionErrorNamingCtx, RegionErrors, -}; +use self::diagnostics::AccessKind; use self::flows::Flows; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -1465,123 +1463,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // initial reservation. } } - - /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`. - fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) { - // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are - // buffered in the `MirBorrowckCtxt`. - - // TODO(mark-i-m): Would be great to get rid of the naming context. - let mut region_naming = RegionErrorNamingCtx::new(); - let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); - - for nll_error in nll_errors.into_iter() { - match nll_error { - RegionErrorKind::TypeTestError { type_test } => { - // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = self.to_error_region(type_test.lower_bound); - - // Skip duplicate-ish errors. - let type_test_span = type_test.locations.span(&self.body); - - if let Some(lower_bound_region) = lower_bound_region { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - self.infcx - .construct_generic_bound_failure( - region_scope_tree, - type_test_span, - None, - type_test.generic_kind, - lower_bound_region, - ) - .buffer(&mut self.errors_buffer); - } else { - // FIXME. We should handle this case better. It indicates that we have - // e.g., some region variable whose value is like `'a+'b` where `'a` and - // `'b` are distinct unrelated univesal regions that are not known to - // outlive one another. It'd be nice to have some examples where this - // arises to decide how best to report it; we could probably handle it by - // iterating over the universal regions and reporting an error that - // multiple bounds are required. - self.infcx - .tcx - .sess - .struct_span_err( - type_test_span, - &format!("`{}` does not live long enough", type_test.generic_kind), - ) - .buffer(&mut self.errors_buffer); - } - } - - RegionErrorKind::UnexpectedHiddenRegion { - opaque_type_def_id, - hidden_ty, - member_region, - } => { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - opaque_types::unexpected_hidden_region_diagnostic( - self.infcx.tcx, - Some(region_scope_tree), - opaque_type_def_id, - hidden_ty, - member_region, - ) - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::BoundUniversalRegionError { - longer_fr, - fr_origin, - error_element, - } => { - let error_region = - self.nonlexical_regioncx.region_from_element(longer_fr, error_element); - - // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( - &self.body, - longer_fr, - fr_origin, - error_region, - ); - - // FIXME: improve this error message - self.infcx - .tcx - .sess - .struct_span_err(span, "higher-ranked subtype error") - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { - if is_reported { - self.report_error( - longer_fr, - fr_origin, - shorter_fr, - &mut outlives_suggestion, - &mut region_naming, - ); - } else { - // We only report the first error, so as not to overwhelm the user. See - // `RegRegionErrorKind` docs. - // - // FIXME: currently we do nothing with these, but perhaps we can do better? - // FIXME: try collecting these constraints on the outlives suggestion - // builder. Does it make the suggestions any better? - debug!( - "Unreported region error: can't prove that {:?}: {:?}", - longer_fr, shorter_fr - ); - } - } - } - } - - // Emit one outlives suggestions for each MIR def we borrowck - outlives_suggestion.add_suggestion(self, &mut region_naming); - } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { From 66c5d5b70697dd98468a88b455dc99681c810db1 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:35:18 -0600 Subject: [PATCH 0294/1253] Privatize the fields of RegionInferenceContext --- .../borrow_check/diagnostics/region_errors.rs | 18 +++--- .../borrow_check/diagnostics/region_name.rs | 12 ++-- .../borrow_check/diagnostics/var_name.rs | 16 ++--- .../borrow_check/region_infer/mod.rs | 63 ++++++++++++++----- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 5980ff0073253..dcba790ad7e48 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -113,18 +113,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// one (e.g., this is just some random part of the CFG). pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { self.to_error_region_vid(r) - .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) + .and_then(|r| self.nonlexical_regioncx.region_definition(r).external_name) } /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.nonlexical_regioncx.universal_regions.is_universal_region(r) { + if self.nonlexical_regioncx.universal_regions().is_universal_region(r) { Some(r) } else { - let r_scc = self.nonlexical_regioncx.constraint_sccs.scc(r); let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); - if self.nonlexical_regioncx.scc_values.contains(r_scc, upper_bound) { + + if self.nonlexical_regioncx.upper_bound_in_region_scc(r, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -137,7 +137,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { if let DefiningTy::Closure(def_id, substs) = - self.nonlexical_regioncx.universal_regions.defining_ty + self.nonlexical_regioncx.universal_regions().defining_ty { let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); @@ -302,8 +302,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.nonlexical_regioncx.universal_regions.is_local_free_region(fr), - self.nonlexical_regioncx.universal_regions.is_local_free_region(outlived_fr), + self.nonlexical_regioncx.universal_regions().is_local_free_region(fr), + self.nonlexical_regioncx.universal_regions().is_local_free_region(outlived_fr), ); debug!( @@ -378,7 +378,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. let return_type_is_closure = - self.nonlexical_regioncx.universal_regions.unnormalized_output_ty.is_closure(); + self.nonlexical_regioncx.universal_regions().unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -445,7 +445,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.nonlexical_regioncx.universal_regions.defining_ty { + let escapes_from = match self.nonlexical_regioncx.universal_regions().defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index e5dfb0f70eee2..b6bfa30b4dcdf 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -191,7 +191,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.nonlexical_regioncx.universal_regions.is_universal_region(fr)); + assert!(self.nonlexical_regioncx.universal_regions().is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); @@ -277,7 +277,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .hir() .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.nonlexical_regioncx.universal_regions.defining_ty; + let def_ty = self.nonlexical_regioncx.universal_regions().defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -345,11 +345,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { renctx: &mut RegionErrorNamingCtx, ) -> Option { let implicit_inputs = - self.nonlexical_regioncx.universal_regions.defining_ty.implicit_inputs(); + self.nonlexical_regioncx.universal_regions().defining_ty.implicit_inputs(); let argument_index = self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; - let arg_ty = self.nonlexical_regioncx.universal_regions.unnormalized_input_tys + let arg_ty = self.nonlexical_regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) @@ -684,7 +684,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { let tcx = self.infcx.tcx; - let return_ty = self.nonlexical_regioncx.universal_regions.unnormalized_output_ty; + let return_ty = self.nonlexical_regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -734,7 +734,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.nonlexical_regioncx.universal_regions.yield_ty?; + let yield_ty = self.nonlexical_regioncx.universal_regions().yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); let tcx = self.infcx.tcx; diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/src/librustc_mir/borrow_check/diagnostics/var_name.rs index 9e3d2a7d5f63c..5f3585ce8b119 100644 --- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/var_name.rs @@ -16,7 +16,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr: RegionVid, ) -> Option<(Option, Span)> { debug!("get_var_name_and_span_for_region(fr={:?})", fr); - assert!(self.universal_regions.is_universal_region(fr)); + assert!(self.universal_regions().is_universal_region(fr)); debug!("get_var_name_and_span_for_region: attempting upvar"); self.get_upvar_index_for_region(tcx, fr) @@ -35,7 +35,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Search the upvars (if any) to find one that references fr. Return its index. crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option { let upvar_index = - self.universal_regions.defining_ty.upvar_tys(tcx).position(|upvar_ty| { + self.universal_regions().defining_ty.upvar_tys(tcx).position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); tcx.any_free_region_meets(&upvar_ty, |r| { let r = r.to_region_vid(); @@ -44,7 +44,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) })?; - let upvar_ty = self.universal_regions.defining_ty.upvar_tys(tcx).nth(upvar_index); + let upvar_ty = self.universal_regions().defining_ty.upvar_tys(tcx).nth(upvar_index); debug!( "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}", @@ -85,9 +85,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { tcx: TyCtxt<'tcx>, fr: RegionVid, ) -> Option { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); let argument_index = - self.universal_regions.unnormalized_input_tys.iter().skip(implicit_inputs).position( + self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position( |arg_ty| { debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty); tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) @@ -96,7 +96,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!( "get_argument_index_for_region: found {:?} in argument {} which has type {:?}", - fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index], + fr, + argument_index, + self.universal_regions().unnormalized_input_tys[argument_index], ); Some(argument_index) @@ -110,7 +112,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { local_names: &IndexVec>, argument_index: usize, ) -> (Option, Span) { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); let argument_local = Local::new(implicit_inputs + argument_index + 1); debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local); diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 406b28e1e3256..359f75cac8376 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -44,49 +44,48 @@ pub struct RegionInferenceContext<'tcx> { /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came /// from as well as its final inferred value. - pub(in crate::borrow_check) definitions: IndexVec>, + definitions: IndexVec>, /// The liveness constraints added to each region. For most /// regions, these start out empty and steadily grow, though for /// each universally quantified region R they start out containing /// the entire CFG and `end(R)`. - pub(in crate::borrow_check) liveness_constraints: LivenessValues, + liveness_constraints: LivenessValues, /// The outlives constraints computed by the type-check. - pub(in crate::borrow_check) constraints: Rc, + constraints: Rc, /// The constraint-set, but in graph form, making it easy to traverse /// the constraints adjacent to a particular region. Used to construct /// the SCC (see `constraint_sccs`) and for error reporting. - pub(in crate::borrow_check) constraint_graph: Rc, + constraint_graph: Rc, /// The SCC computed from `constraints` and the constraint /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. - pub(in crate::borrow_check) constraint_sccs: Rc>, + constraint_sccs: Rc>, /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` /// exists if `B: A`. Computed lazilly. - pub(in crate::borrow_check) rev_constraint_graph: Option>>, + rev_constraint_graph: Option>>, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. - pub(in crate::borrow_check) member_constraints: - Rc>, + member_constraints: Rc>, /// Records the member constraints that we applied to each scc. /// This is useful for error reporting. Once constraint /// propagation is done, this vector is sorted according to /// `member_region_scc`. - pub(in crate::borrow_check) member_constraints_applied: Vec, + member_constraints_applied: Vec, /// Map closure bounds to a `Span` that should be used for error reporting. - pub(in crate::borrow_check) closure_bounds_mapping: + closure_bounds_mapping: FxHashMap>, /// Contains the minimum universe of any variable within the same /// SCC. We will ensure that no SCC contains values that are not /// visible from this index. - pub(in crate::borrow_check) scc_universes: IndexVec, + scc_universes: IndexVec, /// Contains a "representative" from each SCC. This will be the /// minimal RegionVid belonging to that universe. It is used as a @@ -95,23 +94,23 @@ pub struct RegionInferenceContext<'tcx> { /// of its SCC and be sure that -- if they have the same repr -- /// they *must* be equal (though not having the same repr does not /// mean they are unequal). - pub(in crate::borrow_check) scc_representatives: IndexVec, + scc_representatives: IndexVec, /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, /// you first find which scc it is a part of. - pub(in crate::borrow_check) scc_values: RegionValues, + scc_values: RegionValues, /// Type constraints that we check after solving. - pub(in crate::borrow_check) type_tests: Vec>, + type_tests: Vec>, /// Information about the universally quantified regions in scope /// on this function. - pub(in crate::borrow_check) universal_regions: Rc>, + universal_regions: Rc>, /// Information about how the universally quantified regions in /// scope on this function relate to one another. - pub(in crate::borrow_check) universal_region_relations: Rc>, + universal_region_relations: Rc>, } /// Each time that `apply_member_constraint` is successful, it appends @@ -1840,6 +1839,38 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap() } + /// Get the region outlived by `longer_fr` and live at `element`. + crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { + match element { + RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), + RegionElement::RootUniversalRegion(r) => r, + RegionElement::PlaceholderRegion(error_placeholder) => self + .definitions + .iter_enumerated() + .filter_map(|(r, definition)| match definition.origin { + NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), + _ => None, + }) + .next() + .unwrap(), + } + } + + /// Get the region definition of `r`. + crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> { + &self.definitions[r] + } + + /// Check if the SCC of `r` contains `upper`. + crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool { + let r_scc = self.constraint_sccs.scc(r); + self.scc_values.contains(r_scc, upper) + } + + crate fn universal_regions(&self) -> Rc> { + self.universal_regions.clone() + } + /// Tries to find the best constraint to blame for the fact that /// `R: from_region`, where `R` is some region that meets /// `target_test`. This works by following the constraint graph, From 234b9301087ac21dd1dec5e6cad59cb76346ee6c Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 20:02:20 -0600 Subject: [PATCH 0295/1253] rename nonlexical_regioncx -> regioncx --- .../diagnostics/explain_borrow.rs | 15 +++------ .../borrow_check/diagnostics/region_errors.rs | 32 +++++++++---------- .../borrow_check/diagnostics/region_name.rs | 28 +++++++--------- src/librustc_mir/borrow_check/mod.rs | 7 ++-- 4 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index 45c6c845cd156..ca5cf5bc741a0 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -260,17 +260,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_region: RegionVid, outlived_region: RegionVid, ) -> (ConstraintCategory, bool, Span, Option) { - let (category, from_closure, span) = self.nonlexical_regioncx.best_blame_constraint( + let (category, from_closure, span) = self.regioncx.best_blame_constraint( &self.body, borrow_region, NLLRegionVariableOrigin::FreeRegion, - |r| { - self.nonlexical_regioncx.provides_universal_region( - r, - borrow_region, - outlived_region, - ) - }, + |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region), ); let mut renctx = RegionErrorNamingCtx::new(); @@ -303,15 +297,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location, borrow, kind_place ); - let regioncx = &self.nonlexical_regioncx; + let regioncx = &self.regioncx; let body: &Body<'_> = &self.body; let tcx = self.infcx.tcx; let borrow_region_vid = borrow.region; debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); - let region_sub = - self.nonlexical_regioncx.find_sub_region_live_at(borrow_region_vid, location); + let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location); debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index dcba790ad7e48..f3dc8e72e3016 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -112,19 +112,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { - self.to_error_region_vid(r) - .and_then(|r| self.nonlexical_regioncx.region_definition(r).external_name) + self.to_error_region_vid(r).and_then(|r| self.regioncx.region_definition(r).external_name) } /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.nonlexical_regioncx.universal_regions().is_universal_region(r) { + if self.regioncx.universal_regions().is_universal_region(r) { Some(r) } else { - let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); + let upper_bound = self.regioncx.universal_upper_bound(r); - if self.nonlexical_regioncx.upper_bound_in_region_scc(r, upper_bound) { + if self.regioncx.upper_bound_in_region_scc(r, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -137,7 +136,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { if let DefiningTy::Closure(def_id, substs) = - self.nonlexical_regioncx.universal_regions().defining_ty + self.regioncx.universal_regions().defining_ty { let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); @@ -219,11 +218,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin, error_element, } => { - let error_region = - self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + let error_region = self.regioncx.region_from_element(longer_fr, error_element); // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( + let (_, span) = self.regioncx.find_outlives_blame_span( &self.body, longer_fr, fr_origin, @@ -286,8 +284,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); let (category, _, span) = - self.nonlexical_regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { - self.nonlexical_regioncx.provides_universal_region(r, fr, outlived_fr) + self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { + self.regioncx.provides_universal_region(r, fr, outlived_fr) }); debug!("report_error: category={:?} {:?}", category, span); @@ -302,8 +300,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.nonlexical_regioncx.universal_regions().is_local_free_region(fr), - self.nonlexical_regioncx.universal_regions().is_local_free_region(outlived_fr), + self.regioncx.universal_regions().is_local_free_region(fr), + self.regioncx.universal_regions().is_local_free_region(outlived_fr), ); debug!( @@ -378,7 +376,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. let return_type_is_closure = - self.nonlexical_regioncx.universal_regions().unnormalized_output_ty.is_closure(); + self.regioncx.universal_regions().unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -430,14 +428,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; - let fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( self.infcx.tcx, &self.body, &self.local_names, &self.upvars, errci.fr, ); - let outlived_fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + let outlived_fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( self.infcx.tcx, &self.body, &self.local_names, @@ -445,7 +443,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.nonlexical_regioncx.universal_regions().defining_ty { + let escapes_from = match self.regioncx.universal_regions().defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index b6bfa30b4dcdf..7ce29713240ce 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -191,7 +191,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.nonlexical_regioncx.universal_regions().is_universal_region(fr)); + assert!(self.regioncx.universal_regions().is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); @@ -277,7 +277,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .hir() .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.nonlexical_regioncx.universal_regions().defining_ty; + let def_ty = self.regioncx.universal_regions().defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -344,12 +344,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let implicit_inputs = - self.nonlexical_regioncx.universal_regions().defining_ty.implicit_inputs(); - let argument_index = - self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; + let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs(); + let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; - let arg_ty = self.nonlexical_regioncx.universal_regions().unnormalized_input_tys + let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) @@ -415,10 +413,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ); let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - let argument_index = self - .nonlexical_regioncx - .get_argument_index_for_region(self.infcx.tcx, needle_fr)?; - let (_, span) = self.nonlexical_regioncx.get_argument_name_and_span_for_region( + let argument_index = + self.regioncx.get_argument_index_for_region(self.infcx.tcx, needle_fr)?; + let (_, span) = self.regioncx.get_argument_name_and_span_for_region( &self.body, &self.local_names, argument_index, @@ -658,9 +655,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let upvar_index = - self.nonlexical_regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; - let (upvar_name, upvar_span) = self.nonlexical_regioncx.get_upvar_name_and_span_for_region( + let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; + let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( self.infcx.tcx, &self.upvars, upvar_index, @@ -684,7 +680,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { let tcx = self.infcx.tcx; - let return_ty = self.nonlexical_regioncx.universal_regions().unnormalized_output_ty; + let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -734,7 +730,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.nonlexical_regioncx.universal_regions().yield_ty?; + let yield_ty = self.regioncx.universal_regions().yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); let tcx = self.infcx.tcx; diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 22037ac6c81b2..0ad9d4492b208 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -283,7 +283,7 @@ fn do_mir_borrowck<'a, 'tcx>( move_error_reported: BTreeMap::new(), uninitialized_error_reported: Default::default(), errors_buffer, - nonlexical_regioncx: regioncx, + regioncx, used_mut: Default::default(), used_mut_upvars: SmallVec::new(), borrow_set, @@ -474,10 +474,9 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// If the function we're checking is a closure, then we'll need to report back the list of /// mutable upvars that have been used. This field keeps track of them. used_mut_upvars: SmallVec<[Field; 8]>, - /// Non-lexical region inference context, if NLL is enabled. This - /// contains the results from region inference and lets us e.g. + /// Region inference context. This contains the results from region inference and lets us e.g. /// find out which CFG points are contained in each borrow region. - nonlexical_regioncx: Rc>, + regioncx: Rc>, /// The set of borrows extracted from the MIR borrow_set: Rc>, From a804868bbf578dada5249ac3c79b7b524684c78e Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 20:36:42 -0600 Subject: [PATCH 0296/1253] Get rid of RegionErrorNamingContext --- .../diagnostics/explain_borrow.rs | 7 +- .../borrow_check/diagnostics/mod.rs | 2 +- .../diagnostics/outlives_suggestion.rs | 25 +--- .../borrow_check/diagnostics/region_errors.rs | 51 +++---- .../borrow_check/diagnostics/region_name.rs | 138 ++++++------------ src/librustc_mir/borrow_check/mod.rs | 15 +- .../borrow_check/region_infer/mod.rs | 17 --- .../ui/c-variadic/variadic-ffi-4.nll.stderr | 4 +- 8 files changed, 88 insertions(+), 171 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index ca5cf5bc741a0..01b7c5645fe8b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -16,8 +16,8 @@ use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::borrow_check::{ - borrow_set::BorrowData, diagnostics::RegionErrorNamingCtx, nll::ConstraintDescription, - region_infer::Cause, MirBorrowckCtxt, WriteKind, + borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, + WriteKind, }; use super::{find_use, RegionName, UseSpans}; @@ -267,8 +267,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region), ); - let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = self.give_region_a_name(&mut renctx, outlived_region); + let outlived_fr_name = self.give_region_a_name(outlived_region); (category, from_closure, span, outlived_fr_name) } diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 3f3bdb9d36c76..0fc73d33f9001 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -32,7 +32,7 @@ mod region_errors; crate use mutability_errors::AccessKind; crate use outlives_suggestion::OutlivesSuggestionBuilder; crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; -crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource}; +crate use region_name::{RegionName, RegionNameSource}; pub(super) struct IncludingDowncast(pub(super) bool); diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index be067fcf4f261..ee9489078bdb9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -12,7 +12,7 @@ use smallvec::SmallVec; use crate::borrow_check::MirBorrowckCtxt; -use super::{ErrorConstraintInfo, RegionErrorNamingCtx, RegionName, RegionNameSource}; +use super::{ErrorConstraintInfo, RegionName, RegionNameSource}; /// The different things we could suggest. enum SuggestedConstraint { @@ -77,17 +77,15 @@ impl OutlivesSuggestionBuilder { fn region_vid_to_name( &self, mbcx: &MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, region: RegionVid, ) -> Option { - mbcx.give_region_a_name(renctx, region).filter(Self::region_name_is_suggestable) + mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) } /// Compiles a list of all suggestions to be printed in the final big suggestion. fn compile_all_suggestions( &self, mbcx: &MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -96,7 +94,7 @@ impl OutlivesSuggestionBuilder { let mut unified_already = FxHashSet::default(); for (fr, outlived) in &self.constraints_to_add { - let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, renctx, *fr) { + let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) { fr_name } else { continue; @@ -105,9 +103,7 @@ impl OutlivesSuggestionBuilder { let outlived = outlived .iter() // if there is a `None`, we will just omit that constraint - .filter_map(|fr| { - self.region_vid_to_name(mbcx, renctx, *fr).map(|rname| (fr, rname)) - }) + .filter_map(|fr| self.region_vid_to_name(mbcx, *fr).map(|rname| (fr, rname))) .collect::>(); // No suggestable outlived lifetimes. @@ -171,12 +167,11 @@ impl OutlivesSuggestionBuilder { &mut self, mbcx: &MirBorrowckCtxt<'_, '_>, errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, diag: &mut DiagnosticBuilder<'_>, ) { // Emit an intermediate note. - let fr_name = self.region_vid_to_name(mbcx, renctx, errci.fr); - let outlived_fr_name = self.region_vid_to_name(mbcx, renctx, errci.outlived_fr); + let fr_name = self.region_vid_to_name(mbcx, errci.fr); + let outlived_fr_name = self.region_vid_to_name(mbcx, errci.outlived_fr); if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) { if let RegionNameSource::Static = outlived_fr_name.source { @@ -192,11 +187,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - crate fn add_suggestion( - &self, - mbcx: &mut MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, - ) { + crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); @@ -213,7 +204,7 @@ impl OutlivesSuggestionBuilder { } // Get all suggestable constraints. - let suggested = self.compile_all_suggestions(mbcx, renctx); + let suggested = self.compile_all_suggestions(mbcx); // If there are no suggestable constraints... if suggested.is_empty() { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index f3dc8e72e3016..729a679e92a32 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -19,7 +19,7 @@ use crate::borrow_check::{ MirBorrowckCtxt, }; -use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource}; +use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource}; impl ConstraintDescription for ConstraintCategory { fn description(&self) -> &'static str { @@ -152,8 +152,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are // buffered in the `MirBorrowckCtxt`. - // TODO(mark-i-m): Would be great to get rid of the naming context. - let mut region_naming = RegionErrorNamingCtx::new(); let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); for nll_error in nll_errors.into_iter() { @@ -243,7 +241,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin, shorter_fr, &mut outlives_suggestion, - &mut region_naming, ); } else { // We only report the first error, so as not to overwhelm the user. See @@ -262,7 +259,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // Emit one outlives suggestions for each MIR def we borrowck - outlives_suggestion.add_suggestion(self, &mut region_naming); + outlives_suggestion.add_suggestion(self); } /// Report an error because the universal region `fr` was required to outlive @@ -279,7 +276,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, - renctx: &mut RegionErrorNamingCtx, ) { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); @@ -320,21 +316,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let diag = match (category, fr_is_local, outlived_fr_is_local) { (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => { - self.report_fnmut_error(&errci, renctx) + self.report_fnmut_error(&errci) } (ConstraintCategory::Assignment, true, false) | (ConstraintCategory::CallArgument, true, false) => { - let mut db = self.report_escaping_data_error(&errci, renctx); + let mut db = self.report_escaping_data_error(&errci); - outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } _ => { - let mut db = self.report_general_error(&errci, renctx); + let mut db = self.report_general_error(&errci); - outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db @@ -360,11 +356,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// executing... /// = note: ...therefore, returned references to captured variables will escape the closure /// ``` - fn report_fnmut_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_fnmut_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut diag = self @@ -386,7 +378,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { diag.span_label(*span, message); - match self.give_region_a_name(renctx, *outlived_fr).unwrap().source { + match self.give_region_a_name(*outlived_fr).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -421,11 +413,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// LL | ref_obj(x) /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` - fn report_escaping_data_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -456,10 +444,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { || (*category == ConstraintCategory::Assignment && escapes_from == "function") || escapes_from == "const" { - return self.report_general_error( - &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, - renctx, - ); + return self.report_general_error(&ErrorConstraintInfo { + fr_is_local: true, + outlived_fr_is_local: false, + ..*errci + }); } let mut diag = @@ -505,11 +494,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it /// | is returning data with lifetime `'b` /// ``` - fn report_general_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { fr, fr_is_local, @@ -526,9 +511,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mir_def_name = if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; - let fr_name = self.give_region_a_name(renctx, *fr).unwrap(); + let fr_name = self.give_region_a_name(*fr).unwrap(); fr_name.highlight_region_name(&mut diag); - let outlived_fr_name = self.give_region_a_name(renctx, *outlived_fr).unwrap(); + let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); match (category, outlived_fr_is_local, fr_is_local) { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 7ce29713240ce..f7aeec5e76ee9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -3,7 +3,6 @@ use std::fmt::{self, Display}; use rustc::ty::print::RegionHighlightMode; use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::{self, RegionVid, Ty}; -use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -52,46 +51,6 @@ crate enum RegionNameSource { AnonRegionFromAsyncFn(Span), } -/// Records region names that have been assigned before so that we can use the same ones in later -/// diagnostics. -#[derive(Debug, Clone)] -crate struct RegionErrorNamingCtx { - /// Record the region names generated for each region in the given - /// MIR def so that we can reuse them later in help/error messages. - renctx: FxHashMap, - - /// The counter for generating new region names. - counter: usize, -} - -impl RegionErrorNamingCtx { - crate fn new() -> Self { - Self { counter: 1, renctx: FxHashMap::default() } - } - - /// Get the name of `region` if it has previously been named. - crate fn get(&self, region: &RegionVid) -> Option<&RegionName> { - self.renctx.get(region) - } - - /// Give `region` the name `name`. - crate fn insert(&mut self, region: RegionVid, name: RegionName) { - self.renctx.insert(region, name); - } - - /// Creates a synthetic region named `'N`, where `N` is the next value of the counter. Then, - /// increment the counter. - /// - /// The name is not memoized. A separate call to `insert` should be made later. (Currently, - /// this happens at the end of `give_region_a_name`). - crate fn synthesize_region_name(&mut self) -> Symbol { - let c = self.counter; - self.counter += 1; - - Symbol::intern(&format!("'{:?}", c)) - } -} - impl RegionName { crate fn was_named(&self) -> bool { match self.source { @@ -159,6 +118,17 @@ impl Display for RegionName { } impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { + /// Generate a synthetic region named `'N`, where `N` is the next value of the counter. Then, + /// increment the counter. + /// + /// This is _not_ idempotent. Call `give_region_a_name` when possible. + fn synthesize_region_name(&self) -> Symbol { + let mut counter = self.next_region_name.try_borrow_mut().unwrap(); + let c = *counter; + *counter += 1; + Symbol::intern(&format!("'{:?}", c)) + } + /// Maps from an internal MIR region vid to something that we can /// report to the user. In some cases, the region vids will map /// directly to lifetimes that the user has a name for (e.g., @@ -167,6 +137,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// that end, this function takes a "diagnostic" so that it can /// create auxiliary notes as needed. /// + /// The names are memoized, so this is both cheap to recompute and idempotent. + /// /// Example (function arguments): /// /// Suppose we are trying to give a name to the lifetime of the @@ -184,28 +156,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// ``` /// /// and then return the name `'1` for us to use. - crate fn give_region_a_name( - &self, - renctx: &mut RegionErrorNamingCtx, - fr: RegionVid, - ) -> Option { - debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); + crate fn give_region_a_name(&self, fr: RegionVid) -> Option { + debug!( + "give_region_a_name(fr={:?}, counter={:?})", + fr, + self.next_region_name.try_borrow().unwrap() + ); assert!(self.regioncx.universal_regions().is_universal_region(fr)); - if let Some(value) = renctx.get(&fr) { + if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) { return Some(value.clone()); } let value = self - .give_name_from_error_region(fr, renctx) - .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr, renctx)); + .give_name_from_error_region(fr) + .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)); if let Some(ref value) = value { - renctx.insert(fr, value.clone()); + self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone()); } debug!("give_region_a_name: gave name {:?}", value); @@ -216,11 +188,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// *user* has a name for. In that case, we'll be able to map /// `fr` to a `Region<'tcx>`, and that region will be one of /// named variants. - fn give_name_from_error_region( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_from_error_region(&self, fr: RegionVid) -> Option { let error_region = self.to_error_region(fr)?; let tcx = self.infcx.tcx; @@ -262,7 +230,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // happen if we have an elided name in an async fn for example: the // compiler will generate a region named `'_`, but reporting such a name is // not actually useful, so we synthesize a name for it instead. - let name = renctx.synthesize_region_name(); + let name = self.synthesize_region_name(); Some(RegionName { name, source: RegionNameSource::AnonRegionFromAsyncFn(span), @@ -287,7 +255,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } else { bug!("Closure is not defined by a closure expr"); }; - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); let closure_kind_ty = substs.as_closure().kind_ty(def_id, tcx); let note = match closure_kind_ty.to_opt_closure_kind() { @@ -342,7 +310,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fn give_name_if_anonymous_region_appears_in_arguments( &self, fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs(); let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; @@ -350,12 +317,12 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = - self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) + self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index) { return Some(region_name); } - self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty, renctx) + self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty) } fn give_name_if_we_can_match_hir_ty_from_argument( @@ -363,7 +330,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_index: usize, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?; let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; @@ -376,12 +342,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // (`give_name_if_anonymous_region_appears_in_arguments`). hir::TyKind::Infer => None, - _ => self.give_name_if_we_can_match_hir_ty( - needle_fr, - argument_ty, - argument_hir_ty, - renctx, - ), + _ => self.give_name_if_we_can_match_hir_ty(needle_fr, argument_ty, argument_hir_ty), } } @@ -400,9 +361,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { &self, needle_fr: RegionVid, argument_ty: Ty<'tcx>, - renctx: &mut RegionErrorNamingCtx, ) -> Option { - let counter = renctx.counter; + let counter = *self.next_region_name.try_borrow().unwrap(); let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0; @@ -425,7 +385,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // This counter value will already have been used, so this function will increment // it so the next value will be used next and return the region name that would // have been used. - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::CannotMatchHirTy(span, type_name), }) } else { @@ -461,7 +421,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_hir_ty: &hir::Ty<'_>, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> = &mut vec![(argument_ty, argument_hir_ty)]; @@ -479,7 +438,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::TyKind::Rptr(_lifetime, referent_hir_ty), ) => { if region.to_region_vid() == needle_fr { - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); // Just grab the first character, the `&`. let source_map = self.infcx.tcx.sess.source_map(); @@ -512,7 +471,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { substs, needle_fr, last_segment, - renctx, search_stack, ) { return Some(name); @@ -557,7 +515,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { substs: SubstsRef<'tcx>, needle_fr: RegionVid, last_segment: &'hir hir::PathSegment<'hir>, - renctx: &mut RegionErrorNamingCtx, search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, ) -> Option { // Did the user give explicit arguments? (e.g., `Foo<..>`) @@ -569,7 +526,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | hir::LifetimeName::Error | hir::LifetimeName::Static | hir::LifetimeName::Underscore => { - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); let ampersand_span = lifetime.span; Some(RegionName { name: region_name, @@ -650,18 +607,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// | let x = Some(&22); /// - fully elaborated type of `x` is `Option<&'1 u32>` /// ``` - fn give_name_if_anonymous_region_appears_in_upvars( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option { let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( self.infcx.tcx, &self.upvars, upvar_index, ); - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); Some(RegionName { name: region_name, @@ -673,11 +626,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// must be a closure since, in a free fn, such an argument would /// have to either also appear in an argument (if using elision) /// or be early bound (named, not in argument). - fn give_name_if_anonymous_region_appears_in_output( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option { let tcx = self.infcx.tcx; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -687,7 +636,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } let mut highlight = RegionHighlightMode::default(); - highlight.highlighting_region_vid(fr, renctx.counter); + highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0; let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); @@ -714,7 +663,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // This counter value will already have been used, so this function will increment it // so the next value will be used next and return the region name that would have been // used. - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromOutput( return_span, mir_description.to_string(), @@ -726,7 +675,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fn give_name_if_anonymous_region_appears_in_yield_ty( &self, fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. @@ -740,7 +688,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } let mut highlight = RegionHighlightMode::default(); - highlight.highlighting_region_vid(fr, renctx.counter); + highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0; let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); @@ -759,7 +707,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ); Some(RegionName { - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), }) } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0ad9d4492b208..90927069242b1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -11,7 +11,8 @@ use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, RegionVid, TyCtxt}; + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; @@ -21,6 +22,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use smallvec::SmallVec; +use std::cell::RefCell; use std::collections::BTreeMap; use std::mem; use std::rc::Rc; @@ -39,7 +41,7 @@ use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::MirSource; -use self::diagnostics::AccessKind; +use self::diagnostics::{AccessKind, RegionName}; use self::flows::Flows; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -290,6 +292,8 @@ fn do_mir_borrowck<'a, 'tcx>( dominators, upvars, local_names, + region_names: RefCell::default(), + next_region_name: RefCell::new(1), }; // Compute and report region errors, if any. @@ -489,6 +493,13 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// Names of local (user) variables (extracted from `var_debug_info`). local_names: IndexVec>, + + /// Record the region names generated for each region in the given + /// MIR def so that we can reuse them later in help/error messages. + region_names: RefCell>, + + /// The counter for generating new region names. + next_region_name: RefCell, } // Check that: diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 359f75cac8376..180bb95cab9f4 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -1603,23 +1603,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Get the region outlived by `longer_fr` and live at `element`. - crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { - match element { - RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), - RegionElement::RootUniversalRegion(r) => r, - RegionElement::PlaceholderRegion(error_placeholder) => self - .definitions - .iter_enumerated() - .filter_map(|(r, definition)| match definition.origin { - NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), - _ => None, - }) - .next() - .unwrap(), - } - } - /// We have a constraint `fr1: fr2` that is not satisfied, where /// `fr2` represents some universal region. Here, `r` is some /// region where we know that `fr1: r` and this function has the diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr index 8b70b15fa6e50..89107e799bd22 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr @@ -87,12 +87,12 @@ error[E0597]: `ap1` does not live long enough --> $DIR/variadic-ffi-4.rs:24:11 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | - let's call the lifetime of this reference `'1` + | - let's call the lifetime of this reference `'3` LL | ap0 = &mut ap1; | ------^^^^^^^^ | | | | | borrowed value does not live long enough - | assignment requires that `ap1` is borrowed for `'1` + | assignment requires that `ap1` is borrowed for `'3` ... LL | } | - `ap1` dropped here while still borrowed From f05e40eb992fce44db348cfb1e8ecb4699e9cdd6 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 1 Jan 2020 14:35:08 -0600 Subject: [PATCH 0297/1253] address review comments --- .../borrow_check/diagnostics/region_errors.rs | 15 +++++++-------- .../borrow_check/diagnostics/region_name.rs | 4 +--- src/librustc_mir/borrow_check/region_infer/mod.rs | 6 ++++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 729a679e92a32..b999dfa303103 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -138,8 +138,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let DefiningTy::Closure(def_id, substs) = self.regioncx.universal_regions().defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); - return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); + return substs.as_closure().kind(def_id, self.infcx.tcx) + == ty::ClosureKind::FnMut; } } } @@ -160,7 +160,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Try to convert the lower-bound region into something named we can print for the user. let lower_bound_region = self.to_error_region(type_test.lower_bound); - // Skip duplicate-ish errors. let type_test_span = type_test.locations.span(&self.body); if let Some(lower_bound_region) = lower_bound_region { @@ -236,7 +235,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { if is_reported { - self.report_error( + self.report_region_error( longer_fr, fr_origin, shorter_fr, @@ -270,21 +269,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` /// /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`. - pub(in crate::borrow_check) fn report_error( + pub(in crate::borrow_check) fn report_region_error( &mut self, fr: RegionVid, fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, ) { - debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); + debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); let (category, _, span) = self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { self.regioncx.provides_universal_region(r, fr, outlived_fr) }); - debug!("report_error: category={:?} {:?}", category, span); + debug!("report_region_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id); @@ -301,7 +300,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); debug!( - "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", + "report_region_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", fr_is_local, outlived_fr_is_local, category ); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index f7aeec5e76ee9..47eb2d8940af4 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -123,9 +123,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// /// This is _not_ idempotent. Call `give_region_a_name` when possible. fn synthesize_region_name(&self) -> Symbol { - let mut counter = self.next_region_name.try_borrow_mut().unwrap(); - let c = *counter; - *counter += 1; + let c = self.next_region_name.replace_with(|counter| *counter + 1); Symbol::intern(&format!("'{:?}", c)) } diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 180bb95cab9f4..26d9cf2e0450f 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -846,6 +846,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Type-test failed. Report the error. let erased_generic_kind = infcx.tcx.erase_regions(&type_test.generic_kind); + + // Skip duplicate-ish errors. if deduplicate_errors.insert(( erased_generic_kind, type_test.lower_bound, @@ -1850,8 +1852,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.contains(r_scc, upper) } - crate fn universal_regions(&self) -> Rc> { - self.universal_regions.clone() + crate fn universal_regions(&self) -> &UniversalRegions<'tcx> { + self.universal_regions.as_ref() } /// Tries to find the best constraint to blame for the fact that From 7f65475d00c9a3048d0d664a80314734a8c6989e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 12 Jan 2020 21:19:44 -0500 Subject: [PATCH 0298/1253] Turn off const propagation of ref taking Fixes #67529 Fixes #67640 Fixes #67641 Fixes #67862 --- src/librustc_mir/transform/const_prop.rs | 23 +++--------------- .../mir-opt/const_prop/ref_deref_project.rs | 4 ++-- src/test/ui/consts/issue-67529.rs | 11 +++++++++ src/test/ui/consts/issue-67640.rs | 24 +++++++++++++++++++ src/test/ui/consts/issue-67641.rs | 24 +++++++++++++++++++ src/test/ui/consts/issue-67862.rs | 18 ++++++++++++++ 6 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/consts/issue-67529.rs create mode 100644 src/test/ui/consts/issue-67640.rs create mode 100644 src/test/ui/consts/issue-67641.rs create mode 100644 src/test/ui/consts/issue-67862.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..75efe84c32eee 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -595,28 +595,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { self.check_binary_op(*op, left, right, source_info, place_layout, overflow_check)?; } - // Work around: avoid ICE in miri. FIXME(wesleywiser) - // The Miri engine ICEs when taking a reference to an uninitialized unsized - // local. There's nothing it can do here: taking a reference needs an allocation - // which needs to know the size. Normally that's okay as during execution - // (e.g. for CTFE) it can never happen. But here in const_prop - // unknown data is uninitialized, so if e.g. a function argument is unsized - // and has a reference taken, we get an ICE. + // Do not try creating references (#67862) Rvalue::Ref(_, _, place_ref) => { - trace!("checking Ref({:?})", place_ref); + trace!("skipping Ref({:?})", place_ref); - if let Some(local) = place_ref.as_local() { - let alive = if let LocalValue::Live(_) = self.ecx.frame().locals[local].value { - true - } else { - false - }; - - if !alive { - trace!("skipping Ref({:?}) to uninitialized local", place); - return None; - } - } + return None; } _ => {} diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs index 5808a8be176d4..ca539fb7462a5 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.rs +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -1,5 +1,5 @@ fn main() { - *(&(4, 5).1); + *(&(4, 5).1); // This does not currently propagate (#67862) } // END RUST SOURCE @@ -35,7 +35,7 @@ fn main() { // ... // _4 = const main::promoted[0]; // _2 = &((*_4).1: i32); -// _1 = const 5i32; +// _1 = (*_2); // ... // } // END rustc.main.ConstProp.after.mir diff --git a/src/test/ui/consts/issue-67529.rs b/src/test/ui/consts/issue-67529.rs new file mode 100644 index 0000000000000..df4bc668bee17 --- /dev/null +++ b/src/test/ui/consts/issue-67529.rs @@ -0,0 +1,11 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +struct Baz { + a: T +} + +fn main() { + let d : Baz<[i32; 4]> = Baz { a: [1,2,3,4] }; + assert_eq!([1, 2, 3, 4], d.a); +} diff --git a/src/test/ui/consts/issue-67640.rs b/src/test/ui/consts/issue-67640.rs new file mode 100644 index 0000000000000..bc0ee8d386f0a --- /dev/null +++ b/src/test/ui/consts/issue-67640.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=3 +// run-pass + +struct X { + x: isize +} + +fn f1(a: &mut X, b: &mut isize, c: isize) -> isize { + let r = a.x + *b + c; + a.x = 0; + *b = 10; + return r; +} + +fn f2(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; } + +pub fn main() { + let mut a = X {x: 1}; + let mut b = 2; + let c = 3; + assert_eq!(f1(&mut a, &mut b, c), 6); + assert_eq!(a.x, 0); + assert_eq!(f2(a.x, |_| a.x = 50), 0); +} diff --git a/src/test/ui/consts/issue-67641.rs b/src/test/ui/consts/issue-67641.rs new file mode 100644 index 0000000000000..f50fba287a231 --- /dev/null +++ b/src/test/ui/consts/issue-67641.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct B<'a> { + a: [Cell>>; 2] +} + +impl<'a> B<'a> { + fn new() -> B<'a> { + B { a: [Cell::new(None), Cell::new(None)] } + } +} + +fn f() { + let b2 = B::new(); + b2.a[0].set(Some(&b2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/consts/issue-67862.rs b/src/test/ui/consts/issue-67862.rs new file mode 100644 index 0000000000000..84f72154d262f --- /dev/null +++ b/src/test/ui/consts/issue-67862.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +fn e220() -> (i64, i64) { + #[inline(never)] + fn get_displacement() -> [i64; 2] { + [139776, 963904] + } + + let res = get_displacement(); + match (&res[0], &res[1]) { + (arg0, arg1) => (*arg0, *arg1), + } +} + +fn main() { + assert_eq!(e220(), (139776, 963904)); +} From 9d95eaa49b095c396eaee3d3cb62e60df8e81a2f Mon Sep 17 00:00:00 2001 From: Afnan Enayet Date: Fri, 3 Jan 2020 17:27:14 -0800 Subject: [PATCH 0299/1253] Use `report_in_external_macro` for internal lints Add the option to report lints in external macros for rustc internal lints --- src/librustc_lint/internal.rs | 12 ++++++++---- src/librustc_span/symbol.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 2f8393bd906c0..5a5aedc2e9715 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -12,7 +12,8 @@ use syntax::ast::{Ident, Item, ItemKind}; declare_tool_lint! { pub rustc::DEFAULT_HASH_TYPES, Allow, - "forbid HashMap and HashSet and suggest the FxHash* variants" + "forbid HashMap and HashSet and suggest the FxHash* variants", + report_in_external_macro: true } pub struct DefaultHashTypes { @@ -52,19 +53,22 @@ impl EarlyLintPass for DefaultHashTypes { declare_tool_lint! { pub rustc::USAGE_OF_TY_TYKIND, Allow, - "usage of `ty::TyKind` outside of the `ty::sty` module" + "usage of `ty::TyKind` outside of the `ty::sty` module", + report_in_external_macro: true } declare_tool_lint! { pub rustc::TY_PASS_BY_REFERENCE, Allow, - "passing `Ty` or `TyCtxt` by reference" + "passing `Ty` or `TyCtxt` by reference", + report_in_external_macro: true } declare_tool_lint! { pub rustc::USAGE_OF_QUALIFIED_TY, Allow, - "using `ty::{Ty,TyCtxt}` instead of importing it" + "using `ty::{Ty,TyCtxt}` instead of importing it", + report_in_external_macro: true } declare_lint_pass!(TyTyKind => [ diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index a8b2db300a478..889f6099070ae 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -1049,6 +1049,7 @@ pub mod kw { } // This module has a very short name because it's used a lot. +#[allow(rustc::default_hash_types)] pub mod sym { use super::Symbol; use std::convert::TryInto; From a1586f1d2b17d687444d3b94aedd7ce24ae074ed Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Mon, 13 Jan 2020 09:17:10 +0100 Subject: [PATCH 0300/1253] Explain fold_list --- src/librustc/ty/structural_impls.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 783164d2806c1..eade5154c8ad0 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1061,6 +1061,11 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { } } +// Does the equivalent of +// ``` +// let v = self.iter().map(|p| p.fold_with(folder)).collect::>(); +// folder.tcx().intern_*(&v) +// ``` fn fold_list<'tcx, F, T>( list: &'tcx ty::List, folder: &mut F, From 5896998e7659bf22ffb804956a3680c028ede45f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 5 Jan 2020 22:32:53 -0500 Subject: [PATCH 0301/1253] Don't run const propagation on items with inconsistent bounds Using `#![feature(trivial_bounds)]`, it's possible to write functions with unsatisfiable 'where' clauses, making them uncallable. However, the user can act as if these 'where' clauses are true inside the body of the function, leading to code that would normally be impossible to write. Since const propgation can run even without any user-written calls to a function, we need to explcitly check for these uncallable functions. --- src/librustc_mir/transform/const_prop.rs | 25 +++++++++++++++++++ ...ounds-inconsistent-associated-functions.rs | 4 +++ ...s-inconsistent-associated-functions.stderr | 2 ++ 3 files changed, 31 insertions(+) create mode 100644 src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..48ab24a14c7c6 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -74,6 +74,31 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } + // Check if it's even possible to satisy the 'where' clauses + // for this item. + // This branch will never be taken for any normal function. + // However, it's possible to `#!feature(trivial_bounds)]` to write + // a function with impossible to satisfy clauses, e.g.: + // `fn foo() where String: Copy {}` + // + // We don't usually need to worry about this kind of case, + // since we would get a compilation error if the user tried + // to call it. However, since we can do const propagation + // even without any calls to the function, we need to make + // sure that it even makes sense to try to evaluate the body. + // If there are unsatisfiable where clauses, then all bets are + // off, and we just give up. + if !tcx.substitute_normalize_and_test_predicates(( + source.def_id(), + InternalSubsts::identity_for_item(tcx, source.def_id()), + )) { + trace!( + "ConstProp skipped for item with unsatisfiable predicates: {:?}", + source.def_id() + ); + return; + } + trace!("ConstProp starting for {:?}", source.def_id()); let dummy_body = &Body::new( diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index 6450ddd1b67fc..818be10554720 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,4 +1,8 @@ // run-pass +// Force mir to be emitted, to ensure that const +// propagation doesn't ICE on a function +// with an 'impossible' body. See issue #67696 +// compile-flags: --emit=mir,link // Inconsistent bounds with trait implementations #![feature(trivial_bounds)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr new file mode 100644 index 0000000000000..0ee1e2e0ba56a --- /dev/null +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr @@ -0,0 +1,2 @@ +warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type + From e1fc22c4eba6e07a5549c74b197fbaa53f7b29e1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 7 Jan 2020 10:01:52 -0500 Subject: [PATCH 0302/1253] Add additional regression test --- .../ui/consts/issue-67696-const-prop-ice.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/consts/issue-67696-const-prop-ice.rs diff --git a/src/test/ui/consts/issue-67696-const-prop-ice.rs b/src/test/ui/consts/issue-67696-const-prop-ice.rs new file mode 100644 index 0000000000000..ad52608b3f46d --- /dev/null +++ b/src/test/ui/consts/issue-67696-const-prop-ice.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: --emit=mir,link +// Checks that we don't ICE due to attempting to run const prop +// on a function with unsatisifable 'where' clauses + +#![allow(unused)] + +trait A { + fn foo(&self) -> Self where Self: Copy; +} + +impl A for [fn(&())] { + fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) } +} + +impl A for i32 { + fn foo(&self) -> Self { 3 } +} + +fn main() {} From 92d86cc9b8bbd744c5eebf3718a9dc87576b786c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 7 Jan 2020 10:53:04 -0500 Subject: [PATCH 0303/1253] Fix typo --- src/librustc_mir/transform/const_prop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 48ab24a14c7c6..35dbf2f7eaa42 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -74,7 +74,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } - // Check if it's even possible to satisy the 'where' clauses + // Check if it's even possible to satisfy the 'where' clauses // for this item. // This branch will never be taken for any normal function. // However, it's possible to `#!feature(trivial_bounds)]` to write From 7df8ca29545301c1d3020bf8fc9aa8f9fd8759ea Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 11 Jan 2020 13:20:09 -0500 Subject: [PATCH 0304/1253] Convert test to check-pass --- .../trivial-bounds-inconsistent-associated-functions.rs | 4 ++-- .../trivial-bounds-inconsistent-associated-functions.stderr | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index 818be10554720..e0d4d538b40e7 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,8 +1,8 @@ -// run-pass +// check-pass +// compile-flags: --emit=mir // Force mir to be emitted, to ensure that const // propagation doesn't ICE on a function // with an 'impossible' body. See issue #67696 -// compile-flags: --emit=mir,link // Inconsistent bounds with trait implementations #![feature(trivial_bounds)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr deleted file mode 100644 index 0ee1e2e0ba56a..0000000000000 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr +++ /dev/null @@ -1,2 +0,0 @@ -warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type - From 6a0bb1867b2026e05982f865bb48857d7e492cd7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 11 Jan 2020 14:17:42 -0500 Subject: [PATCH 0305/1253] Add "--emit=link" This avoids a strange linker error that we get with only "--emit=mir" and "check-pass" --- .../trivial-bounds-inconsistent-associated-functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index e0d4d538b40e7..69eee66e64d89 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: --emit=mir +// compile-flags: --emit=mir,link // Force mir to be emitted, to ensure that const // propagation doesn't ICE on a function // with an 'impossible' body. See issue #67696 From e390b91e5717a338db20360a1ddffa23ba66701d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 13 Jan 2020 06:06:42 -0500 Subject: [PATCH 0306/1253] Use TraitQueryMode::Canonical when testing predicates in const prop --- src/librustc/mir/mono.rs | 5 ++++- src/librustc/query/mod.rs | 6 +++--- src/librustc/traits/fulfill.rs | 24 ++++++++++++++++++++++-- src/librustc/traits/mod.rs | 18 +++++++++++------- src/librustc/ty/query/keys.rs | 9 +++++++++ src/librustc_mir/transform/const_prop.rs | 16 ++++++++++++++++ 6 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 51ce575e51f3b..e7a4c5b592105 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,7 @@ use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; use crate::session::config::OptLevel; +use crate::traits::TraitQueryMode; use crate::ty::print::obsolete::DefPathBasedNames; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; use rustc_data_structures::base_n; @@ -167,7 +168,9 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(..) => return true, }; - tcx.substitute_normalize_and_test_predicates((def_id, &substs)) + // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\ + // to report an error if overflow somehow occurs. + tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard)) } pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 50ef115da2c42..669ba4abfadd8 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1141,11 +1141,11 @@ rustc_queries! { desc { "normalizing `{:?}`", goal } } - query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { + query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool { no_force desc { |tcx| - "testing substituted normalized predicates:`{}`", - tcx.def_path_str(key.0) + "testing substituted normalized predicates in mode {:?}:`{}`", + key.2, tcx.def_path_str(key.0) } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 46ece6fc40593..9e5abc80822c7 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -16,6 +16,7 @@ use super::CodeSelectionError; use super::{ConstEvalFailure, Unimplemented}; use super::{FulfillmentError, FulfillmentErrorCode}; use super::{ObligationCause, PredicateObligation}; +use crate::traits::TraitQueryMode; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { type Predicate = ty::Predicate<'tcx>; @@ -62,6 +63,9 @@ pub struct FulfillmentContext<'tcx> { // a snapshot (they don't *straddle* a snapshot, so there // is no trouble there). usable_in_snapshot: bool, + + // The `TraitQueryMode` used when constructing a `SelectionContext` + query_mode: TraitQueryMode, } #[derive(Clone, Debug)] @@ -75,12 +79,26 @@ pub struct PendingPredicateObligation<'tcx> { static_assert_size!(PendingPredicateObligation<'_>, 136); impl<'a, 'tcx> FulfillmentContext<'tcx> { - /// Creates a new fulfillment context. + /// Creates a new fulfillment context with `TraitQueryMode::Standard` + /// You almost always want to use this instead of `with_query_mode` pub fn new() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: false, + query_mode: TraitQueryMode::Standard, + } + } + + /// Creates a new fulfillment context with the specified query mode. + /// This should only be used when you want to ignore overflow, + /// rather than reporting it as an error. + pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> { + FulfillmentContext { + predicates: ObligationForest::new(), + register_region_obligations: true, + usable_in_snapshot: false, + query_mode, } } @@ -89,6 +107,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: true, + query_mode: TraitQueryMode::Standard, } } @@ -97,6 +116,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: false, usable_in_snapshot: false, + query_mode: TraitQueryMode::Standard, } } @@ -217,7 +237,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { &mut self, infcx: &InferCtxt<'_, 'tcx>, ) -> Result<(), Vec>> { - let mut selcx = SelectionContext::new(infcx); + let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode); self.select(&mut selcx) } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 2d3160dc3e51a..31de5409fc8be 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -95,7 +95,7 @@ pub enum IntercrateMode { } /// The mode that trait queries run in. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)] pub enum TraitQueryMode { // Standard/un-canonicalized queries get accurate // spans etc. passed in and hence can do reasonable @@ -1017,13 +1017,14 @@ where fn normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: Vec>, + mode: TraitQueryMode, ) -> bool { - debug!("normalize_and_test_predicates(predicates={:?})", predicates); + debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode); let result = tcx.infer_ctxt().enter(|infcx| { let param_env = ty::ParamEnv::reveal_all(); - let mut selcx = SelectionContext::new(&infcx); - let mut fulfill_cx = FulfillmentContext::new(); + let mut selcx = SelectionContext::with_query_mode(&infcx, mode); + let mut fulfill_cx = FulfillmentContext::with_query_mode(mode); let cause = ObligationCause::dummy(); let Normalized { value: predicates, obligations } = normalize(&mut selcx, param_env, cause.clone(), &predicates); @@ -1043,12 +1044,12 @@ fn normalize_and_test_predicates<'tcx>( fn substitute_normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, - key: (DefId, SubstsRef<'tcx>), + key: (DefId, SubstsRef<'tcx>, TraitQueryMode), ) -> bool { debug!("substitute_normalize_and_test_predicates(key={:?})", key); let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; - let result = normalize_and_test_predicates(tcx, predicates); + let result = normalize_and_test_predicates(tcx, predicates, key.2); debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result); result @@ -1101,7 +1102,10 @@ fn vtable_methods<'tcx>( // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - if !normalize_and_test_predicates(tcx, predicates.predicates) { + // We don't expect overflow here, so report an error if it somehow ends + // up happening. + if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard) + { debug!("vtable_methods: predicates do not hold"); return None; } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d64f27d9cc26c..20f8e7f564abd 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -115,6 +115,15 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } +impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) { + fn query_crate(&self) -> CrateNum { + self.0.krate + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { fn query_crate(&self) -> CrateNum { self.1.def_id().krate diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 35dbf2f7eaa42..90c97480c7562 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -14,6 +14,7 @@ use rustc::mir::{ SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; +use rustc::traits::TraitQueryMode; use rustc::ty::layout::{ HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; @@ -88,9 +89,24 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // sure that it even makes sense to try to evaluate the body. // If there are unsatisfiable where clauses, then all bets are // off, and we just give up. + // + // Note that we use TraitQueryMode::Canonical here, which causes + // us to treat overflow like any other error. This is because we + // are "speculatively" evaluating this item with the default substs. + // While this usually succeeds, it may fail with tricky impls + // (e.g. the typenum crate). Const-propagation is fundamentally + // "best-effort", and does not affect correctness in any way. + // Therefore, it's perfectly fine to just "give up" if we're + // unable to check the bounds with the default substs. + // + // False negatives (failing to run const-prop on something when we actually + // could) are fine. However, false positives (running const-prop on + // an item with unsatisfiable bounds) can lead to us generating invalid + // MIR. if !tcx.substitute_normalize_and_test_predicates(( source.def_id(), InternalSubsts::identity_for_item(tcx, source.def_id()), + TraitQueryMode::Canonical, )) { trace!( "ConstProp skipped for item with unsatisfiable predicates: {:?}", From 9908a8736736fe3b7c416eb4560de87c15d10f47 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jan 2020 13:40:30 +0100 Subject: [PATCH 0307/1253] Move to new crate rustc_ty. --- Cargo.lock | 12 +++++++++++ src/librustc_interface/Cargo.toml | 1 + src/librustc_passes/lib.rs | 2 -- src/librustc_ty/Cargo.toml | 16 ++++++++++++++ src/librustc_ty/lib.rs | 25 ++++++++++++++++++++++ src/{librustc_passes => librustc_ty}/ty.rs | 0 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/librustc_ty/Cargo.toml create mode 100644 src/librustc_ty/lib.rs rename src/{librustc_passes => librustc_ty}/ty.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..14e41ca209625 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3642,6 +3642,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_traits", + "rustc_ty", "rustc_typeck", "serialize", "smallvec 1.0.0", @@ -3918,6 +3919,17 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_ty" +version = "0.0.0" +dependencies = [ + "log", + "rustc", + "rustc_data_structures", + "rustc_hir", + "rustc_span", +] + [[package]] name = "rustc_typeck" version = "0.0.0" diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index eb0551c606548..c7d387caa2d1d 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -39,6 +39,7 @@ rustc_errors = { path = "../librustc_errors" } rustc_plugin_impl = { path = "../librustc_plugin_impl" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } +rustc_ty = { path = "../librustc_ty" } tempfile = "3.0.5" once_cell = "1" diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 8bd06465628fa..c45f83f213078 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -31,7 +31,6 @@ pub mod loops; mod reachable; mod region; pub mod stability; -mod ty; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); @@ -44,5 +43,4 @@ pub fn provide(providers: &mut Providers<'_>) { reachable::provide(providers); region::provide(providers); stability::provide(providers); - ty::provide(providers); } diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml new file mode 100644 index 0000000000000..fb0d93fe5ebb6 --- /dev/null +++ b/src/librustc_ty/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ty" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_ty" +path = "lib.rs" + +[dependencies] +log = "0.4" +rustc = { path = "../librustc" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_hir = { path = "../librustc_hir" } +rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs new file mode 100644 index 0000000000000..2548d2cff9766 --- /dev/null +++ b/src/librustc_ty/lib.rs @@ -0,0 +1,25 @@ +//! Various checks +//! +//! # Note +//! +//! This API is completely unstable and subject to change. + +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(bool_to_option)] +#![feature(in_band_lifetimes)] +#![feature(nll)] +#![feature(slice_patterns)] +#![recursion_limit = "256"] + +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate log; + +use rustc::ty::query::Providers; + +mod ty; + +pub fn provide(providers: &mut Providers<'_>) { + ty::provide(providers); +} diff --git a/src/librustc_passes/ty.rs b/src/librustc_ty/ty.rs similarity index 100% rename from src/librustc_passes/ty.rs rename to src/librustc_ty/ty.rs From 25519e5290b4e04ab7a6cb07bcda01a542a0b1f3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Mon, 13 Jan 2020 08:04:48 +0000 Subject: [PATCH 0308/1253] Fix destructor in emcc.rs --- src/libpanic_unwind/emcc.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 0f93140238bc4..9161d49959cf5 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -88,8 +88,12 @@ cfg_if::cfg_if! { } extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> DestructorRet { unsafe { - ptr::drop_in_place(ptr as *mut Exception); - super::__rust_drop_panic(); + if let Some(b) = (ptr as *mut Exception).read().data { + drop(b); + super::__rust_drop_panic(); + } + #[cfg(any(target_arch = "arm", target_arch = "wasm32"))] + ptr } } From 13785c4c2ecf26e859c38b5656f611ae2a84fdba Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 13 Jan 2020 16:54:58 +0900 Subject: [PATCH 0309/1253] Remove unneeded scope --- src/librustdoc/clean/auto_trait.rs | 58 ++++++++++++++---------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index c8b63ed5c8096..56013ee3a816f 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -560,8 +560,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { lifetime_to_bounds.entry(lifetime).or_default().extend(bounds); } WherePredicate::EqPredicate { lhs, rhs } => { - match &lhs { - &Type::QPath { name: ref left_name, ref self_type, ref trait_ } => { + match lhs { + Type::QPath { name: ref left_name, ref self_type, ref trait_ } => { let ty = &*self_type; match **trait_ { Type::ResolvedPath { @@ -580,36 +580,30 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { continue; } - // FIXME: Remove this scope when NLL lands - { - let args = &mut new_trait_path - .segments - .last_mut() - .expect("segments were empty") - .args; - - match args { - // Convert somethiung like ' = u8' - // to 'T: Iterator' - &mut GenericArgs::AngleBracketed { - ref mut bindings, - .. - } => { - bindings.push(TypeBinding { - name: left_name.clone(), - kind: TypeBindingKind::Equality { ty: rhs }, - }); - } - &mut GenericArgs::Parenthesized { .. } => { - existing_predicates.push( - WherePredicate::EqPredicate { - lhs: lhs.clone(), - rhs, - }, - ); - continue; // If something other than a Fn ends up - // with parenthesis, leave it alone - } + let args = &mut new_trait_path + .segments + .last_mut() + .expect("segments were empty") + .args; + + match args { + // Convert somethiung like ' = u8' + // to 'T: Iterator' + GenericArgs::AngleBracketed { + ref mut bindings, .. + } => { + bindings.push(TypeBinding { + name: left_name.clone(), + kind: TypeBindingKind::Equality { ty: rhs }, + }); + } + GenericArgs::Parenthesized { .. } => { + existing_predicates.push(WherePredicate::EqPredicate { + lhs: lhs.clone(), + rhs, + }); + continue; // If something other than a Fn ends up + // with parenthesis, leave it alone } } From 11f74189f1fa92fce4d7bfec5d9eed4e1f0c352e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 Jan 2020 13:32:32 +0100 Subject: [PATCH 0310/1253] Clean up E0191 explanation --- src/librustc_error_codes/error_codes/E0191.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0191.md b/src/librustc_error_codes/error_codes/E0191.md index b79196f6cec7a..46b773bdc50d6 100644 --- a/src/librustc_error_codes/error_codes/E0191.md +++ b/src/librustc_error_codes/error_codes/E0191.md @@ -1,5 +1,6 @@ -Trait objects need to have all associated types specified. Erroneous code -example: +An associated type wasn't specified for a trait object. + +Erroneous code example: ```compile_fail,E0191 trait Trait { @@ -10,8 +11,9 @@ type Foo = Trait; // error: the value of the associated type `Bar` (from // the trait `Trait`) must be specified ``` -Please verify you specified all associated types of the trait and that you -used the right trait. Example: +Trait objects need to have all associated types specified. Please verify that +all associated types of the trait were specified and the correct trait was used. +Example: ``` trait Trait { From 3ec0a84e6ef35f58c837a0afbcf02b70ee543459 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 Jan 2020 13:34:55 +0100 Subject: [PATCH 0311/1253] Clean up E0192 explanation --- src/librustc_error_codes/error_codes/E0192.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/librustc_error_codes/error_codes/E0192.md b/src/librustc_error_codes/error_codes/E0192.md index 33308868cb235..5fd951b2e86cb 100644 --- a/src/librustc_error_codes/error_codes/E0192.md +++ b/src/librustc_error_codes/error_codes/E0192.md @@ -1,3 +1,19 @@ +A negative impl was added on a trait implementation. + +Erroneous code example: + +```compile_fail,E0192 +trait Trait { + type Bar; +} + +struct Foo; + +impl !Trait for Foo { } //~ ERROR E0192 + +fn main() {} +``` + Negative impls are only allowed for auto traits. For more information see the [opt-in builtin traits RFC][RFC 19]. From 894dc2d3d2b96e1f992324aa95125e0d161ab681 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jan 2020 15:36:05 +0100 Subject: [PATCH 0312/1253] Do not forget to provide queries. --- src/librustc_interface/passes.rs | 1 + src/librustc_passes/lib.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..787d9a8ed77d7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -677,6 +677,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { rustc_passes::provide(providers); rustc_resolve::provide(providers); rustc_traits::provide(providers); + rustc_ty::provide(providers); rustc_metadata::provide(providers); rustc_lint::provide(providers); rustc_codegen_utils::provide(providers); diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index c45f83f213078..65eb07b989d83 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(slice_patterns)] From 19f8c5824f1e431a08cfdfd27b816e48c56b4857 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 13 Jan 2020 23:45:20 +0900 Subject: [PATCH 0313/1253] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 43ac9416d9359..920cdb59e1edf 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 43ac9416d935942d6c7d2b2e0c876c551652c4ec +Subproject commit 920cdb59e1edf2c4cb2f266fa521f12c1b97a499 From 19b9b26986246b92e1f686a9a7b29da42a79ed9f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 13 Jan 2020 16:12:10 +0100 Subject: [PATCH 0314/1253] Early abort validation of arrays of zsts because there is no data to be checked --- src/librustc_mir/interpret/validity.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 12e8cb6071d92..2f0fb81fffd13 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -608,9 +608,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); } // This is the element type size. - let ty_size = self.ecx.layout_of(tys)?.size; + let layout = self.ecx.layout_of(tys)?; + // Empty tuples and fieldless structs (the only ZSTs that allow reaching this code) + // have no data to be checked. + if layout.is_zst() { + return Ok(()); + } // This is the size in bytes of the whole array. - let size = ty_size * len; + let size = layout.size * len; // Size is not 0, get a pointer. let ptr = self.ecx.force_ptr(mplace.ptr)?; @@ -640,7 +645,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // Some byte was undefined, determine which // element that byte belongs to so we can // provide an index. - let i = (offset.bytes() / ty_size.bytes()) as usize; + let i = (offset.bytes() / layout.size.bytes()) as usize; self.path.push(PathElem::ArrayElem(i)); throw_validation_failure!("undefined bytes", self.path) From a6c4025fac3c3a60581af72998230d46aa6f5ade Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 11 Jan 2020 15:22:36 +1300 Subject: [PATCH 0315/1253] perf: eagerly convert literals to consts, this avoids creating loads on unevaluated consts which requires a lot of unnecessary work to evaluate them further down the line. --- src/librustc/dep_graph/dep_node.rs | 2 +- src/librustc/mir/interpret/mod.rs | 21 ++++++- src/librustc/query/mod.rs | 9 ++- src/librustc/ty/query/keys.rs | 10 ++++ src/librustc/ty/query/mod.rs | 1 + src/librustc_mir/lib.rs | 2 +- src/librustc_mir_build/hair/constant.rs | 57 +++++++++++-------- src/librustc_mir_build/hair/cx/mod.rs | 4 +- src/librustc_mir_build/hair/mod.rs | 2 +- src/librustc_mir_build/hair/pattern/mod.rs | 52 ++++++++--------- src/librustc_mir_build/lib.rs | 1 + src/librustc_typeck/astconv.rs | 40 ++++++++----- src/libsyntax/ast.rs | 41 ++++++++++--- .../ui/consts/const-eval/ub-nonnull.stderr | 2 +- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 2 +- src/test/ui/symbol-names/impl1.legacy.stderr | 8 +-- src/test/ui/symbol-names/impl1.rs | 10 ++-- src/test/ui/symbol-names/impl1.v0.stderr | 2 +- 18 files changed, 175 insertions(+), 91 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 858627a1e8962..9df8e28254cf5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -52,7 +52,7 @@ use crate::hir::map::DefPathHash; use crate::ich::{Fingerprint, StableHashingContext}; use crate::mir; -use crate::mir::interpret::GlobalId; +use crate::mir::interpret::{GlobalId, LitToConstInput}; use crate::traits; use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 99113d6ef1836..21cc54a6e6b2d 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -119,7 +119,7 @@ use crate::mir; use crate::ty::codec::TyDecoder; use crate::ty::layout::{self, Size}; use crate::ty::subst::GenericArgKind; -use crate::ty::{self, Instance, TyCtxt}; +use crate::ty::{self, Instance, Ty, TyCtxt}; use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; @@ -131,6 +131,7 @@ use std::fmt; use std::io; use std::num::NonZeroU32; use std::sync::atomic::{AtomicU32, Ordering}; +use syntax::ast::LitKind; /// Uniquely identifies one of the following: /// - A constant @@ -147,6 +148,24 @@ pub struct GlobalId<'tcx> { pub promoted: Option, } +/// Input argument for `tcx.lit_to_const` +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable)] +pub struct LitToConstInput<'tcx> { + /// The absolute value of the resultant constant + pub lit: &'tcx LitKind, + /// The type of the constant + pub ty: Ty<'tcx>, + /// If the constant is negative + pub neg: bool, +} + +/// Error type for `tcx.lit_to_const` +#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] +pub enum LitToConstError { + UnparseableFloat, + Reported, +} + #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] pub struct AllocId(pub u64); diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 50ef115da2c42..f4c262fbac1d4 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1,6 +1,6 @@ use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex}; use crate::mir; -use crate::mir::interpret::GlobalId; +use crate::mir::interpret::{GlobalId, LitToConstInput}; use crate::traits; use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, @@ -518,6 +518,13 @@ rustc_queries! { no_force desc { "get a &core::panic::Location referring to a span" } } + + query lit_to_const( + key: LitToConstInput<'tcx> + ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { + no_force + desc { "converting literal to const" } + } } TypeChecking { diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d64f27d9cc26c..cbf335ad607ef 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -52,6 +52,16 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { } } +impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl Key for CrateNum { fn query_crate(&self) -> CrateNum { *self diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 1d41871bb33a9..0f09a08b199f1 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -15,6 +15,7 @@ use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; +use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use crate::session::CrateDisambiguator; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 1ff529181f705..1c25b269b18fd 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -62,5 +62,5 @@ pub fn provide(providers: &mut Providers<'_>) { providers.destructure_const = |tcx, param_env_and_value| { let (param_env, value) = param_env_and_value.into_parts(); const_eval::destructure_const(tcx, param_env, value) - } + }; } diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs index a4bedfa6490e2..266f4738c50a6 100644 --- a/src/librustc_mir_build/hair/constant.rs +++ b/src/librustc_mir_build/hair/constant.rs @@ -1,21 +1,15 @@ -use rustc::mir::interpret::{ConstValue, Scalar}; -use rustc::ty::{self, layout::Size, ParamEnv, Ty, TyCtxt}; +use rustc::mir::interpret::{ + truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, +}; +use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt}; use rustc_span::symbol::Symbol; use syntax::ast; -#[derive(PartialEq)] -crate enum LitToConstError { - UnparseableFloat, - Reported, -} - crate fn lit_to_const<'tcx>( - lit: &'tcx ast::LitKind, tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - neg: bool, + lit_input: LitToConstInput<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { - use syntax::ast::*; + let LitToConstInput { lit, ty, neg } = lit_input; let trunc = |n| { let param_ty = ParamEnv::reveal_all().and(ty); @@ -26,35 +20,50 @@ crate fn lit_to_const<'tcx>( Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) }; - use rustc::mir::interpret::*; let lit = match *lit { - LitKind::Str(ref s, _) => { + ast::LitKind::Str(ref s, _) => { let s = s.as_str(); let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes()); let allocation = tcx.intern_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: s.len() } } - LitKind::ByteStr(ref data) => { - let id = tcx.allocate_bytes(data); - ConstValue::Scalar(Scalar::Ptr(id.into())) + ast::LitKind::ByteStr(ref data) => { + if let ty::Ref(_, ref_ty, _) = ty.kind { + match ref_ty.kind { + ty::Slice(_) => { + let allocation = Allocation::from_byte_aligned_bytes(data as &Vec); + let allocation = tcx.intern_const_alloc(allocation); + ConstValue::Slice { data: allocation, start: 0, end: data.len() } + } + ty::Array(_, _) => { + let id = tcx.allocate_bytes(data); + ConstValue::Scalar(Scalar::Ptr(id.into())) + } + _ => { + bug!("bytestring should have type of either &[u8] or &[u8; _], not {}", ty) + } + } + } else { + bug!("bytestring should have type of either &[u8] or &[u8; _], not {}", ty) + } } - LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))), - LitKind::Int(n, _) if neg => { + ast::LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))), + ast::LitKind::Int(n, _) if neg => { let n = n as i128; let n = n.overflowing_neg().0; trunc(n as u128)? } - LitKind::Int(n, _) => trunc(n)?, - LitKind::Float(n, _) => { + ast::LitKind::Int(n, _) => trunc(n)?, + ast::LitKind::Float(n, _) => { let fty = match ty.kind { ty::Float(fty) => fty, _ => bug!(), }; parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)? } - LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)), - LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)), - LitKind::Err(_) => unreachable!(), + ast::LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)), + ast::LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)), + ast::LitKind::Err(_) => return Err(LitToConstError::Reported), }; Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Value(lit), ty })) } diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs index 5fc9a1ecad555..497c6610550f3 100644 --- a/src/librustc_mir_build/hair/cx/mod.rs +++ b/src/librustc_mir_build/hair/cx/mod.rs @@ -5,9 +5,9 @@ use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::*; -use crate::hair::constant::{lit_to_const, LitToConstError}; use rustc::infer::InferCtxt; use rustc::middle::region; +use rustc::mir::interpret::{LitToConstError, LitToConstInput}; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::Subst; use rustc::ty::subst::{GenericArg, InternalSubsts}; @@ -136,7 +136,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { ) -> &'tcx ty::Const<'tcx> { trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg); - match lit_to_const(lit, self.tcx, ty, neg) { + match self.tcx.at(sp).lit_to_const(LitToConstInput { lit, ty, neg }) { Ok(c) => c, Err(LitToConstError::UnparseableFloat) => { // FIXME(#31407) this is only necessary because float parsing is buggy diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs index 3257f282dc1cb..0f2c76152edae 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -16,7 +16,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::Span; -mod constant; +crate mod constant; crate mod cx; crate mod pattern; diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 9e00c4ea53a0f..8645abe5c1acc 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -6,10 +6,11 @@ mod const_to_pat; pub(crate) use self::check_match::check_match; -use crate::hair::constant::*; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled}; +use rustc::mir::interpret::{ + get_slice_bytes, sign_extend, ConstValue, ErrorHandled, LitToConstError, LitToConstInput, +}; use rustc::mir::UserTypeProjection; use rustc::mir::{BorrowKind, Field, Mutability}; use rustc::ty::layout::VariantIdx; @@ -822,35 +823,30 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { /// which would overflow if we tried to evaluate `128_i8` and then negate /// afterwards. fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> { - match expr.kind { - hir::ExprKind::Lit(ref lit) => { - let ty = self.tables.expr_ty(expr); - match lit_to_const(&lit.node, self.tcx, ty, false) { - Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind, - Err(LitToConstError::UnparseableFloat) => { - self.errors.push(PatternError::FloatBug); - PatKind::Wild - } - Err(LitToConstError::Reported) => PatKind::Wild, + if let hir::ExprKind::Path(ref qpath) = expr.kind { + *self.lower_path(qpath, expr.hir_id, expr.span).kind + } else { + let (lit, neg) = match expr.kind { + hir::ExprKind::Lit(ref lit) => (lit, false), + hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => { + let lit = match expr.kind { + hir::ExprKind::Lit(ref lit) => lit, + _ => span_bug!(expr.span, "not a literal: {:?}", expr), + }; + (lit, true) } - } - hir::ExprKind::Path(ref qpath) => *self.lower_path(qpath, expr.hir_id, expr.span).kind, - hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => { - let ty = self.tables.expr_ty(expr); - let lit = match expr.kind { - hir::ExprKind::Lit(ref lit) => lit, - _ => span_bug!(expr.span, "not a literal: {:?}", expr), - }; - match lit_to_const(&lit.node, self.tcx, ty, true) { - Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind, - Err(LitToConstError::UnparseableFloat) => { - self.errors.push(PatternError::FloatBug); - PatKind::Wild - } - Err(LitToConstError::Reported) => PatKind::Wild, + _ => span_bug!(expr.span, "not a literal: {:?}", expr), + }; + + let lit_input = LitToConstInput { lit: &lit.node, ty: self.tables.expr_ty(expr), neg }; + match self.tcx.at(expr.span).lit_to_const(lit_input) { + Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind, + Err(LitToConstError::UnparseableFloat) => { + self.errors.push(PatternError::FloatBug); + PatKind::Wild } + Err(LitToConstError::Reported) => PatKind::Wild, } - _ => span_bug!(expr.span, "not a literal: {:?}", expr), } } } diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index 96032a732abd6..5a17f36e1da25 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -22,5 +22,6 @@ use rustc::ty::query::Providers; pub fn provide(providers: &mut Providers<'_>) { providers.check_match = hair::pattern::check_match; + providers.lit_to_const = hair::constant::lit_to_const; providers.mir_built = build::mir_built; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index dae394b8f4bd4..920ffaa4c3a0b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength FIXME(#67418) Split up this file //! Conversion from AST representation of types to the `ty.rs` representation. //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an //! instance of `AstConv`. @@ -37,6 +38,7 @@ use std::collections::BTreeSet; use std::iter; use std::slice; +use rustc::mir::interpret::LitToConstInput; use rustc_error_codes::*; #[derive(Debug)] @@ -2699,17 +2701,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let def_id = tcx.hir().local_def_id(ast_const.hir_id); - let mut const_ = ty::Const { - val: ty::ConstKind::Unevaluated( - def_id, - InternalSubsts::identity_for_item(tcx, def_id), - None, - ), - ty, + let expr = &tcx.hir().body(ast_const.body).value; + + let lit_input = match expr.kind { + hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), + hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind { + hir::ExprKind::Lit(ref lit) => { + Some(LitToConstInput { lit: &lit.node, ty, neg: true }) + } + _ => None, + }, + _ => None, }; - let expr = &tcx.hir().body(ast_const.body).value; - if let Some(def_id) = self.const_param_def_id(expr) { + if let Some(lit_input) = lit_input { + // If an error occurred, ignore that it's a literal and leave reporting the error up to + // mir + if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) { + return c; + } + } + + let kind = if let Some(def_id) = self.const_param_def_id(expr) { // Find the name and index of the const parameter by indexing the generics of the // parent item and construct a `ParamConst`. let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -2718,10 +2731,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)]; let name = tcx.hir().name(hir_id); - const_.val = ty::ConstKind::Param(ty::ParamConst::new(index, name)); - } - - tcx.mk_const(const_) + ty::ConstKind::Param(ty::ParamConst::new(index, name)) + } else { + ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None) + }; + tcx.mk_const(ty::Const { val: kind, ty }) } pub fn impl_trait_ty_to_ty( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 33acba8eba010..ace12a7ffd208 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1441,8 +1441,17 @@ pub struct MacroDef { pub legacy: bool, } -// Clippy uses Hash and PartialEq -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq, HashStable_Generic)] +#[derive( + Clone, + RustcEncodable, + RustcDecodable, + Debug, + Copy, + Hash, + Eq, + PartialEq, + HashStable_Generic +)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1491,9 +1500,18 @@ impl StrLit { } } -// Clippy uses Hash and PartialEq /// Type of the integer literal based on provided suffix. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] +#[derive( + Clone, + Copy, + RustcEncodable, + RustcDecodable, + Debug, + Hash, + Eq, + PartialEq, + HashStable_Generic +)] pub enum LitIntType { /// e.g. `42_i32`. Signed(IntTy), @@ -1504,7 +1522,17 @@ pub enum LitIntType { } /// Type of the float literal based on provided suffix. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] +#[derive( + Clone, + Copy, + RustcEncodable, + RustcDecodable, + Debug, + Hash, + Eq, + PartialEq, + HashStable_Generic +)] pub enum LitFloatType { /// A float literal with a suffix (`1f32` or `1E10f32`). Suffixed(FloatTy), @@ -1515,8 +1543,7 @@ pub enum LitFloatType { /// Literal kind. /// /// E.g., `"foo"`, `42`, `12.34`, or `bool`. -// Clippy uses Hash and PartialEq -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)] pub enum LitKind { /// A string literal (`"foo"`). Str(Symbol, StrStyle), diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index ea9fffa883ea5..c2446d1404019 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! LL | | let out_of_bounds_ptr = &ptr[255]; - | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 9 which has size 1 + | | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1 LL | | mem::transmute(out_of_bounds_ptr) LL | | } }; | |____- 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 0ae64edcc0546..7d3c99bda6b6a 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -59,7 +59,7 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 | LL | type A = [u8; 4]::AssocTy; - | ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; _] as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; 4] as Trait>::AssocTy` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:5:10 diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index affb5537b1856..8e498e4b39477 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -46,25 +46,25 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17hf07584432cd4d8beE) +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h62e540f14f879d56E) --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::hf07584432cd4d8be) +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::h62e540f14f879d56) --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) +error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index c1aaec5169d8b..b054c1373e66c 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -60,15 +60,15 @@ fn main() { // Test type mangling, by putting them in an `impl` header. impl Bar for [&'_ (dyn Foo + AutoTrait); 3] { #[rustc_symbol_name] - //[legacy]~^ ERROR symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method - //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method - //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) + //[legacy]~^ ERROR symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method + //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method + //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) #[rustc_def_path] - //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) - //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) + //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) fn method(&self) {} } }; diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index a931937d1a813..111c360b36080 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -64,7 +64,7 @@ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, .. LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] From 02fffc1556e01c64d84d07d0a3ab059a9c7505f8 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 11 Jan 2020 20:57:38 +1300 Subject: [PATCH 0316/1253] Code review changes and fix rustdoc test. --- src/librustc/mir/interpret/mod.rs | 10 +++--- src/librustc_mir_build/hair/pattern/mod.rs | 5 ++- src/librustc_typeck/astconv.rs | 4 +-- src/libsyntax/ast.rs | 39 ++++----------------- src/test/rustdoc/const-generics/add-impl.rs | 2 +- 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 21cc54a6e6b2d..47f067590b9d5 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -148,18 +148,18 @@ pub struct GlobalId<'tcx> { pub promoted: Option, } -/// Input argument for `tcx.lit_to_const` +/// Input argument for `tcx.lit_to_const`. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable)] pub struct LitToConstInput<'tcx> { - /// The absolute value of the resultant constant + /// The absolute value of the resultant constant. pub lit: &'tcx LitKind, - /// The type of the constant + /// The type of the constant. pub ty: Ty<'tcx>, - /// If the constant is negative + /// If the constant is negative. pub neg: bool, } -/// Error type for `tcx.lit_to_const` +/// Error type for `tcx.lit_to_const`. #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] pub enum LitToConstError { UnparseableFloat, diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 8645abe5c1acc..205e25f7f8f0c 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -8,9 +8,8 @@ pub(crate) use self::check_match::check_match; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc::mir::interpret::{ - get_slice_bytes, sign_extend, ConstValue, ErrorHandled, LitToConstError, LitToConstInput, -}; +use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled}; +use rustc::mir::interpret::{LitToConstError, LitToConstInput}; use rustc::mir::UserTypeProjection; use rustc::mir::{BorrowKind, Field, Mutability}; use rustc::ty::layout::VariantIdx; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 920ffaa4c3a0b..a3be264ddc128 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1,4 +1,4 @@ -// ignore-tidy-filelength FIXME(#67418) Split up this file +// ignore-tidy-filelength FIXME(#67418) Split up this file. //! Conversion from AST representation of types to the `ty.rs` representation. //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an //! instance of `AstConv`. @@ -2716,7 +2716,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(lit_input) = lit_input { // If an error occurred, ignore that it's a literal and leave reporting the error up to - // mir + // mir. if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) { return c; } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ace12a7ffd208..331eb109ec0b4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1441,17 +1441,8 @@ pub struct MacroDef { pub legacy: bool, } -#[derive( - Clone, - RustcEncodable, - RustcDecodable, - Debug, - Copy, - Hash, - Eq, - PartialEq, - HashStable_Generic -)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)] +#[derive(HashStable_Generic)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1501,17 +1492,8 @@ impl StrLit { } /// Type of the integer literal based on provided suffix. -#[derive( - Clone, - Copy, - RustcEncodable, - RustcDecodable, - Debug, - Hash, - Eq, - PartialEq, - HashStable_Generic -)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)] +#[derive(HashStable_Generic)] pub enum LitIntType { /// e.g. `42_i32`. Signed(IntTy), @@ -1522,17 +1504,8 @@ pub enum LitIntType { } /// Type of the float literal based on provided suffix. -#[derive( - Clone, - Copy, - RustcEncodable, - RustcDecodable, - Debug, - Hash, - Eq, - PartialEq, - HashStable_Generic -)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)] +#[derive(HashStable_Generic)] pub enum LitFloatType { /// A float literal with a suffix (`1f32` or `1E10f32`). Suffixed(FloatTy), diff --git a/src/test/rustdoc/const-generics/add-impl.rs b/src/test/rustdoc/const-generics/add-impl.rs index ed45d339728bc..54bdd768f8a73 100644 --- a/src/test/rustdoc/const-generics/add-impl.rs +++ b/src/test/rustdoc/const-generics/add-impl.rs @@ -11,7 +11,7 @@ pub struct Simd { inner: T, } -// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add> for Simd' +// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add> for Simd' impl Add for Simd { type Output = Self; From d975228cedeaab828e91ab72d4d6fb5ded324de8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 14 Jan 2020 04:44:57 +0900 Subject: [PATCH 0317/1253] Tweak assertion note in fmt --- src/bootstrap/format.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 65b654fb51929..6e5e3fe07e746 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -20,7 +20,15 @@ fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) { cmd.arg(&path); let cmd_debug = format!("{:?}", cmd); let status = cmd.status().expect("executing rustfmt"); - assert!(status.success(), "running {} successful", cmd_debug); + if !status.success() { + eprintln!( + "Running `{}` failed.\nIf you're running `tidy`, \ + try again with `--bless` flag. Or, you just want to format \ + code, run `./x.py fmt` instead.", + cmd_debug, + ); + std::process::exit(1); + } } #[derive(serde::Deserialize)] From 6421127340047130e546af9dc3afb45643cf692f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 7 Jan 2020 00:51:00 +0900 Subject: [PATCH 0318/1253] Update rustc-guide --- src/doc/rustc-guide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide index b5c6babcdd4ce..92baf7293dd2d 160000 --- a/src/doc/rustc-guide +++ b/src/doc/rustc-guide @@ -1 +1 @@ -Subproject commit b5c6babcdd4ce1fa90458b7827a5fde082e79e87 +Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7 From 72710d6dc2d0511cd21378f7cc99ac59ac3a5af5 Mon Sep 17 00:00:00 2001 From: Konstantinos Triantafyllou Date: Fri, 10 Jan 2020 20:15:16 +0100 Subject: [PATCH 0319/1253] Add unreachable propagation mir optimization pass --- src/librustc_mir/transform/mod.rs | 2 + .../transform/unreachable_prop.rs | 108 ++++++++++++++++++ src/test/mir-opt/simplify_try.rs | 26 ++--- .../mir-opt/uninhabited_enum_branching.rs | 81 +++++-------- src/test/mir-opt/unreachable.rs | 78 +++++++++++++ src/test/mir-opt/unreachable_asm.rs | 72 ++++++++++++ src/test/mir-opt/unreachable_asm_2.rs | 84 ++++++++++++++ src/test/mir-opt/unreachable_diverging.rs | 65 +++++++++++ 8 files changed, 449 insertions(+), 67 deletions(-) create mode 100644 src/librustc_mir/transform/unreachable_prop.rs create mode 100644 src/test/mir-opt/unreachable.rs create mode 100644 src/test/mir-opt/unreachable_asm.rs create mode 100644 src/test/mir-opt/unreachable_asm_2.rs create mode 100644 src/test/mir-opt/unreachable_diverging.rs diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 22aed9a9e66bd..3c37eccc1843b 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -36,6 +36,7 @@ pub mod simplify; pub mod simplify_branches; pub mod simplify_try; pub mod uninhabited_enum_branching; +pub mod unreachable_prop; pub(crate) fn provide(providers: &mut Providers<'_>) { self::check_unsafety::provide(providers); @@ -299,6 +300,7 @@ fn run_optimization_passes<'tcx>( // From here on out, regions are gone. &erase_regions::EraseRegions, // Optimizations begin. + &unreachable_prop::UnreachablePropagation, &uninhabited_enum_branching::UninhabitedEnumBranching, &simplify::SimplifyCfg::new("after-uninhabited-enum-branching"), &inline::Inline, diff --git a/src/librustc_mir/transform/unreachable_prop.rs b/src/librustc_mir/transform/unreachable_prop.rs new file mode 100644 index 0000000000000..27173e0c171b7 --- /dev/null +++ b/src/librustc_mir/transform/unreachable_prop.rs @@ -0,0 +1,108 @@ +//! A pass that propagates the unreachable terminator of a block to its predecessors +//! when all of their successors are unreachable. This is achieved through a +//! post-order traversal of the blocks. + +use crate::transform::simplify; +use crate::transform::{MirPass, MirSource}; +use rustc::mir::*; +use rustc::ty::TyCtxt; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use std::borrow::Cow; + +pub struct UnreachablePropagation; + +impl MirPass<'_> for UnreachablePropagation { + fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { + if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { + // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt + // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code. + return; + } + + let mut unreachable_blocks = FxHashSet::default(); + let mut replacements = FxHashMap::default(); + + for (bb, bb_data) in traversal::postorder(body) { + let terminator = bb_data.terminator(); + // HACK: If the block contains any asm statement it is not regarded as unreachable. + // This is a temporary solution that handles possibly diverging asm statements. + // Accompanying testcases: mir-opt/unreachable_asm.rs and mir-opt/unreachable_asm_2.rs + let asm_stmt_in_block = || { + bb_data.statements.iter().any(|stmt: &Statement<'_>| match stmt.kind { + StatementKind::InlineAsm(..) => true, + _ => false, + }) + }; + + if terminator.kind == TerminatorKind::Unreachable && !asm_stmt_in_block() { + unreachable_blocks.insert(bb); + } else { + let is_unreachable = |succ: BasicBlock| unreachable_blocks.contains(&succ); + let terminator_kind_opt = remove_successors(&terminator.kind, is_unreachable); + + if let Some(terminator_kind) = terminator_kind_opt { + if terminator_kind == TerminatorKind::Unreachable && !asm_stmt_in_block() { + unreachable_blocks.insert(bb); + } + replacements.insert(bb, terminator_kind); + } + } + } + + let replaced = !replacements.is_empty(); + for (bb, terminator_kind) in replacements { + body.basic_blocks_mut()[bb].terminator_mut().kind = terminator_kind; + } + + if replaced { + simplify::remove_dead_blocks(body); + } + } +} + +fn remove_successors( + terminator_kind: &TerminatorKind<'tcx>, + predicate: F, +) -> Option> +where + F: Fn(BasicBlock) -> bool, +{ + match *terminator_kind { + TerminatorKind::Goto { target } if predicate(target) => Some(TerminatorKind::Unreachable), + TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { + let original_targets_len = targets.len(); + let (otherwise, targets) = targets.split_last().unwrap(); + let retained = values + .iter() + .zip(targets.iter()) + .filter(|(_, &t)| !predicate(t)) + .collect::>(); + let mut values = retained.iter().map(|&(v, _)| *v).collect::>(); + let mut targets = retained.iter().map(|&(_, d)| *d).collect::>(); + + if !predicate(*otherwise) { + targets.push(*otherwise); + } else { + values.pop(); + } + + let retained_targets_len = targets.len(); + + if targets.is_empty() { + Some(TerminatorKind::Unreachable) + } else if targets.len() == 1 { + Some(TerminatorKind::Goto { target: targets[0] }) + } else if original_targets_len != retained_targets_len { + Some(TerminatorKind::SwitchInt { + discr: discr.clone(), + switch_ty, + values: Cow::from(values), + targets, + }) + } else { + None + } + } + _ => None, + } +} diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs index 656b405ef340e..d85eff45b4989 100644 --- a/src/test/mir-opt/simplify_try.rs +++ b/src/test/mir-opt/simplify_try.rs @@ -47,25 +47,22 @@ fn main() { // } // bb0: { // _5 = discriminant(_1); -// switchInt(move _5) -> [0isize: bb4, 1isize: bb2, otherwise: bb1]; +// switchInt(move _5) -> [0isize: bb3, otherwise: bb1]; // } // bb1: { -// unreachable; -// } -// bb2: { // _6 = ((_1 as Err).0: i32); // ((_0 as Err).0: i32) = move _6; // discriminant(_0) = 1; -// goto -> bb3; +// goto -> bb2; // } -// bb3: { +// bb2: { // return; // } -// bb4: { +// bb3: { // _10 = ((_1 as Ok).0: u32); // ((_0 as Ok).0: u32) = move _10; // discriminant(_0) = 0; -// goto -> bb3; +// goto -> bb2; // } // } // END rustc.try_identity.SimplifyArmIdentity.before.mir @@ -109,25 +106,22 @@ fn main() { // } // bb0: { // _5 = discriminant(_1); -// switchInt(move _5) -> [0isize: bb4, 1isize: bb2, otherwise: bb1]; +// switchInt(move _5) -> [0isize: bb3, otherwise: bb1]; // } // bb1: { -// unreachable; -// } -// bb2: { // _0 = move _1; // nop; // nop; -// goto -> bb3; +// goto -> bb2; // } -// bb3: { +// bb2: { // return; // } -// bb4: { +// bb3: { // _0 = move _1; // nop; // nop; -// goto -> bb3; +// goto -> bb2; // } // } // END rustc.try_identity.SimplifyArmIdentity.after.mir diff --git a/src/test/mir-opt/uninhabited_enum_branching.rs b/src/test/mir-opt/uninhabited_enum_branching.rs index aa56918a9b8c1..dda5fd4fb7577 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.rs +++ b/src/test/mir-opt/uninhabited_enum_branching.rs @@ -45,53 +45,47 @@ fn main() { // StorageLive(_2); // _2 = Test1::C; // _3 = discriminant(_2); -// switchInt(move _3) -> [0isize: bb3, 1isize: bb4, 2isize: bb1, otherwise: bb2]; +// switchInt(move _3) -> [0isize: bb2, 1isize: bb3, otherwise: bb1]; // } // bb1: { // StorageLive(_5); // _5 = const "C"; // _1 = &(*_5); // StorageDead(_5); -// goto -> bb5; +// goto -> bb4; // } // bb2: { -// unreachable; -// } -// bb3: { // _1 = const "A(Empty)"; -// goto -> bb5; +// goto -> bb4; // } -// bb4: { +// bb3: { // StorageLive(_4); // _4 = const "B(Empty)"; // _1 = &(*_4); // StorageDead(_4); -// goto -> bb5; +// goto -> bb4; // } -// bb5: { +// bb4: { // StorageDead(_2); // StorageDead(_1); // StorageLive(_6); // StorageLive(_7); // _7 = Test2::D; // _8 = discriminant(_7); -// switchInt(move _8) -> [4isize: bb8, 5isize: bb6, otherwise: bb7]; +// switchInt(move _8) -> [4isize: bb6, otherwise: bb5]; // } -// bb6: { +// bb5: { // StorageLive(_9); // _9 = const "E"; // _6 = &(*_9); // StorageDead(_9); -// goto -> bb9; -// } -// bb7: { -// unreachable; +// goto -> bb7; // } -// bb8: { +// bb6: { // _6 = const "D"; -// goto -> bb9; +// goto -> bb7; // } -// bb9: { +// bb7: { // StorageDead(_7); // StorageDead(_6); // _0 = (); @@ -114,53 +108,47 @@ fn main() { // StorageLive(_2); // _2 = Test1::C; // _3 = discriminant(_2); -// switchInt(move _3) -> [2isize: bb1, otherwise: bb2]; +// switchInt(move _3) -> bb1; // } // bb1: { // StorageLive(_5); // _5 = const "C"; // _1 = &(*_5); // StorageDead(_5); -// goto -> bb5; +// goto -> bb4; // } // bb2: { -// unreachable; -// } -// bb3: { // _1 = const "A(Empty)"; -// goto -> bb5; +// goto -> bb4; // } -// bb4: { +// bb3: { // StorageLive(_4); // _4 = const "B(Empty)"; // _1 = &(*_4); // StorageDead(_4); -// goto -> bb5; +// goto -> bb4; // } -// bb5: { +// bb4: { // StorageDead(_2); // StorageDead(_1); // StorageLive(_6); // StorageLive(_7); // _7 = Test2::D; // _8 = discriminant(_7); -// switchInt(move _8) -> [4isize: bb8, 5isize: bb6, otherwise: bb7]; +// switchInt(move _8) -> [4isize: bb6, otherwise: bb5]; // } -// bb6: { +// bb5: { // StorageLive(_9); // _9 = const "E"; // _6 = &(*_9); // StorageDead(_9); -// goto -> bb9; +// goto -> bb7; // } -// bb7: { -// unreachable; -// } -// bb8: { +// bb6: { // _6 = const "D"; -// goto -> bb9; +// goto -> bb7; // } -// bb9: { +// bb7: { // StorageDead(_7); // StorageDead(_6); // _0 = (); @@ -183,9 +171,6 @@ fn main() { // StorageLive(_2); // _2 = Test1::C; // _3 = discriminant(_2); -// switchInt(move _3) -> [2isize: bb1, otherwise: bb2]; -// } -// bb1: { // StorageLive(_5); // _5 = const "C"; // _1 = &(*_5); @@ -196,26 +181,20 @@ fn main() { // StorageLive(_7); // _7 = Test2::D; // _8 = discriminant(_7); -// switchInt(move _8) -> [4isize: bb5, 5isize: bb3, otherwise: bb4]; -// } -// bb2: { -// unreachable; +// switchInt(move _8) -> [4isize: bb2, otherwise: bb1]; // } -// bb3: { +// bb1: { // StorageLive(_9); // _9 = const "E"; // _6 = &(*_9); // StorageDead(_9); -// goto -> bb6; -// } -// bb4: { -// unreachable; +// goto -> bb3; // } -// bb5: { +// bb2: { // _6 = const "D"; -// goto -> bb6; +// goto -> bb3; // } -// bb6: { +// bb3: { // StorageDead(_7); // StorageDead(_6); // _0 = (); diff --git a/src/test/mir-opt/unreachable.rs b/src/test/mir-opt/unreachable.rs new file mode 100644 index 0000000000000..fa5c1a074ee15 --- /dev/null +++ b/src/test/mir-opt/unreachable.rs @@ -0,0 +1,78 @@ +enum Empty {} + +fn empty() -> Option { + None +} + +fn main() { + if let Some(_x) = empty() { + let mut _y; + + if true { + _y = 21; + } else { + _y = 42; + } + + match _x { } + } +} + +// END RUST SOURCE +// START rustc.main.UnreachablePropagation.before.mir +// bb0: { +// StorageLive(_1); +// _1 = const empty() -> bb1; +// } +// bb1: { +// _2 = discriminant(_1); +// switchInt(move _2) -> [1isize: bb3, otherwise: bb2]; +// } +// bb2: { +// _0 = (); +// StorageDead(_1); +// return; +// } +// bb3: { +// StorageLive(_3); +// _3 = move ((_1 as Some).0: Empty); +// StorageLive(_4); +// StorageLive(_5); +// StorageLive(_6); +// _6 = const true; +// switchInt(_6) -> [false: bb4, otherwise: bb5]; +// } +// bb4: { +// _4 = const 42i32; +// _5 = (); +// goto -> bb6; +// } +// bb5: { +// _4 = const 21i32; +// _5 = (); +// goto -> bb6; +// } +// bb6: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_7); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.before.mir +// START rustc.main.UnreachablePropagation.after.mir +// bb0: { +// StorageLive(_1); +// _1 = const empty() -> bb1; +// } +// bb1: { +// _2 = discriminant(_1); +// goto -> bb2; +// } +// bb2: { +// _0 = (); +// StorageDead(_1); +// return; +// } +// } +// END rustc.main.UnreachablePropagation.after.mir diff --git a/src/test/mir-opt/unreachable_asm.rs b/src/test/mir-opt/unreachable_asm.rs new file mode 100644 index 0000000000000..ca614ac32b764 --- /dev/null +++ b/src/test/mir-opt/unreachable_asm.rs @@ -0,0 +1,72 @@ +// ignore-tidy-linelength +#![feature(asm)] + +enum Empty {} + +fn empty() -> Option { + None +} + +fn main() { + if let Some(_x) = empty() { + let mut _y; + + if true { + _y = 21; + } else { + _y = 42; + } + + // asm instruction stops unreachable propagation to if else blocks bb4 and bb5. + unsafe { asm!("NOP"); } + match _x { } + } +} + +// END RUST SOURCE +// START rustc.main.UnreachablePropagation.before.mir +// bb4: { +// _4 = const 42i32; +// _5 = (); +// goto -> bb6; +// } +// bb5: { +// _4 = const 21i32; +// _5 = (); +// goto -> bb6; +// } +// bb6: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_7); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _7 = (); +// StorageDead(_7); +// StorageLive(_8); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.before.mir +// START rustc.main.UnreachablePropagation.after.mir +// bb4: { +// _4 = const 42i32; +// _5 = (); +// goto -> bb6; +// } +// bb5: { +// _4 = const 21i32; +// _5 = (); +// goto -> bb6; +// } +// bb6: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_7); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _7 = (); +// StorageDead(_7); +// StorageLive(_8); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.after.mir diff --git a/src/test/mir-opt/unreachable_asm_2.rs b/src/test/mir-opt/unreachable_asm_2.rs new file mode 100644 index 0000000000000..8fdbcfb5cab7f --- /dev/null +++ b/src/test/mir-opt/unreachable_asm_2.rs @@ -0,0 +1,84 @@ +// ignore-tidy-linelength +#![feature(asm)] + +enum Empty {} + +fn empty() -> Option { + None +} + +fn main() { + if let Some(_x) = empty() { + let mut _y; + + if true { + // asm instruction stops unreachable propagation to block bb3. + unsafe { asm!("NOP"); } + _y = 21; + } else { + // asm instruction stops unreachable propagation to block bb3. + unsafe { asm!("NOP"); } + _y = 42; + } + + match _x { } + } +} + +// END RUST SOURCE +// START rustc.main.UnreachablePropagation.before.mir +// bb3: { +// ... +// switchInt(_6) -> [false: bb4, otherwise: bb5]; +// } +// bb4: { +// StorageLive(_8); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _8 = (); +// StorageDead(_8); +// _4 = const 42i32; +// _5 = (); +// goto -> bb6; +// } +// bb5: { +// StorageLive(_7); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _7 = (); +// StorageDead(_7); +// _4 = const 21i32; +// _5 = (); +// goto -> bb6; +// } +// bb6: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_9); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.before.mir +// START rustc.main.UnreachablePropagation.after.mir +// bb3: { +// ... +// switchInt(_6) -> [false: bb4, otherwise: bb5]; +// } +// bb4: { +// StorageLive(_8); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _8 = (); +// StorageDead(_8); +// _4 = const 42i32; +// _5 = (); +// unreachable; +// } +// bb5: { +// StorageLive(_7); +// asm!(InlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); +// _7 = (); +// StorageDead(_7); +// _4 = const 21i32; +// _5 = (); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.after.mir diff --git a/src/test/mir-opt/unreachable_diverging.rs b/src/test/mir-opt/unreachable_diverging.rs new file mode 100644 index 0000000000000..bf05019d5ced1 --- /dev/null +++ b/src/test/mir-opt/unreachable_diverging.rs @@ -0,0 +1,65 @@ +pub enum Empty {} + +fn empty() -> Option { + None +} + +fn loop_forever() { + loop {} +} + +fn main() { + let x = true; + if let Some(bomb) = empty() { + if x { + loop_forever() + } + match bomb {} + } +} + +// END RUST SOURCE +// START rustc.main.UnreachablePropagation.before.mir +// bb3: { +// StorageLive(_4); +// _4 = move ((_2 as Some).0: Empty); +// StorageLive(_5); +// StorageLive(_6); +// _6 = _1; +// switchInt(_6) -> [false: bb4, otherwise: bb5]; +// } +// bb4: { +// _5 = (); +// goto -> bb6; +// } +// bb5: { +// _5 = const loop_forever() -> bb6; +// } +// bb6: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_7); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.before.mir +// START rustc.main.UnreachablePropagation.after.mir +// bb3: { +// StorageLive(_4); +// _4 = move ((_2 as Some).0: Empty); +// StorageLive(_5); +// StorageLive(_6); +// _6 = _1; +// goto -> bb4; +// } +// bb4: { +// _5 = const loop_forever() -> bb5; +// } +// bb5: { +// StorageDead(_6); +// StorageDead(_5); +// StorageLive(_7); +// unreachable; +// } +// } +// END rustc.main.UnreachablePropagation.after.mir From 30dba975400054424dd0ff31bea9fd312bc68d2c Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Tue, 14 Jan 2020 20:41:14 +1300 Subject: [PATCH 0320/1253] Normalize symbol hash in ui test for legacy symbol mangling, as it's dependent on the number of bits within consts. --- src/test/ui/symbol-names/impl1.legacy.stderr | 28 ++++++++++---------- src/test/ui/symbol-names/impl1.rs | 2 ++ src/test/ui/symbol-names/impl1.v0.stderr | 24 ++++++++--------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index 8e498e4b39477..33cacaf212855 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -1,71 +1,71 @@ error: symbol-name(_ZN5impl13foo3Foo3bar17h92cf46db76791039E) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(impl1::foo::Foo::bar::h92cf46db76791039) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::foo::Foo::bar) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:21:9 + --> $DIR/impl1.rs:23:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h90c4a800b1aa0df0E) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(impl1::bar::::baz::h90c4a800b1aa0df0) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::bar::::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:39:9 + --> $DIR/impl1.rs:41:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h62e540f14f879d56E) - --> $DIR/impl1.rs:62:13 +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17SYMBOL_HASHE) + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::h62e540f14f879d56) - --> $DIR/impl1.rs:62:13 +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::SYMBOL_HASH) + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:62:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) - --> $DIR/impl1.rs:69:13 + --> $DIR/impl1.rs:71:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index b054c1373e66c..8e53eac3e47c0 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,6 +3,8 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 +//[legacy]normalize-stderr-32-bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH" #![feature(optin_builtin_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 111c360b36080..b6a35d9746925 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -1,71 +1,71 @@ error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13fooNtB2_3Foo3bar) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::bar) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::bar) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:21:9 + --> $DIR/impl1.rs:23:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13barNtNtB4_3foo3Foo3baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:39:9 + --> $DIR/impl1.rs:41:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - --> $DIR/impl1.rs:62:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:62:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:62:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) - --> $DIR/impl1.rs:69:13 + --> $DIR/impl1.rs:71:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ From 06b9a73cfa5ef1cb6fb9160d61f1beada2b81b79 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Tue, 14 Jan 2020 20:02:27 +0800 Subject: [PATCH 0321/1253] Update APIs according to RFC change suggestions. --- src/liballoc/collections/linked_list.rs | 43 +++++++++---- src/liballoc/collections/linked_list/tests.rs | 60 ++++++++++++++++--- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d7504b0b80bd9..b88ca8a0fb0d1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -509,20 +509,42 @@ impl LinkedList { IterMut { head: self.head, tail: self.tail, len: self.len, list: self } } - /// Provides a cursor. + /// Provides a cursor at the front element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. #[inline] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor(&self) -> Cursor<'_, T> { + pub fn cursor_front(&self) -> Cursor<'_, T> { Cursor { index: 0, current: self.head, list: self } } - /// Provides a cursor with editing operations. + /// Provides a cursor with editing operations at the front element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. #[inline] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> { CursorMut { index: 0, current: self.head, list: self } } + /// Provides a cursor at the back element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_back(&self) -> Cursor<'_, T> { + Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + } + + /// Provides a cursor with editing operations at the back element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> { + CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + } + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. @@ -1146,8 +1168,6 @@ impl fmt::Debug for Cursor<'_, T> { /// Cursors always rest between two elements in the list, and index in a logically circular way. /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. -/// -/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct CursorMut<'a, T: 'a> { index: usize, @@ -1474,9 +1494,12 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_after(self) -> LinkedList { + pub fn split_after(&mut self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; - // no need to update `self.index` because the cursor is consumed. + if self.index == self.list.len { + // The "ghost" non-element's index has changed to 0. + self.index = 0; + } unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } @@ -1487,9 +1510,9 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_before(self) -> LinkedList { + pub fn split_before(&mut self) -> LinkedList { let split_off_idx = self.index; - // no need to update `self.index` because the cursor is consumed. + self.index = 0; unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index d223752c7f7ec..085f734ed916a 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -309,7 +309,7 @@ fn drain_to_empty_test() { fn test_cursor_move_peek() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor(); + let mut cursor = m.cursor_front(); assert_eq!(cursor.current(), Some(&1)); assert_eq!(cursor.peek_next(), Some(&2)); assert_eq!(cursor.peek_prev(), None); @@ -326,9 +326,26 @@ fn test_cursor_move_peek() { assert_eq!(cursor.peek_prev(), Some(&1)); assert_eq!(cursor.index(), Some(1)); + let mut cursor = m.cursor_back(); + assert_eq!(cursor.current(), Some(&6)); + assert_eq!(cursor.peek_next(), None); + assert_eq!(cursor.peek_prev(), Some(&5)); + assert_eq!(cursor.index(), Some(5)); + cursor.move_next(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&1)); + assert_eq!(cursor.peek_prev(), Some(&6)); + assert_eq!(cursor.index(), None); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.current(), Some(&5)); + assert_eq!(cursor.peek_next(), Some(&6)); + assert_eq!(cursor.peek_prev(), Some(&4)); + assert_eq!(cursor.index(), Some(4)); + let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); assert_eq!(cursor.current(), Some(&mut 1)); assert_eq!(cursor.peek_next(), Some(&mut 2)); assert_eq!(cursor.peek_prev(), None); @@ -352,24 +369,51 @@ fn test_cursor_move_peek() { assert_eq!(cursor2.index(), Some(2)); assert_eq!(cursor.current(), Some(&mut 2)); assert_eq!(cursor.index(), Some(1)); + + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_back_mut(); + assert_eq!(cursor.current(), Some(&mut 6)); + assert_eq!(cursor.peek_next(), None); + assert_eq!(cursor.peek_prev(), Some(&mut 5)); + assert_eq!(cursor.index(), Some(5)); + cursor.move_next(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&mut 1)); + assert_eq!(cursor.peek_prev(), Some(&mut 6)); + assert_eq!(cursor.index(), None); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.current(), Some(&mut 5)); + assert_eq!(cursor.peek_next(), Some(&mut 6)); + assert_eq!(cursor.peek_prev(), Some(&mut 4)); + assert_eq!(cursor.index(), Some(4)); + let mut cursor2 = cursor.as_cursor(); + assert_eq!(cursor2.current(), Some(&5)); + assert_eq!(cursor2.index(), Some(4)); + cursor2.move_prev(); + assert_eq!(cursor2.current(), Some(&4)); + assert_eq!(cursor2.index(), Some(3)); + assert_eq!(cursor.current(), Some(&mut 5)); + assert_eq!(cursor.index(), Some(4)); } #[test] fn test_cursor_mut_insert() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.insert_before(7); cursor.insert_after(8); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[7, 1, 8, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); cursor.insert_before(9); cursor.insert_after(10); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); assert_eq!(cursor.remove_current(), None); cursor.move_next(); @@ -383,7 +427,7 @@ fn test_cursor_mut_insert() { assert_eq!(cursor.remove_current(), Some(10)); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); let mut p: LinkedList = LinkedList::new(); p.extend(&[100, 101, 102, 103]); let mut q: LinkedList = LinkedList::new(); @@ -395,12 +439,12 @@ fn test_cursor_mut_insert() { m.iter().cloned().collect::>(), &[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6] ); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); let tmp = cursor.split_before(); assert_eq!(m.into_iter().collect::>(), &[]); m = tmp; - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_next(); cursor.move_next(); cursor.move_next(); From 5076a3efc707436c20c62f90e5df47e78052ed2d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 14 Jan 2020 14:04:03 +0100 Subject: [PATCH 0322/1253] Add failing example for E0170 explanation --- src/librustc_error_codes/error_codes/E0170.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/librustc_error_codes/error_codes/E0170.md b/src/librustc_error_codes/error_codes/E0170.md index 4b870dbf22155..56e1b5aa241d2 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/src/librustc_error_codes/error_codes/E0170.md @@ -1,3 +1,24 @@ +A pattern binding is using the same name as one of the variants a type. + +Erroneous code example: + +```compile_fail,E0170 +# #![deny(warnings)] +enum Method { + GET, + POST, +} + +fn is_empty(s: Method) -> bool { + match s { + GET => true, + _ => false + } +} + +fn main() {} +``` + Enum variants are qualified by default. For example, given this type: ``` From 148c1bca0f0eb8da23a50cd876cb86cb060a8375 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:21:14 +0800 Subject: [PATCH 0323/1253] record generoator interior exprs in typecktable --- src/librustc/traits/error_reporting.rs | 33 +++++++++++++++++++++----- src/librustc/ty/adjustment.rs | 9 +++++++ src/librustc/ty/context.rs | 5 ++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0c9a73d78a5eb..66737372bda37 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { + .zip(tables.generator_interior_exprs.iter()) + .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we // want to erase them when comparing (and anyway, @@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); eq }) - .map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| { - (span, source_map.span_to_snippet(*span), scope_span) + .map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| { + (span, source_map.span_to_snippet(*span), scope_span, expr) }); + debug!( "maybe_note_obligation_cause_for_async_await: target_ty={:?} \ generator_interior_types={:?} target_span={:?}", target_ty, tables.generator_interior_types, target_span ); - if let Some((target_span, Ok(snippet), scope_span)) = target_span { + if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span { self.note_obligation_cause_for_async_await( err, *target_span, scope_span, + *expr, snippet, generator_did, last_generator, @@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, target_span: Span, scope_span: &Option, + expr: Option, snippet: String, first_generator: DefId, last_generator: Option, @@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // not implemented. let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id); let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id); + let hir = self.tcx.hir(); let trait_explanation = if is_send || is_sync { let (trait_name, trait_verb) = if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") }; @@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let message = if let Some(name) = last_generator .and_then(|generator_did| self.tcx.parent(generator_did)) - .and_then(|parent_did| self.tcx.hir().as_local_hir_id(parent_did)) - .and_then(|parent_hir_id| self.tcx.hir().opt_name(parent_hir_id)) + .and_then(|parent_did| hir.as_local_hir_id(parent_did)) + .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) { format!("future returned by `{}` is not {}", name, trait_name) } else { @@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), ); + if let Some(expr_id) = expr { + let expr = hir.expect_expr(expr_id); + let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + let parent = hir.get_parent_node(expr_id); + if let Some(hir::Node::Expr(e)) = hir.find(parent) { + let method_span = hir.span(parent); + if tables.is_method_call(e) && is_ref { + err.span_help( + method_span, + "consider moving this method call into a `let` \ + binding to create a shorter lived borrow" + ); + } + } + } + span.push_span_label(target_span, format!("has type `{}`", target_ty)); // If available, use the scope span to annotate the drop location. diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index ebefb03b813f2..6531289bd7050 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -81,6 +81,15 @@ pub struct Adjustment<'tcx> { pub target: Ty<'tcx>, } +impl Adjustment<'tcx> { + pub fn is_region_borrow(&self) -> bool { + match self.kind { + Adjust::Borrow(AutoBorrow::Ref(..)) => true, + _ => false + } + } +} + #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] pub enum Adjust<'tcx> { /// Go from ! to any type. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6b98fddb22ef9..4a5fced7a89e5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -439,6 +439,8 @@ pub struct TypeckTables<'tcx> { /// Stores the type, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). pub generator_interior_types: Vec>, + + pub generator_interior_exprs: Vec>, } impl<'tcx> TypeckTables<'tcx> { @@ -465,6 +467,7 @@ impl<'tcx> TypeckTables<'tcx> { concrete_opaque_types: Default::default(), upvar_list: Default::default(), generator_interior_types: Default::default(), + generator_interior_exprs: Default::default(), } } @@ -728,6 +731,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { ref concrete_opaque_types, ref upvar_list, ref generator_interior_types, + ref generator_interior_exprs, } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -766,6 +770,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { concrete_opaque_types.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher); generator_interior_types.hash_stable(hcx, hasher); + generator_interior_exprs.hash_stable(hcx, hasher); }) } } From b97560116785f2dbb488e66ab34aeee981ec2912 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:22:19 +0800 Subject: [PATCH 0324/1253] suggest to limit lifetime of temporary borrow with let --- src/librustc/traits/error_reporting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 66737372bda37..13eb47a041fa6 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2578,7 +2578,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; span.push_span_label(original_span, message); - err.set_span(span); + err.set_span(span.clone()); format!("is not {}", trait_name) } else { From 6faad6dc7a0ad1524e3c490f4ea99c998ce9ae04 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 13 Jan 2020 17:58:37 +0100 Subject: [PATCH 0325/1253] Untangle ZST validation from integer validation and generalize it to all zsts --- src/librustc_mir/interpret/validity.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 2f0fb81fffd13..6934ec0bdb6aa 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -587,12 +587,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // padding. match tys.kind { ty::Int(..) | ty::Uint(..) | ty::Float(..) => true, - ty::Tuple(tys) if tys.len() == 0 => true, - ty::Adt(adt_def, _) - if adt_def.is_struct() && adt_def.all_fields().next().is_none() => - { - true - } _ => false, } } => @@ -609,11 +603,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } // This is the element type size. let layout = self.ecx.layout_of(tys)?; - // Empty tuples and fieldless structs (the only ZSTs that allow reaching this code) - // have no data to be checked. - if layout.is_zst() { - return Ok(()); - } // This is the size in bytes of the whole array. let size = layout.size * len; // Size is not 0, get a pointer. @@ -656,6 +645,13 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } } + // Fast path for arrays and slices of ZSTs. We only need to check a single ZST element + // of an array and not all of them, because there's only a single value of a specific + // ZST type, so either validation fails for all elements or none. + ty::Array(tys, ..) | ty::Slice(tys) if self.ecx.layout_of(tys)?.is_zst() => { + // Validate just the first element + self.walk_aggregate(op, fields.take(1))? + } _ => { self.walk_aggregate(op, fields)? // default handler } From 5ad8b9e3948fa05df0b9c2a6c71146c3af10cbc8 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:22:43 +0800 Subject: [PATCH 0326/1253] update async-await send/sync test --- src/librustc/traits/error_reporting.rs | 38 +++++++++---------- src/librustc/ty/adjustment.rs | 2 +- src/librustc/ty/context.rs | 9 +---- .../check/generator_interior.rs | 6 ++- .../issue-64130-4-async-move.stderr | 5 +++ 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 13eb47a041fa6..aaad0be9a048c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .zip(tables.generator_interior_exprs.iter()) .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we @@ -2578,7 +2577,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; span.push_span_label(original_span, message); - err.set_span(span.clone()); + err.set_span(span); format!("is not {}", trait_name) } else { @@ -2586,29 +2585,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; // Look at the last interior type to get a span for the `.await`. - let await_span = tables.generator_interior_types.iter().map(|i| i.span).last().unwrap(); + let await_span = + tables.generator_interior_types.iter().map(|(i, _)| i.span).last().unwrap(); let mut span = MultiSpan::from_span(await_span); span.push_span_label( await_span, format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), ); - if let Some(expr_id) = expr { - let expr = hir.expect_expr(expr_id); - let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); - let parent = hir.get_parent_node(expr_id); - if let Some(hir::Node::Expr(e)) = hir.find(parent) { - let method_span = hir.span(parent); - if tables.is_method_call(e) && is_ref { - err.span_help( - method_span, - "consider moving this method call into a `let` \ - binding to create a shorter lived borrow" - ); - } - } - } - span.push_span_label(target_span, format!("has type `{}`", target_ty)); // If available, use the scope span to annotate the drop location. @@ -2627,6 +2611,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ), ); + if let Some(expr_id) = expr { + let expr = hir.expect_expr(expr_id); + let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + let parent = hir.get_parent_node(expr_id); + if let Some(hir::Node::Expr(e)) = hir.find(parent) { + let method_span = hir.span(parent); + if tables.is_method_call(e) && is_ref { + err.span_help( + method_span, + "consider moving this method call into a `let` \ + binding to create a shorter lived borrow", + ); + } + } + } + // Add a note for the item obligation that remains - normally a note pointing to the // bound that introduced the obligation (e.g. `T: Send`). debug!("note_obligation_cause_for_async_await: next_code={:?}", next_code); diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 6531289bd7050..db034d1618cea 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -85,7 +85,7 @@ impl Adjustment<'tcx> { pub fn is_region_borrow(&self) -> bool { match self.kind { Adjust::Borrow(AutoBorrow::Ref(..)) => true, - _ => false + _ => false, } } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4a5fced7a89e5..d64e049c47b54 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -436,11 +436,9 @@ pub struct TypeckTables<'tcx> { /// entire variable. pub upvar_list: ty::UpvarListMap, - /// Stores the type, span and optional scope span of all types + /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec>, - - pub generator_interior_exprs: Vec>, + pub generator_interior_types: Vec<(GeneratorInteriorTypeCause<'tcx>, Option)>, } impl<'tcx> TypeckTables<'tcx> { @@ -467,7 +465,6 @@ impl<'tcx> TypeckTables<'tcx> { concrete_opaque_types: Default::default(), upvar_list: Default::default(), generator_interior_types: Default::default(), - generator_interior_exprs: Default::default(), } } @@ -731,7 +728,6 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { ref concrete_opaque_types, ref upvar_list, ref generator_interior_types, - ref generator_interior_exprs, } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -770,7 +766,6 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { concrete_opaque_types.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher); generator_interior_types.hash_stable(hcx, hasher); - generator_interior_exprs.hash_stable(hcx, hasher); }) } } diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 9d8805f225d7e..7185de76fcbb6 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -18,6 +18,7 @@ use rustc_span::Span; struct InteriorVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, types: FxHashMap, usize>, + exprs: Vec>, region_scope_tree: &'tcx region::ScopeTree, expr_count: usize, kind: hir::GeneratorKind, @@ -99,6 +100,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { scope_span, }) .or_insert(entries); + self.exprs.push(expr.map(|e| e.hir_id)); } } else { debug!( @@ -136,6 +138,7 @@ pub fn resolve_interior<'a, 'tcx>( expr_count: 0, kind, prev_unresolved_span: None, + exprs: vec![], }; intravisit::walk_body(&mut visitor, body); @@ -170,7 +173,8 @@ pub fn resolve_interior<'a, 'tcx>( }); // Store the generator types and spans into the tables for this generator. - let interior_types = types.iter().map(|t| t.0.clone()).collect::>(); + let interior_types = + types.iter().zip(visitor.exprs).map(|(t, e)| (t.0.clone(), e)).collect::>(); visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types; // Extract type components diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index ddbb469b99c24..77d0885c38d58 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -16,6 +16,11 @@ LL | let _x = get().await; ... LL | } | - `client` is later dropped here +help: consider moving this method call into a `let` binding to create a shorter lived borrow + --> $DIR/issue-64130-4-async-move.rs:19:15 + | +LL | match client.status() { + | ^^^^^^^^^^^^^^^ = note: the return type of a function must have a statically known size error: aborting due to previous error From 9864ec499ffe5621c1da47150adcfaf606ec76a4 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sun, 24 Nov 2019 20:44:19 +0000 Subject: [PATCH 0327/1253] Implement `finish_non_exhaustive` for `DebugStruct`. --- src/libcore/fmt/builders.rs | 56 +++++++++++++++++++++ src/libcore/tests/fmt/builders.rs | 83 +++++++++++++++++++++++++++++++ src/libcore/tests/lib.rs | 1 + 3 files changed, 140 insertions(+) diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index 626eb1e862d99..dd0f3ccb15841 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -159,6 +159,62 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { self } + /// Marks the struct as non-exhaustive, indicating to the reader that there are some other + /// fields that are not shown in the debug representation. + /// + /// # Examples + /// + /// ``` + /// # #![feature(debug_non_exhaustive)] + /// use std::fmt; + /// + /// struct Bar { + /// bar: i32, + /// hidden: f32, + /// } + /// + /// impl fmt::Debug for Bar { + /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + /// fmt.debug_struct("Bar") + /// .field("bar", &self.bar) + /// .finish_non_exhaustive() // Show that some other field(s) exist. + /// } + /// } + /// + /// assert_eq!( + /// format!("{:?}", Bar { bar: 10, hidden: 1.0 }), + /// "Bar { bar: 10, .. }", + /// ); + /// ``` + #[unstable(feature = "debug_non_exhaustive", issue = "67364")] + pub fn finish_non_exhaustive(&mut self) -> fmt::Result { + self.result = self.result.and_then(|_| { + // Draw non-exhaustive dots (`..`), and open brace if necessary (no fields). + if self.is_pretty() { + if !self.has_fields { + self.fmt.write_str(" {\n")?; + } + let mut slot = None; + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); + writer.write_str("..\n")?; + } else { + if self.has_fields { + self.fmt.write_str(", ..")?; + } else { + self.fmt.write_str(" { ..")?; + } + } + if self.is_pretty() { + self.fmt.write_str("}")? + } else { + self.fmt.write_str(" }")?; + } + Ok(()) + }); + self.result + } + /// Finishes output and returns any error encountered. /// /// # Examples diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index 90a9bccda1580..d8ec6764bc620 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -93,6 +93,89 @@ mod debug_struct { format!("{:#?}", Bar) ); } + + #[test] + fn test_only_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .finish_non_exhaustive() + } + } + + + assert_eq!("Foo { .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_multiple_and_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + bar: true, + baz: 10/20, + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_nested_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + struct Bar; + + impl fmt::Debug for Bar { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Bar") + .field("foo", &Foo) + .field("hello", &"world") + .finish_non_exhaustive() + } + } + + assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", + format!("{:?}", Bar)); + assert_eq!( +"Bar { + foo: Foo { + bar: true, + baz: 10/20, + .. + }, + hello: \"world\", + .. +}", + format!("{:#?}", Bar)); + } + } mod debug_tuple { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 86cf6fc104c83..8c034938c2bb9 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -5,6 +5,7 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(debug_map_key_value)] +#![feature(debug_non_exhaustive)] #![feature(dec2flt)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] From 6da85d6f998f06bde43508e7b43690c9e47c0614 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 14 Jan 2020 09:47:04 -0800 Subject: [PATCH 0328/1253] Update cargo, rls --- Cargo.lock | 32 ++++++++++++++++++----- src/tools/cargo | 2 +- src/tools/rls | 2 +- src/tools/rustc-workspace-hack/Cargo.toml | 2 +- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..2eb2c0aa1c7db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,6 +57,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "anyhow" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" + [[package]] name = "arc-swap" version = "0.3.7" @@ -277,6 +283,7 @@ dependencies = [ name = "cargo" version = "0.43.0" dependencies = [ + "anyhow", "atty", "bytesize", "cargo-platform", @@ -290,7 +297,6 @@ dependencies = [ "curl", "curl-sys", "env_logger 0.7.1", - "failure", "filetime", "flate2", "fs2", @@ -318,7 +324,7 @@ dependencies = [ "pretty_env_logger", "remove_dir_all", "rustc-workspace-hack", - "rustfix", + "rustfix 0.5.0", "same-file", "semver", "serde", @@ -590,7 +596,7 @@ dependencies = [ "log", "miow 0.3.3", "regex", - "rustfix", + "rustfix 0.4.6", "serde", "serde_json", "walkdir", @@ -610,7 +616,7 @@ dependencies = [ "log", "miow 0.3.3", "regex", - "rustfix", + "rustfix 0.4.6", "serde", "serde_derive", "serde_json", @@ -694,10 +700,10 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "crates-io" -version = "0.30.0" +version = "0.31.0" dependencies = [ + "anyhow", "curl", - "failure", "percent-encoding 2.1.0", "serde", "serde_derive", @@ -2936,13 +2942,13 @@ dependencies = [ name = "rls" version = "1.41.0" dependencies = [ + "anyhow", "cargo", "cargo_metadata 0.8.0", "clippy_lints", "crossbeam-channel", "difference", "env_logger 0.7.1", - "failure", "futures", "heck", "home", @@ -4005,6 +4011,18 @@ dependencies = [ "serde_json", ] +[[package]] +name = "rustfix" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804b11883a5ce0ad0378fbf95a8dea59ee6b51c331a73b8f471b6bdaa3bd40c1" +dependencies = [ + "anyhow", + "log", + "serde", + "serde_json", +] + [[package]] name = "rustfmt-config_proc_macro" version = "0.2.0" diff --git a/src/tools/cargo b/src/tools/cargo index 6e1ca924a67dd..ad3dbe10e1e65 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 6e1ca924a67dd1ac89c33f294ef26b5c43b89168 +Subproject commit ad3dbe10e1e654fb1f032a5dd9481d7cbaa00d65 diff --git a/src/tools/rls b/src/tools/rls index 7c0489c5ff4f5..b27e117396963 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 7c0489c5ff4f5c594e65a3b22efd9ce373deab9b +Subproject commit b27e1173969639448cd2e486b1c5f0fcb1b3b17c diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index fced6c52012ab..936e8ae895a74 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -65,7 +65,7 @@ serde_json = { version = "1.0.31", features = ["raw_value"] } smallvec-0_6 = { package = "smallvec", version = "0.6", features = ['union', 'may_dangle'] } smallvec = { version = "1.0", features = ['union', 'may_dangle'] } url = { version = "2.0", features = ['serde'] } -syn = { version = "0.15", features = ['full'] } +syn = { version = "0.15", features = ['full', 'extra-traits'] } [target.'cfg(not(windows))'.dependencies] openssl = { version = "0.10.12", optional = true } From 55cb505257f3dd86fbae051fe90dc34efa7d0151 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 14 Jan 2020 09:50:55 -0800 Subject: [PATCH 0329/1253] Update rustfix in compiletest. --- Cargo.lock | 2 +- src/tools/compiletest/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2eb2c0aa1c7db..a1adc820d2e42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,7 +596,7 @@ dependencies = [ "log", "miow 0.3.3", "regex", - "rustfix 0.4.6", + "rustfix 0.5.0", "serde", "serde_json", "walkdir", diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 80ef8dd662637..a26c3a4acabfa 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -12,7 +12,7 @@ log = "0.4" regex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -rustfix = "0.4.1" +rustfix = "0.5.0" lazy_static = "1.0" walkdir = "2" From 583a4fc827d1f4f491286218549a6048c0a9c9bf Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Wed, 15 Jan 2020 06:59:26 +1300 Subject: [PATCH 0330/1253] Fix normalizing 32bit symbol hash. --- src/test/ui/symbol-names/impl1.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 8e53eac3e47c0..1f689a5bd2541 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,7 +3,7 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 -//[legacy]normalize-stderr-32-bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" //[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH" #![feature(optin_builtin_traits, rustc_attrs)] From 87504173b3bb948ca0292055fbeb833fc5a41400 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 14 Jan 2020 09:59:46 -0800 Subject: [PATCH 0331/1253] Update the wasi-libc bundled with libstd --- src/ci/docker/dist-various-2/build-wasi-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index 925d5ca0223b1..b868677564298 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -12,7 +12,7 @@ export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH git clone https://github.com/CraneStation/wasi-libc cd wasi-libc -git reset --hard f645f498dfbbbc00a7a97874d33082d3605c3f21 +git reset --hard 1fad33890a5e299027ce0eab7b6ad5260585e347 make -j$(nproc) INSTALL_DIR=/wasm32-wasi install cd .. From 1bf9f69579e525a35fd712b7f00f2f24eebc6387 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 14 Jan 2020 19:21:10 +0100 Subject: [PATCH 0332/1253] Prevent urls in headings --- src/librustdoc/html/markdown.rs | 8 ++++++-- src/test/rustdoc/remove-url-from-headings.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/remove-url-from-headings.rs diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c5f88f9f7f421..b2f5c8e81ff7e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -380,7 +380,11 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, } _ => {} } - self.buf.push_back(event); + match event { + Event::Start(Tag::Link(_, _, text)) => self.buf.push_back(Event::Text(text)), + Event::End(Tag::Link(..)) => {} + event => self.buf.push_back(event), + } } let id = self.id_map.derive(id); @@ -395,7 +399,7 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, let start_tags = format!( "\ - ", + ", id = id, level = level ); diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs new file mode 100644 index 0000000000000..7fbcdbafa7486 --- /dev/null +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -0,0 +1,12 @@ +#![crate_name = "foo"] + +// @has foo/fn.foo.html +// !@has - '//a[@href="http://a.a"]' +// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere' + +/// fooo +/// +/// # Implementing [stuff](http://a.a) somewhere +/// +/// hello +pub fn foo() {} From 9f1452f6996935f796daadab05a956fd0ae69196 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:26:03 -0800 Subject: [PATCH 0333/1253] Update libssh2-sys to a version that can build for aarch64-pc-windows-msvc --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..202c297b82de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1806,9 +1806,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d" +checksum = "36aa6e813339d3a063292b77091dfbbb6152ff9006a459895fa5bebed7d34f10" dependencies = [ "cc", "libc", From 535fc9ce4c97598f7cc1a093c9cd506a81e22689 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:52:46 -0800 Subject: [PATCH 0334/1253] Update iovec to a version with no winapi dependency --- Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..9eedab0a1d093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1581,12 +1581,11 @@ dependencies = [ [[package]] name = "iovec" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ "libc", - "winapi 0.2.8", ] [[package]] From 9febc2bc7a3a6397ca7e30155924d2d180a5e940 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:56:51 -0800 Subject: [PATCH 0335/1253] Update to a version of cmake with windows arm64 support --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..602e0ae150a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -514,9 +514,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.38" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96210eec534fc3fbfc0452a63769424eaa80205fda6cea98e5b61cb3d97bcec8" +checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" dependencies = [ "cc", ] From 7d6271b76b7ee7a192e03933ed6b37e6e6385c08 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Fri, 10 Jan 2020 09:11:32 -0800 Subject: [PATCH 0336/1253] Better support for cross compilation on Windows. --- src/bootstrap/native.rs | 2 ++ src/librustc_llvm/build.rs | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index ce977f1bbc44e..89e1a7319cf59 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -230,6 +230,8 @@ impl Step for Llvm { cfg.define("CMAKE_SYSTEM_NAME", "NetBSD"); } else if target.contains("freebsd") { cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD"); + } else if target.contains("windows") { + cfg.define("CMAKE_SYSTEM_NAME", "Windows"); } cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build")); diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index dff20f8741065..405ce0307cd82 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -215,12 +215,14 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg(llvm_link_arg).arg("--ldflags"); for lib in output(&mut cmd).split_whitespace() { - if lib.starts_with("-LIBPATH:") { - println!("cargo:rustc-link-search=native={}", &lib[9..]); - } else if is_crossed { - if lib.starts_with("-L") { + if is_crossed { + if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", lib[9..].replace(&host, &target)); + } else if lib.starts_with("-L") { println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target)); } + } else if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", &lib[9..]); } else if lib.starts_with("-l") { println!("cargo:rustc-link-lib={}", &lib[2..]); } else if lib.starts_with("-L") { From 2fb4c4472e4563a52e2dc544e47a01f564b9219e Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 11 Nov 2019 11:48:47 -0800 Subject: [PATCH 0337/1253] Improve graphviz visualization for new framework --- src/librustc_mir/dataflow/generic/graphviz.rs | 518 ++++++++++++++---- src/librustc_span/symbol.rs | 3 + 2 files changed, 405 insertions(+), 116 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/graphviz.rs b/src/librustc_mir/dataflow/generic/graphviz.rs index e843956a7a78b..fdf86e7b53f60 100644 --- a/src/librustc_mir/dataflow/generic/graphviz.rs +++ b/src/librustc_mir/dataflow/generic/graphviz.rs @@ -1,13 +1,14 @@ +//! A helpful diagram for debugging dataflow problems. + use std::cell::RefCell; -use std::io::{self, Write}; -use std::{ops, str}; +use std::{io, ops, str}; use rustc::mir::{self, BasicBlock, Body, Location}; use rustc_hir::def_id::DefId; use rustc_index::bit_set::{BitSet, HybridBitSet}; -use rustc_index::vec::Idx; +use rustc_index::vec::{Idx, IndexVec}; -use super::{Analysis, Results, ResultsRefCursor}; +use super::{Analysis, GenKillSet, Results, ResultsRefCursor}; use crate::util::graphviz_safe_def_name; pub struct Formatter<'a, 'tcx, A> @@ -25,11 +26,16 @@ impl Formatter<'a, 'tcx, A> where A: Analysis<'tcx>, { - pub fn new(body: &'a Body<'tcx>, def_id: DefId, results: &'a Results<'tcx, A>) -> Self { + pub fn new( + body: &'a Body<'tcx>, + def_id: DefId, + results: &'a Results<'tcx, A>, + state_formatter: &'a mut dyn StateFormatter<'tcx, A>, + ) -> Self { let block_formatter = BlockFormatter { bg: Background::Light, - prev_state: BitSet::new_empty(results.analysis.bits_per_block(body)), results: ResultsRefCursor::new(body, results), + state_formatter, }; Formatter { body, def_id, block_formatter: RefCell::new(block_formatter) } @@ -117,15 +123,21 @@ struct BlockFormatter<'a, 'tcx, A> where A: Analysis<'tcx>, { - prev_state: BitSet, results: ResultsRefCursor<'a, 'a, 'tcx, A>, bg: Background, + state_formatter: &'a mut dyn StateFormatter<'tcx, A>, } impl BlockFormatter<'a, 'tcx, A> where A: Analysis<'tcx>, { + const HEADER_COLOR: &'static str = "#a0a0a0"; + + fn num_state_columns(&self) -> usize { + std::cmp::max(1, self.state_formatter.column_names().len()) + } + fn toggle_background(&mut self) -> Background { let bg = self.bg; self.bg = !bg; @@ -164,196 +176,470 @@ where r#""#, )?; - // A: Block info - write!( - w, - r#" - - "#, - num_headers = 3, - block_id = block.index(), - )?; - - // B: Column headings - write!( - w, - r#" - - - "#, - fmt = r##"bgcolor="#a0a0a0" sides="tl""##, - )?; + // A + B: Block header + if self.state_formatter.column_names().is_empty() { + self.write_block_header_simple(w, block)?; + } else { + self.write_block_header_with_state_columns(w, block)?; + } // C: Entry state self.bg = Background::Light; self.results.seek_to_block_start(block); - self.write_row_with_curr_state(w, "", "(on entry)")?; - self.prev_state.overwrite(self.results.get()); + self.write_row_with_full_state(w, "", "(on_entry)")?; // D: Statement transfer functions for (i, statement) in body[block].statements.iter().enumerate() { let location = Location { block, statement_index: i }; - - let mir_col = format!("{:?}", statement); - let i_col = i.to_string(); - - self.results.seek_after(location); - self.write_row_with_curr_diff(w, &i_col, &mir_col)?; - self.prev_state.overwrite(self.results.get()); + let statement_str = format!("{:?}", statement); + self.write_row_for_location(w, &i.to_string(), &statement_str, location)?; } // E: Terminator transfer function let terminator = body[block].terminator(); - let location = body.terminator_loc(block); + let terminator_loc = body.terminator_loc(block); + let mut terminator_str = String::new(); + terminator.kind.fmt_head(&mut terminator_str).unwrap(); - let mut mir_col = String::new(); - terminator.kind.fmt_head(&mut mir_col).unwrap(); - - self.results.seek_after(location); - self.write_row_with_curr_diff(w, "T", &mir_col)?; - self.prev_state.overwrite(self.results.get()); + self.write_row_for_location(w, "T", &terminator_str, terminator_loc)?; // F: Exit state + self.results.seek_after(terminator_loc); if let mir::TerminatorKind::Call { destination: Some(_), .. } = &terminator.kind { - self.write_row_with_curr_state(w, "", "(on unwind)")?; - - self.results.seek_after_assume_call_returns(location); - self.write_row_with_curr_diff(w, "", "(on successful return)")?; + self.write_row_with_full_state(w, "", "(on unwind)")?; + + let num_state_columns = self.num_state_columns(); + self.write_row(w, "", "(on successful return)", |this, w, fmt| { + write!( + w, + r#"") + })?; } else { - self.write_row_with_curr_state(w, "", "(on exit)")?; + self.write_row_with_full_state(w, "", "(on exit)")?; } write!(w, "
bb{block_id}
MIRSTATE
"#, + colspan = num_state_columns, + fmt = fmt, + )?; + + let state_on_unwind = this.results.get().clone(); + this.results.seek_after_assume_call_returns(terminator_loc); + write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?; + + write!(w, "
") } - fn write_row_with_curr_state( + fn write_block_header_simple( &mut self, w: &mut impl io::Write, - i: &str, - mir: &str, + block: BasicBlock, ) -> io::Result<()> { - let bg = self.toggle_background(); + // +-------------------------------------------------+ + // A | bb4 | + // +-----------------------------------+-------------+ + // B | MIR | STATE | + // +-+---------------------------------+-------------+ + // | | ... | | - let mut out = Vec::new(); - write!(&mut out, "{{")?; - pretty_print_state_elems(&mut out, self.results.analysis(), self.results.get().iter())?; - write!(&mut out, "}}")?; + // A + write!( + w, + concat!("", r#"bb{block_id}"#, "",), + block_id = block.index(), + )?; + // B write!( w, - r#" - {i} - {mir} - {state} - "#, - fmt = &["sides=\"tl\"", bg.attr()].join(" "), - i = i, - mir = dot::escape_html(mir), - state = dot::escape_html(str::from_utf8(&out).unwrap()), + concat!( + "", + r#"MIR"#, + r#"STATE"#, + "", + ), + fmt = format!("bgcolor=\"{}\" sides=\"tl\"", Self::HEADER_COLOR), ) } - fn write_row_with_curr_diff( + fn write_block_header_with_state_columns( &mut self, w: &mut impl io::Write, - i: &str, - mir: &str, + block: BasicBlock, ) -> io::Result<()> { - let bg = self.toggle_background(); - let analysis = self.results.analysis(); + // +------------------------------------+-------------+ + // A | bb4 | STATE | + // +------------------------------------+------+------+ + // B | MIR | GEN | KILL | + // +-+----------------------------------+------+------+ + // | | ... | | | - let diff = BitSetDiff::compute(&self.prev_state, self.results.get()); + let state_column_names = self.state_formatter.column_names(); - let mut set = Vec::new(); - pretty_print_state_elems(&mut set, analysis, diff.set.iter())?; + // A + write!( + w, + concat!( + "", + r#"bb{block_id}"#, + r#"STATE"#, + "", + ), + fmt = "sides=\"tl\"", + num_state_cols = state_column_names.len(), + block_id = block.index(), + )?; + + // B + let fmt = format!("bgcolor=\"{}\" sides=\"tl\"", Self::HEADER_COLOR); + write!(w, concat!("", r#"MIR"#,), fmt = fmt,)?; - let mut clear = Vec::new(); - pretty_print_state_elems(&mut clear, analysis, diff.clear.iter())?; + for name in state_column_names { + write!(w, "{name}", fmt = fmt, name = name)?; + } + + write!(w, "") + } + + /// Write a row with the given index and MIR, using the function argument to fill in the + /// "STATE" column(s). + fn write_row( + &mut self, + w: &mut W, + i: &str, + mir: &str, + f: impl FnOnce(&mut Self, &mut W, &str) -> io::Result<()>, + ) -> io::Result<()> { + let bg = self.toggle_background(); + let fmt = format!("sides=\"tl\" {}", bg.attr()); write!( w, - r#" - {i} - {mir} - "#, + concat!( + "", + r#"{i}"#, + r#"{mir}"#, + ), i = i, - fmt = &["sides=\"tl\"", bg.attr()].join(" "), + fmt = fmt, mir = dot::escape_html(mir), )?; - if !set.is_empty() { + f(self, w, &fmt)?; + write!(w, "") + } + + fn write_row_with_full_state( + &mut self, + w: &mut impl io::Write, + i: &str, + mir: &str, + ) -> io::Result<()> { + self.write_row(w, i, mir, |this, w, fmt| { + let state = this.results.get(); + let analysis = this.results.analysis(); + write!( w, - r#"+{}"#, - dot::escape_html(str::from_utf8(&set).unwrap()), + r#"{{"#, + colspan = this.num_state_columns(), + fmt = fmt, )?; + pretty_print_state_elems(w, analysis, state.iter(), ",", LIMIT_40_ALIGN_1)?; + write!(w, "}}") + }) + } + + fn write_row_for_location( + &mut self, + w: &mut impl io::Write, + i: &str, + mir: &str, + location: Location, + ) -> io::Result<()> { + self.write_row(w, i, mir, |this, w, fmt| { + this.state_formatter.write_state_for_location(w, fmt, &mut this.results, location) + }) + } +} + +/// Controls what gets printed under the `STATE` header. +pub trait StateFormatter<'tcx, A> +where + A: Analysis<'tcx>, +{ + /// The columns that will get printed under `STATE`. + fn column_names(&self) -> &[&str]; + + fn write_state_for_location( + &mut self, + w: &mut dyn io::Write, + fmt: &str, + results: &mut ResultsRefCursor<'_, '_, 'tcx, A>, + location: Location, + ) -> io::Result<()>; +} + +/// Prints a single column containing the state vector immediately *after* each statement. +pub struct SimpleDiff { + prev_state: BitSet, + prev_loc: Location, +} + +impl SimpleDiff { + #![allow(unused)] + pub fn new(bits_per_block: usize) -> Self { + SimpleDiff { prev_state: BitSet::new_empty(bits_per_block), prev_loc: Location::START } + } +} + +impl
StateFormatter<'tcx, A> for SimpleDiff +where + A: Analysis<'tcx>, +{ + fn column_names(&self) -> &[&str] { + &[] + } + + fn write_state_for_location( + &mut self, + mut w: &mut dyn io::Write, + fmt: &str, + results: &mut ResultsRefCursor<'_, '_, 'tcx, A>, + location: Location, + ) -> io::Result<()> { + if location.statement_index == 0 { + results.seek_to_block_start(location.block); + self.prev_state.overwrite(results.get()); + } else { + // Ensure that we are visiting statements in order, so `prev_state` is correct. + assert_eq!(self.prev_loc.successor_within_block(), location); + } + + self.prev_loc = location; + write!(w, r#""#, fmt = fmt)?; + results.seek_before(location); + let curr_state = results.get(); + write_diff(&mut w, results.analysis(), &self.prev_state, curr_state)?; + self.prev_state.overwrite(curr_state); + write!(w, "") + } +} + +/// Prints two state columns, one containing only the "before" effect of each statement and one +/// containing the full effect. +pub struct TwoPhaseDiff { + prev_state: BitSet, + prev_loc: Location, +} + +impl TwoPhaseDiff { + #![allow(unused)] + pub fn new(bits_per_block: usize) -> Self { + TwoPhaseDiff { prev_state: BitSet::new_empty(bits_per_block), prev_loc: Location::START } + } +} + +impl StateFormatter<'tcx, A> for TwoPhaseDiff +where + A: Analysis<'tcx>, +{ + fn column_names(&self) -> &[&str] { + &["ENTRY", " EXIT"] + } + + fn write_state_for_location( + &mut self, + mut w: &mut dyn io::Write, + fmt: &str, + results: &mut ResultsRefCursor<'_, '_, 'tcx, A>, + location: Location, + ) -> io::Result<()> { + if location.statement_index == 0 { + results.seek_to_block_start(location.block); + self.prev_state.overwrite(results.get()); + } else { + // Ensure that we are visiting statements in order, so `prev_state` is correct. + assert_eq!(self.prev_loc.successor_within_block(), location); } - if !set.is_empty() && !clear.is_empty() { - write!(w, " ")?; + self.prev_loc = location; + + // Entry + + write!(w, r#""#, fmt = fmt)?; + results.seek_before(location); + let curr_state = results.get(); + write_diff(&mut w, results.analysis(), &self.prev_state, curr_state)?; + self.prev_state.overwrite(curr_state); + write!(w, "")?; + + // Exit + + write!(w, r#""#, fmt = fmt)?; + results.seek_after(location); + let curr_state = results.get(); + write_diff(&mut w, results.analysis(), &self.prev_state, curr_state)?; + self.prev_state.overwrite(curr_state); + write!(w, "") + } +} + +/// Prints the gen/kill set for the entire block. +pub struct BlockTransferFunc<'a, 'tcx, T: Idx> { + body: &'a mir::Body<'tcx>, + trans_for_block: IndexVec>, +} + +impl BlockTransferFunc<'mir, 'tcx, T> { + #![allow(unused)] + pub fn new( + body: &'mir mir::Body<'tcx>, + trans_for_block: IndexVec>, + ) -> Self { + BlockTransferFunc { body, trans_for_block } + } +} + +impl StateFormatter<'tcx, A> for BlockTransferFunc<'mir, 'tcx, A::Idx> +where + A: Analysis<'tcx>, +{ + fn column_names(&self) -> &[&str] { + &["GEN", "KILL"] + } + + fn write_state_for_location( + &mut self, + mut w: &mut dyn io::Write, + fmt: &str, + results: &mut ResultsRefCursor<'_, '_, 'tcx, A>, + location: Location, + ) -> io::Result<()> { + // Only print a single row. + if location.statement_index != 0 { + return Ok(()); } - if !clear.is_empty() { + let block_trans = &self.trans_for_block[location.block]; + let rowspan = self.body.basic_blocks()[location.block].statements.len(); + + for set in &[&block_trans.gen, &block_trans.kill] { write!( w, - r#"-{}"#, - dot::escape_html(str::from_utf8(&clear).unwrap()), + r#""#, + fmt = fmt, + rowspan = rowspan )?; + + pretty_print_state_elems(&mut w, results.analysis(), set.iter(), "\n", None)?; + write!(w, "")?; } - write!(w, "") + Ok(()) } } -/// The operations required to transform one `BitSet` into another. -struct BitSetDiff { - set: HybridBitSet, - clear: HybridBitSet, -} +/// Writes two lines, one containing the added bits and one the removed bits. +fn write_diff>( + w: &mut impl io::Write, + analysis: &A, + from: &BitSet, + to: &BitSet, +) -> io::Result<()> { + assert_eq!(from.domain_size(), to.domain_size()); + let len = from.domain_size(); + + let mut set = HybridBitSet::new_empty(len); + let mut clear = HybridBitSet::new_empty(len); + + // FIXME: Implement a lazy iterator over the symmetric difference of two bitsets. + for i in (0..len).map(|i| A::Idx::new(i)) { + match (from.contains(i), to.contains(i)) { + (false, true) => set.insert(i), + (true, false) => clear.insert(i), + _ => continue, + }; + } -impl BitSetDiff { - fn compute(from: &BitSet, to: &BitSet) -> Self { - assert_eq!(from.domain_size(), to.domain_size()); - let len = from.domain_size(); - - let mut set = HybridBitSet::new_empty(len); - let mut clear = HybridBitSet::new_empty(len); - - // FIXME: This could be made faster if `BitSet::xor` were implemented. - for i in (0..len).map(|i| T::new(i)) { - match (from.contains(i), to.contains(i)) { - (false, true) => set.insert(i), - (true, false) => clear.insert(i), - _ => continue, - }; - } + if !set.is_empty() { + write!(w, r#"+"#)?; + pretty_print_state_elems(w, analysis, set.iter(), ",", LIMIT_40_ALIGN_1)?; + write!(w, r#""#)?; + } - BitSetDiff { set, clear } + if !set.is_empty() && !clear.is_empty() { + write!(w, "
")?; } + + if !clear.is_empty() { + write!(w, r#"-"#)?; + pretty_print_state_elems(w, analysis, clear.iter(), ",", LIMIT_40_ALIGN_1)?; + write!(w, r#""#)?; + } + + Ok(()) } -/// Formats each `elem` using the pretty printer provided by `analysis` into a comma-separated -/// list. +/// Line break policy that breaks at 40 characters and starts the next line with a single space. +const LIMIT_40_ALIGN_1: Option = Some(LineBreak { sequence: "
", limit: 40 }); + +struct LineBreak { + sequence: &'static str, + limit: usize, +} + +/// Formats each `elem` using the pretty printer provided by `analysis` into a list with the given +/// separator (`sep`). +/// +/// Optionally, it will break lines using the given character sequence (usually `
`) and +/// character limit. fn pretty_print_state_elems
( w: &mut impl io::Write, analysis: &A, elems: impl Iterator, -) -> io::Result<()> + sep: &str, + line_break: Option, +) -> io::Result where A: Analysis<'tcx>, { + let sep_width = sep.chars().count(); + + let mut buf = Vec::new(); + let mut first = true; + let mut curr_line_width = 0; + let mut line_break_inserted = false; + for idx in elems { if first { first = false; } else { - write!(w, ",")?; + write!(w, "{}", sep)?; + curr_line_width += sep_width; + } + + buf.clear(); + analysis.pretty_print_idx(&mut buf, idx)?; + let idx_str = + str::from_utf8(&buf).expect("Output of `pretty_print_idx` must be valid UTF-8"); + let escaped = dot::escape_html(idx_str); + let escaped_width = escaped.chars().count(); + + if let Some(line_break) = &line_break { + if curr_line_width + sep_width + escaped_width > line_break.limit { + write!(w, "{}", line_break.sequence)?; + line_break_inserted = true; + curr_line_width = 0; + } } - analysis.pretty_print_idx(w, idx)?; + write!(w, "{}", escaped)?; + curr_line_width += escaped_width; } - Ok(()) + Ok(line_break_inserted) } /// The background color used for zebra-striping the table. diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index a8b2db300a478..138388d8719de 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -167,6 +167,7 @@ symbols! { bindings_after_at, block, bool, + borrowck_graphviz_format, borrowck_graphviz_postflow, borrowck_graphviz_preflow, box_patterns, @@ -337,6 +338,7 @@ symbols! { FxHashSet, FxHashMap, gen_future, + gen_kill, generators, generic_associated_types, generic_param_attrs, @@ -735,6 +737,7 @@ symbols! { try_trait, tt, tuple_indexing, + two_phase, Ty, ty, type_alias_impl_trait, From 106fe0b13a60c678c7a3372b8ef3f6160549ad5c Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 13:32:26 -0800 Subject: [PATCH 0338/1253] Update to a version of compiler_builtins with changes for fixes remainder for aarch64 windows --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..08b22e629d221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f083abf9bb9005a27d2da62706f661245278cb7096da37ab27410eaf60f2c1" +checksum = "b9975aefa63997ef75ca9cf013ff1bb81487aaa0b622c21053afd3b92979a7af" dependencies = [ "cc", "rustc-std-workspace-core", From 01dc44bfe00e374cf769cee5757d0ac97faa15a2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 14 Jan 2020 14:26:35 -0500 Subject: [PATCH 0339/1253] Avoid calling tcx.hir().get() on CRATE_HIR_ID This was causing an ICE when enabling trace logging for an unrelated module, since the arguments to `trace!` ended up getting evaluated --- src/librustc/infer/opaque_types/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index a1afb1a86be44..ee214bea7b8fc 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1219,7 +1219,7 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir let res = hir_id == scope; trace!( "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}", - tcx.hir().get(hir_id), + tcx.hir().find(hir_id), tcx.hir().get(opaque_hir_id), res ); From 07c51f605a021f1416a23e0cd76afa2156d5526c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 11 Nov 2019 11:48:17 -0800 Subject: [PATCH 0340/1253] Implement new dataflow framework and cursor --- src/librustc_mir/dataflow/generic/cursor.rs | 265 ++++++++++++ src/librustc_mir/dataflow/generic/engine.rs | 421 ++++++++++++++++++++ src/librustc_mir/dataflow/generic/mod.rs | 309 ++++++++++++++ 3 files changed, 995 insertions(+) create mode 100644 src/librustc_mir/dataflow/generic/cursor.rs create mode 100644 src/librustc_mir/dataflow/generic/engine.rs create mode 100644 src/librustc_mir/dataflow/generic/mod.rs diff --git a/src/librustc_mir/dataflow/generic/cursor.rs b/src/librustc_mir/dataflow/generic/cursor.rs new file mode 100644 index 0000000000000..f819b0fb5d69a --- /dev/null +++ b/src/librustc_mir/dataflow/generic/cursor.rs @@ -0,0 +1,265 @@ +//! Random access inspection of the results of a dataflow analysis. + +use std::borrow::Borrow; + +use rustc::mir::{self, BasicBlock, Location}; +use rustc_index::bit_set::BitSet; + +use super::{Analysis, Results}; + +/// A `ResultsCursor` that borrows the underlying `Results`. +pub type ResultsRefCursor<'a, 'mir, 'tcx, A> = ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>; + +/// Allows random access inspection of the results of a dataflow analysis. +/// +/// This cursor only has linear performance within a basic block when its statements are visited in +/// order. In the worst case—when statements are visited in *reverse* order—performance will be +/// quadratic in the number of statements in the block. The order in which basic blocks are +/// inspected has no impact on performance. +/// +/// A `ResultsCursor` can either own (the default) or borrow the dataflow results it inspects. The +/// type of ownership is determined by `R` (see `ResultsRefCursor` above). +pub struct ResultsCursor<'mir, 'tcx, A, R = Results<'tcx, A>> +where + A: Analysis<'tcx>, +{ + body: &'mir mir::Body<'tcx>, + results: R, + state: BitSet, + + pos: CursorPosition, + + /// When this flag is set, the cursor is pointing at a `Call` terminator whose call return + /// effect has been applied to `state`. + /// + /// This flag helps to ensure that multiple calls to `seek_after_assume_call_returns` with the + /// same target will result in exactly one invocation of `apply_call_return_effect`. It is + /// sufficient to clear this only in `seek_to_block_start`, since seeking away from a + /// terminator will always require a cursor reset. + call_return_effect_applied: bool, +} + +impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R> +where + A: Analysis<'tcx>, + R: Borrow>, +{ + /// Returns a new cursor for `results` that points to the start of the `START_BLOCK`. + pub fn new(body: &'mir mir::Body<'tcx>, results: R) -> Self { + ResultsCursor { + body, + pos: CursorPosition::BlockStart(mir::START_BLOCK), + state: results.borrow().entry_sets[mir::START_BLOCK].clone(), + call_return_effect_applied: false, + results, + } + } + + /// Returns the `Analysis` used to generate the underlying results. + pub fn analysis(&self) -> &A { + &self.results.borrow().analysis + } + + /// Returns the dataflow state at the current location. + pub fn get(&self) -> &BitSet { + &self.state + } + + /// Resets the cursor to the start of the given basic block. + pub fn seek_to_block_start(&mut self, block: BasicBlock) { + self.state.overwrite(&self.results.borrow().entry_sets[block]); + self.pos = CursorPosition::BlockStart(block); + self.call_return_effect_applied = false; + } + + /// Advances the cursor to hold all effects up to and including to the "before" effect of the + /// statement (or terminator) at the given location. + /// + /// If you wish to observe the full effect of a statement or terminator, not just the "before" + /// effect, use `seek_after` or `seek_after_assume_call_returns`. + pub fn seek_before(&mut self, target: Location) { + assert!(target <= self.body.terminator_loc(target.block)); + self._seek(target, false); + } + + /// Advances the cursor to hold the full effect of all statements (and possibly closing + /// terminators) up to and including the `target`. + /// + /// If the `target` is a `Call` terminator, any call return effect for that terminator will + /// **not** be observed. Use `seek_after_assume_call_returns` if you wish to observe the call + /// return effect. + pub fn seek_after(&mut self, target: Location) { + assert!(target <= self.body.terminator_loc(target.block)); + + // If we have already applied the call return effect, we are currently pointing at a `Call` + // terminator. Unconditionally reset the dataflow cursor, since there is no way to "undo" + // the call return effect. + if self.call_return_effect_applied { + self.seek_to_block_start(target.block); + } + + self._seek(target, true); + } + + /// Advances the cursor to hold all effects up to and including of the statement (or + /// terminator) at the given location. + /// + /// If the `target` is a `Call` terminator, any call return effect for that terminator will + /// be observed. Use `seek_after` if you do **not** wish to observe the call return effect. + pub fn seek_after_assume_call_returns(&mut self, target: Location) { + let terminator_loc = self.body.terminator_loc(target.block); + assert!(target.statement_index <= terminator_loc.statement_index); + + self._seek(target, true); + + if target != terminator_loc { + return; + } + + let terminator = self.body.basic_blocks()[target.block].terminator(); + if let mir::TerminatorKind::Call { + destination: Some((return_place, _)), func, args, .. + } = &terminator.kind + { + if !self.call_return_effect_applied { + self.call_return_effect_applied = true; + self.results.borrow().analysis.apply_call_return_effect( + &mut self.state, + target.block, + func, + args, + return_place, + ); + } + } + } + + fn _seek(&mut self, target: Location, apply_after_effect_at_target: bool) { + use CursorPosition::*; + + match self.pos { + // Return early if we are already at the target location. + Before(curr) if curr == target && !apply_after_effect_at_target => return, + After(curr) if curr == target && apply_after_effect_at_target => return, + + // Otherwise, we must reset to the start of the target block if... + + // we are in a different block entirely. + BlockStart(block) | Before(Location { block, .. }) | After(Location { block, .. }) + if block != target.block => + { + self.seek_to_block_start(target.block) + } + + // we are in the same block but have advanced past the target statement. + Before(curr) | After(curr) if curr.statement_index > target.statement_index => { + self.seek_to_block_start(target.block) + } + + // we have already applied the entire effect of a statement but only wish to observe + // its "before" effect. + After(curr) + if curr.statement_index == target.statement_index + && !apply_after_effect_at_target => + { + self.seek_to_block_start(target.block) + } + + // N.B., `call_return_effect_applied` is checked in `seek_after`, not here. + _ => (), + } + + let analysis = &self.results.borrow().analysis; + let block_data = &self.body.basic_blocks()[target.block]; + + // At this point, the cursor is in the same block as the target location at an earlier + // statement. + debug_assert_eq!(target.block, self.pos.block()); + + // Find the first statement whose transfer function has not yet been applied. + let first_unapplied_statement = match self.pos { + BlockStart(_) => 0, + After(Location { statement_index, .. }) => statement_index + 1, + + // If we have only applied the "before" effect for the current statement, apply the + // remainder before continuing. + Before(curr) => { + if curr.statement_index == block_data.statements.len() { + let terminator = block_data.terminator(); + analysis.apply_terminator_effect(&mut self.state, terminator, curr); + } else { + let statement = &block_data.statements[curr.statement_index]; + analysis.apply_statement_effect(&mut self.state, statement, curr); + } + + // If all we needed to do was go from `Before` to `After` in the same statement, + // we are now done. + if curr.statement_index == target.statement_index { + debug_assert!(apply_after_effect_at_target); + self.pos = After(target); + return; + } + + curr.statement_index + 1 + } + }; + + // We have now applied all effects prior to `first_unapplied_statement`. + + // Apply the effects of all statements before `target`. + let mut location = Location { block: target.block, statement_index: 0 }; + for statement_index in first_unapplied_statement..target.statement_index { + location.statement_index = statement_index; + let statement = &block_data.statements[statement_index]; + analysis.apply_before_statement_effect(&mut self.state, statement, location); + analysis.apply_statement_effect(&mut self.state, statement, location); + } + + // Apply the effect of the statement (or terminator) at `target`. + location.statement_index = target.statement_index; + if target.statement_index == block_data.statements.len() { + let terminator = &block_data.terminator(); + analysis.apply_before_terminator_effect(&mut self.state, terminator, location); + + if apply_after_effect_at_target { + analysis.apply_terminator_effect(&mut self.state, terminator, location); + self.pos = After(target); + } else { + self.pos = Before(target); + } + } else { + let statement = &block_data.statements[target.statement_index]; + analysis.apply_before_statement_effect(&mut self.state, statement, location); + + if apply_after_effect_at_target { + analysis.apply_statement_effect(&mut self.state, statement, location); + self.pos = After(target) + } else { + self.pos = Before(target); + } + } + } +} + +#[derive(Clone, Copy, Debug)] +enum CursorPosition { + /// No effects within this block have been applied. + BlockStart(BasicBlock), + + /// Only the "before" effect of the statement (or terminator) at this location has been + /// applied (along with the effects of all previous statements). + Before(Location), + + /// The effects of all statements up to and including the one at this location have been + /// applied. + After(Location), +} + +impl CursorPosition { + fn block(&self) -> BasicBlock { + match *self { + Self::BlockStart(block) => block, + Self::Before(loc) | Self::After(loc) => loc.block, + } + } +} diff --git a/src/librustc_mir/dataflow/generic/engine.rs b/src/librustc_mir/dataflow/generic/engine.rs new file mode 100644 index 0000000000000..3322177006666 --- /dev/null +++ b/src/librustc_mir/dataflow/generic/engine.rs @@ -0,0 +1,421 @@ +//! A solver for dataflow problems. + +use std::ffi::OsString; +use std::fs; +use std::path::PathBuf; + +use rustc::mir::{self, traversal, BasicBlock, Location}; +use rustc::ty::TyCtxt; +use rustc_data_structures::work_queue::WorkQueue; +use rustc_hir::def_id::DefId; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; +use rustc_span::symbol::{sym, Symbol}; +use syntax::ast; + +use super::graphviz; +use super::{Analysis, GenKillAnalysis, GenKillSet, Results}; + +/// A solver for dataflow problems. +pub struct Engine<'a, 'tcx, A> +where + A: Analysis<'tcx>, +{ + bits_per_block: usize, + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, + def_id: DefId, + dead_unwinds: Option<&'a BitSet>, + entry_sets: IndexVec>, + analysis: A, + + /// Cached, cumulative transfer functions for each block. + trans_for_block: Option>>, +} + +impl Engine<'a, 'tcx, A> +where + A: GenKillAnalysis<'tcx>, +{ + /// Creates a new `Engine` to solve a gen-kill dataflow problem. + pub fn new_gen_kill( + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, + def_id: DefId, + analysis: A, + ) -> Self { + let bits_per_block = analysis.bits_per_block(body); + let mut trans_for_block = + IndexVec::from_elem(GenKillSet::identity(bits_per_block), body.basic_blocks()); + + // Compute cumulative block transfer functions. + // + // FIXME: we may want to skip this if the MIR is acyclic, since we will never access a + // block transfer function more than once. + + for (block, block_data) in body.basic_blocks().iter_enumerated() { + let trans = &mut trans_for_block[block]; + + for (i, statement) in block_data.statements.iter().enumerate() { + let loc = Location { block, statement_index: i }; + analysis.before_statement_effect(trans, statement, loc); + analysis.statement_effect(trans, statement, loc); + } + + if let Some(terminator) = &block_data.terminator { + let loc = Location { block, statement_index: block_data.statements.len() }; + analysis.before_terminator_effect(trans, terminator, loc); + analysis.terminator_effect(trans, terminator, loc); + } + } + + Self::new(tcx, body, def_id, analysis, Some(trans_for_block)) + } +} + +impl Engine<'a, 'tcx, A> +where + A: Analysis<'tcx>, +{ + /// Creates a new `Engine` to solve a dataflow problem with an arbitrary transfer + /// function. + /// + /// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for + /// better performance. + pub fn new_generic( + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, + def_id: DefId, + analysis: A, + ) -> Self { + Self::new(tcx, body, def_id, analysis, None) + } + + fn new( + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, + def_id: DefId, + analysis: A, + trans_for_block: Option>>, + ) -> Self { + let bits_per_block = analysis.bits_per_block(body); + + let bottom_value_set = if A::BOTTOM_VALUE == true { + BitSet::new_filled(bits_per_block) + } else { + BitSet::new_empty(bits_per_block) + }; + + let mut entry_sets = IndexVec::from_elem(bottom_value_set, body.basic_blocks()); + analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); + + Engine { + analysis, + bits_per_block, + tcx, + body, + def_id, + dead_unwinds: None, + entry_sets, + trans_for_block, + } + } + + pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet) -> Self { + self.dead_unwinds = Some(dead_unwinds); + self + } + + pub fn iterate_to_fixpoint(mut self) -> Results<'tcx, A> { + let mut temp_state = BitSet::new_empty(self.bits_per_block); + + let mut dirty_queue: WorkQueue = + WorkQueue::with_none(self.body.basic_blocks().len()); + + for (bb, _) in traversal::reverse_postorder(self.body) { + dirty_queue.insert(bb); + } + + // Add blocks that are not reachable from START_BLOCK to the work queue. These blocks will + // be processed after the ones added above. + for bb in self.body.basic_blocks().indices() { + dirty_queue.insert(bb); + } + + while let Some(bb) = dirty_queue.pop() { + let bb_data = &self.body[bb]; + let on_entry = &self.entry_sets[bb]; + + temp_state.overwrite(on_entry); + self.apply_whole_block_effect(&mut temp_state, bb, bb_data); + + self.propagate_bits_into_graph_successors_of( + &mut temp_state, + (bb, bb_data), + &mut dirty_queue, + ); + } + + let Engine { tcx, body, def_id, trans_for_block, entry_sets, analysis, .. } = self; + let results = Results { analysis, entry_sets }; + + let res = write_graphviz_results(tcx, def_id, body, &results, trans_for_block); + if let Err(e) = res { + warn!("Failed to write graphviz dataflow results: {}", e); + } + + results + } + + /// Applies the cumulative effect of an entire block, excluding the call return effect if one + /// exists. + fn apply_whole_block_effect( + &self, + state: &mut BitSet, + block: BasicBlock, + block_data: &mir::BasicBlockData<'tcx>, + ) { + // Use the cached block transfer function if available. + if let Some(trans_for_block) = &self.trans_for_block { + trans_for_block[block].apply(state); + return; + } + + // Otherwise apply effects one-by-one. + + for (statement_index, statement) in block_data.statements.iter().enumerate() { + let location = Location { block, statement_index }; + self.analysis.apply_before_statement_effect(state, statement, location); + self.analysis.apply_statement_effect(state, statement, location); + } + + let terminator = block_data.terminator(); + let location = Location { block, statement_index: block_data.statements.len() }; + self.analysis.apply_before_terminator_effect(state, terminator, location); + self.analysis.apply_terminator_effect(state, terminator, location); + } + + fn propagate_bits_into_graph_successors_of( + &mut self, + in_out: &mut BitSet, + (bb, bb_data): (BasicBlock, &'a mir::BasicBlockData<'tcx>), + dirty_list: &mut WorkQueue, + ) { + use mir::TerminatorKind::*; + + match bb_data.terminator().kind { + Return | Resume | Abort | GeneratorDrop | Unreachable => {} + + Goto { target } + | Assert { target, cleanup: None, .. } + | Yield { resume: target, drop: None, .. } + | Drop { target, location: _, unwind: None } + | DropAndReplace { target, value: _, location: _, unwind: None } => { + self.propagate_bits_into_entry_set_for(in_out, target, dirty_list) + } + + Yield { resume: target, drop: Some(drop), .. } => { + self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); + self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list); + } + + Assert { target, cleanup: Some(unwind), .. } + | Drop { target, location: _, unwind: Some(unwind) } + | DropAndReplace { target, value: _, location: _, unwind: Some(unwind) } => { + self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); + if self.dead_unwinds.map_or(true, |bbs| !bbs.contains(bb)) { + self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); + } + } + + SwitchInt { ref targets, .. } => { + for target in targets { + self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list); + } + } + + Call { cleanup, ref destination, ref func, ref args, .. } => { + if let Some(unwind) = cleanup { + if self.dead_unwinds.map_or(true, |bbs| !bbs.contains(bb)) { + self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); + } + } + + if let Some((ref dest_place, dest_bb)) = *destination { + // N.B.: This must be done *last*, otherwise the unwind path will see the call + // return effect. + self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place); + self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list); + } + } + + FalseEdges { real_target, imaginary_target } => { + self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list); + self.propagate_bits_into_entry_set_for(in_out, imaginary_target, dirty_list); + } + + FalseUnwind { real_target, unwind } => { + self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list); + if let Some(unwind) = unwind { + if self.dead_unwinds.map_or(true, |bbs| !bbs.contains(bb)) { + self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); + } + } + } + } + } + + fn propagate_bits_into_entry_set_for( + &mut self, + in_out: &BitSet, + bb: BasicBlock, + dirty_queue: &mut WorkQueue, + ) { + let entry_set = &mut self.entry_sets[bb]; + let set_changed = self.analysis.join(entry_set, &in_out); + if set_changed { + dirty_queue.insert(bb); + } + } +} + +// Graphviz + +/// Writes a DOT file containing the results of a dataflow analysis if the user requested it via +/// `rustc_mir` attributes. +fn write_graphviz_results( + tcx: TyCtxt<'tcx>, + def_id: DefId, + body: &mir::Body<'tcx>, + results: &Results<'tcx, A>, + block_transfer_functions: Option>>, +) -> std::io::Result<()> +where + A: Analysis<'tcx>, +{ + let attrs = match RustcMirAttrs::parse(tcx, def_id) { + Ok(attrs) => attrs, + + // Invalid `rustc_mir` attrs will be reported using `span_err`. + Err(()) => return Ok(()), + }; + + let path = match attrs.output_path(A::NAME) { + Some(path) => path, + None => return Ok(()), + }; + + let bits_per_block = results.analysis.bits_per_block(body); + + let mut formatter: Box> = match attrs.formatter { + Some(sym::two_phase) => Box::new(graphviz::TwoPhaseDiff::new(bits_per_block)), + Some(sym::gen_kill) => { + if let Some(trans_for_block) = block_transfer_functions { + Box::new(graphviz::BlockTransferFunc::new(body, trans_for_block)) + } else { + Box::new(graphviz::SimpleDiff::new(bits_per_block)) + } + } + + // Default to the `SimpleDiff` output style. + _ => Box::new(graphviz::SimpleDiff::new(bits_per_block)), + }; + + debug!("printing dataflow results for {:?} to {}", def_id, path.display()); + let mut buf = Vec::new(); + + let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter); + dot::render(&graphviz, &mut buf)?; + fs::write(&path, buf)?; + Ok(()) +} + +#[derive(Default)] +struct RustcMirAttrs { + basename_and_suffix: Option, + formatter: Option, +} + +impl RustcMirAttrs { + fn parse(tcx: TyCtxt<'tcx>, def_id: DefId) -> Result { + let attrs = tcx.get_attrs(def_id); + + let mut result = Ok(()); + let mut ret = RustcMirAttrs::default(); + + let rustc_mir_attrs = attrs + .into_iter() + .filter(|attr| attr.check_name(sym::rustc_mir)) + .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); + + for attr in rustc_mir_attrs { + let attr_result = if attr.check_name(sym::borrowck_graphviz_postflow) { + Self::set_field(&mut ret.basename_and_suffix, tcx, &attr, |s| { + let path = PathBuf::from(s.to_string()); + match path.file_name() { + Some(_) => Ok(path), + None => { + tcx.sess.span_err(attr.span(), "path must end in a filename"); + Err(()) + } + } + }) + } else if attr.check_name(sym::borrowck_graphviz_format) { + Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s { + sym::gen_kill | sym::two_phase => Ok(s), + _ => { + tcx.sess.span_err(attr.span(), "unknown formatter"); + Err(()) + } + }) + } else { + Ok(()) + }; + + result = result.and(attr_result); + } + + result.map(|()| ret) + } + + fn set_field( + field: &mut Option, + tcx: TyCtxt<'tcx>, + attr: &ast::NestedMetaItem, + mapper: impl FnOnce(Symbol) -> Result, + ) -> Result<(), ()> { + if field.is_some() { + tcx.sess + .span_err(attr.span(), &format!("duplicate values for `{}`", attr.name_or_empty())); + + return Err(()); + } + + if let Some(s) = attr.value_str() { + *field = Some(mapper(s)?); + Ok(()) + } else { + tcx.sess + .span_err(attr.span(), &format!("`{}` requires an argument", attr.name_or_empty())); + Err(()) + } + } + + /// Returns the path where dataflow results should be written, or `None` + /// `borrowck_graphviz_postflow` was not specified. + /// + /// This performs the following transformation to the argument of `borrowck_graphviz_postflow`: + /// + /// "path/suffix.dot" -> "path/analysis_name_suffix.dot" + fn output_path(&self, analysis_name: &str) -> Option { + let mut ret = self.basename_and_suffix.as_ref().cloned()?; + let suffix = ret.file_name().unwrap(); // Checked when parsing attrs + + let mut file_name: OsString = analysis_name.into(); + file_name.push("_"); + file_name.push(suffix); + ret.set_file_name(file_name); + + Some(ret) + } +} diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs new file mode 100644 index 0000000000000..1b628f2c7eb8e --- /dev/null +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -0,0 +1,309 @@ +//! A framework for expressing dataflow problems. + +use std::io; + +use rustc::mir::{self, BasicBlock, Location}; +use rustc_index::bit_set::{BitSet, HybridBitSet}; +use rustc_index::vec::{Idx, IndexVec}; + +use crate::dataflow::BottomValue; + +mod cursor; +mod engine; +mod graphviz; + +pub use self::cursor::{ResultsCursor, ResultsRefCursor}; +pub use self::engine::Engine; + +/// A dataflow analysis that has converged to fixpoint. +pub struct Results<'tcx, A> +where + A: Analysis<'tcx>, +{ + pub analysis: A, + entry_sets: IndexVec>, +} + +impl Results<'tcx, A> +where + A: Analysis<'tcx>, +{ + pub fn into_cursor(self, body: &'mir mir::Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> { + ResultsCursor::new(body, self) + } + + pub fn on_block_entry(&self, block: BasicBlock) -> &BitSet { + &self.entry_sets[block] + } +} + +/// Define the domain of a dataflow problem. +/// +/// This trait specifies the lattice on which this analysis operates. For now, this must be a +/// powerset of values of type `Idx`. The elements of this lattice are represented with a `BitSet` +/// and referred to as the state vector. +/// +/// This trait also defines the initial value for the dataflow state upon entry to the +/// `START_BLOCK`, as well as some names used to refer to this analysis when debugging. +pub trait AnalysisDomain<'tcx>: BottomValue { + /// The type of the elements in the state vector. + type Idx: Idx; + + /// A descriptive name for this analysis. Used only for debugging. + /// + /// This name should be brief and contain no spaces, periods or other characters that are not + /// suitable as part of a filename. + const NAME: &'static str; + + /// The size of the state vector. + fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize; + + /// Mutates the entry set of the `START_BLOCK` to contain the initial state for dataflow + /// analysis. + fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet); + + /// Prints an element in the state vector for debugging. + fn pretty_print_idx(&self, w: &mut impl io::Write, idx: Self::Idx) -> io::Result<()> { + write!(w, "{:?}", idx) + } +} + +/// Define a dataflow problem with an arbitrarily complex transfer function. +pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { + /// Updates the current dataflow state with the effect of evaluating a statement. + fn apply_statement_effect( + &self, + state: &mut BitSet, + statement: &mir::Statement<'tcx>, + location: Location, + ); + + /// Updates the current dataflow state with an effect that occurs immediately *before* the + /// given statement. + /// + /// This method is useful if the consumer of the results of this analysis needs only to observe + /// *part* of the effect of a statement (e.g. for two-phase borrows). As a general rule, + /// analyses should not implement this without implementing `apply_statement_effect`. + fn apply_before_statement_effect( + &self, + _state: &mut BitSet, + _statement: &mir::Statement<'tcx>, + _location: Location, + ) { + } + + /// Updates the current dataflow state with the effect of evaluating a terminator. + /// + /// The effect of a successful return from a `Call` terminator should **not** be accounted for + /// in this function. That should go in `apply_call_return_effect`. For example, in the + /// `InitializedPlaces` analyses, the return place for a function call is not marked as + /// initialized here. + fn apply_terminator_effect( + &self, + state: &mut BitSet, + terminator: &mir::Terminator<'tcx>, + location: Location, + ); + + /// Updates the current dataflow state with an effect that occurs immediately *before* the + /// given terminator. + /// + /// This method is useful if the consumer of the results of this analysis needs only to observe + /// *part* of the effect of a terminator (e.g. for two-phase borrows). As a general rule, + /// analyses should not implement this without implementing `apply_terminator_effect`. + fn apply_before_terminator_effect( + &self, + _state: &mut BitSet, + _terminator: &mir::Terminator<'tcx>, + _location: Location, + ) { + } + + /// Updates the current dataflow state with the effect of a successful return from a `Call` + /// terminator. + /// + /// This is separate from `apply_terminator_effect` to properly track state across unwind + /// edges. + fn apply_call_return_effect( + &self, + state: &mut BitSet, + block: BasicBlock, + func: &mir::Operand<'tcx>, + args: &[mir::Operand<'tcx>], + return_place: &mir::Place<'tcx>, + ); +} + +/// Define a gen/kill dataflow problem. +/// +/// Each method in this trait has a corresponding one in `Analysis`. However, these methods only +/// allow modification of the dataflow state via "gen" and "kill" operations. By defining transfer +/// functions for each statement in this way, the transfer function for an entire basic block can +/// be computed efficiently. +/// +/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis`. +pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { + /// See `Analysis::apply_statement_effect`. + fn statement_effect( + &self, + trans: &mut impl GenKill, + statement: &mir::Statement<'tcx>, + location: Location, + ); + + /// See `Analysis::apply_before_statement_effect`. + fn before_statement_effect( + &self, + _trans: &mut impl GenKill, + _statement: &mir::Statement<'tcx>, + _location: Location, + ) { + } + + /// See `Analysis::apply_terminator_effect`. + fn terminator_effect( + &self, + trans: &mut impl GenKill, + terminator: &mir::Terminator<'tcx>, + location: Location, + ); + + /// See `Analysis::apply_before_terminator_effect`. + fn before_terminator_effect( + &self, + _trans: &mut impl GenKill, + _terminator: &mir::Terminator<'tcx>, + _location: Location, + ) { + } + + /// See `Analysis::apply_call_return_effect`. + fn call_return_effect( + &self, + trans: &mut impl GenKill, + block: BasicBlock, + func: &mir::Operand<'tcx>, + args: &[mir::Operand<'tcx>], + return_place: &mir::Place<'tcx>, + ); +} + +impl Analysis<'tcx> for A +where + A: GenKillAnalysis<'tcx>, +{ + fn apply_statement_effect( + &self, + state: &mut BitSet, + statement: &mir::Statement<'tcx>, + location: Location, + ) { + self.statement_effect(state, statement, location); + } + + fn apply_before_statement_effect( + &self, + state: &mut BitSet, + statement: &mir::Statement<'tcx>, + location: Location, + ) { + self.before_statement_effect(state, statement, location); + } + + fn apply_terminator_effect( + &self, + state: &mut BitSet, + terminator: &mir::Terminator<'tcx>, + location: Location, + ) { + self.terminator_effect(state, terminator, location); + } + + fn apply_before_terminator_effect( + &self, + state: &mut BitSet, + terminator: &mir::Terminator<'tcx>, + location: Location, + ) { + self.before_terminator_effect(state, terminator, location); + } + + fn apply_call_return_effect( + &self, + state: &mut BitSet, + block: BasicBlock, + func: &mir::Operand<'tcx>, + args: &[mir::Operand<'tcx>], + return_place: &mir::Place<'tcx>, + ) { + self.call_return_effect(state, block, func, args, return_place); + } +} + +/// The legal operations for a transfer function in a gen/kill problem. +pub trait GenKill: Sized { + /// Inserts `elem` into the `gen` set, removing it the `kill` set if present. + fn gen(&mut self, elem: T); + + /// Inserts `elem` into the `kill` set, removing it the `gen` set if present. + fn kill(&mut self, elem: T); + + /// Inserts the given elements into the `gen` set, removing them from the `kill` set if present. + fn gen_all(&mut self, elems: impl IntoIterator) { + for elem in elems { + self.gen(elem); + } + } + + /// Inserts the given elements into the `kill` set, removing them from the `gen` set if present. + fn kill_all(&mut self, elems: impl IntoIterator) { + for elem in elems { + self.kill(elem); + } + } +} + +/// Stores a transfer function for a gen/kill problem. +#[derive(Clone)] +pub struct GenKillSet { + gen: HybridBitSet, + kill: HybridBitSet, +} + +impl GenKillSet { + /// Creates a new transfer function that will leave the dataflow state unchanged. + pub fn identity(universe: usize) -> Self { + GenKillSet { + gen: HybridBitSet::new_empty(universe), + kill: HybridBitSet::new_empty(universe), + } + } + + /// Applies this transfer function to the given bitset. + pub fn apply(&self, state: &mut BitSet) { + state.union(&self.gen); + state.subtract(&self.kill); + } +} + +impl GenKill for GenKillSet { + fn gen(&mut self, elem: T) { + self.gen.insert(elem); + self.kill.remove(elem); + } + + fn kill(&mut self, elem: T) { + self.kill.insert(elem); + self.gen.remove(elem); + } +} + +impl GenKill for BitSet { + fn gen(&mut self, elem: T) { + self.insert(elem); + } + + fn kill(&mut self, elem: T) { + self.remove(elem); + } +} From 7d5885727d4a42518f811933de20676f8be61818 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 11 Nov 2019 11:49:08 -0800 Subject: [PATCH 0341/1253] Remove old "generic" framework --- src/librustc_mir/dataflow/generic.rs | 595 --------------------------- 1 file changed, 595 deletions(-) delete mode 100644 src/librustc_mir/dataflow/generic.rs diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs deleted file mode 100644 index d2ca4f1572c1f..0000000000000 --- a/src/librustc_mir/dataflow/generic.rs +++ /dev/null @@ -1,595 +0,0 @@ -//! Dataflow analysis with arbitrary transfer functions. -//! -//! This module is a work in progress. You should instead use `BitDenotation` in -//! `librustc_mir/dataflow/mod.rs` and encode your transfer function as a [gen/kill set][gk]. In -//! doing so, your analysis will run faster and you will be able to generate graphviz diagrams for -//! debugging with no extra effort. The interface in this module is intended only for dataflow -//! problems that cannot be expressed using gen/kill sets. -//! -//! FIXME(ecstaticmorse): In the long term, the plan is to preserve the existing `BitDenotation` -//! interface, but make `Engine` and `ResultsCursor` the canonical way to perform and inspect a -//! dataflow analysis. This requires porting the graphviz debugging logic to this module, deciding -//! on a way to handle the `before` methods in `BitDenotation` and creating an adapter so that -//! gen-kill problems can still be evaluated efficiently. See the discussion in [#64566] for more -//! information. -//! -//! [gk]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems -//! [#64566]: https://github.com/rust-lang/rust/pull/64566 - -use std::borrow::Borrow; -use std::cmp::Ordering; -use std::ffi::OsString; -use std::path::{Path, PathBuf}; -use std::{fs, io, ops}; - -use rustc::mir::{self, traversal, BasicBlock, Location}; -use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::work_queue::WorkQueue; -use rustc_hir::def_id::DefId; -use rustc_index::bit_set::BitSet; -use rustc_index::vec::{Idx, IndexVec}; -use rustc_span::symbol::sym; - -use crate::dataflow::BottomValue; - -mod graphviz; - -/// A specific kind of dataflow analysis. -/// -/// To run a dataflow analysis, one must set the initial state of the `START_BLOCK` via -/// `initialize_start_block` and define a transfer function for each statement or terminator via -/// the various `effect` methods. The entry set for all other basic blocks is initialized to -/// `Self::BOTTOM_VALUE`. The dataflow `Engine` then iteratively updates the various entry sets for -/// each block with the cumulative effects of the transfer functions of all preceding blocks. -/// -/// You should use an `Engine` to actually run an analysis, and a `ResultsCursor` to inspect the -/// results of that analysis like so: -/// -/// ```ignore(cross-crate-imports) -/// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet) { -/// // `MyAnalysis` implements `Analysis`. -/// let analysis = MyAnalysis::new(); -/// -/// let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint(); -/// let mut cursor = ResultsCursor::new(body, results); -/// -/// for (_, statement_index) in body.block_data[START_BLOCK].statements.iter_enumerated() { -/// cursor.seek_after(Location { block: START_BLOCK, statement_index }); -/// let state = cursor.get(); -/// println!("{:?}", state); -/// } -/// } -/// ``` -pub trait Analysis<'tcx>: BottomValue { - /// The index type used to access the dataflow state. - type Idx: Idx; - - /// A name, used for debugging, that describes this dataflow analysis. - /// - /// The name should be suitable as part of a filename, so avoid whitespace, slashes or periods - /// and try to keep it short. - const NAME: &'static str; - - /// How each element of your dataflow state will be displayed during debugging. - /// - /// By default, this is the `fmt::Debug` representation of `Self::Idx`. - fn pretty_print_idx(&self, w: &mut impl io::Write, idx: Self::Idx) -> io::Result<()> { - write!(w, "{:?}", idx) - } - - /// The size of each bitvector allocated for each block. - fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize; - - /// Mutates the entry set of the `START_BLOCK` to contain the initial state for dataflow - /// analysis. - fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet); - - /// Updates the current dataflow state with the effect of evaluating a statement. - fn apply_statement_effect( - &self, - state: &mut BitSet, - statement: &mir::Statement<'tcx>, - location: Location, - ); - - /// Updates the current dataflow state with the effect of evaluating a terminator. - /// - /// Note that the effect of a successful return from a `Call` terminator should **not** be - /// acounted for in this function. That should go in `apply_call_return_effect`. For example, - /// in the `InitializedPlaces` analyses, the return place is not marked as initialized here. - fn apply_terminator_effect( - &self, - state: &mut BitSet, - terminator: &mir::Terminator<'tcx>, - location: Location, - ); - - /// Updates the current dataflow state with the effect of a successful return from a `Call` - /// terminator. - /// - /// This is separated from `apply_terminator_effect` to properly track state across - /// unwind edges for `Call`s. - fn apply_call_return_effect( - &self, - state: &mut BitSet, - block: BasicBlock, - func: &mir::Operand<'tcx>, - args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, - ); - - /// Applies the cumulative effect of an entire basic block to the dataflow state (except for - /// `call_return_effect`, which is handled in the `Engine`). - /// - /// The default implementation calls `statement_effect` for every statement in the block before - /// finally calling `terminator_effect`. However, some dataflow analyses are able to coalesce - /// transfer functions for an entire block and apply them at once. Such analyses should - /// override `block_effect`. - fn apply_whole_block_effect( - &self, - state: &mut BitSet, - block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - ) { - for (statement_index, stmt) in block_data.statements.iter().enumerate() { - let location = Location { block, statement_index }; - self.apply_statement_effect(state, stmt, location); - } - - let location = Location { block, statement_index: block_data.statements.len() }; - self.apply_terminator_effect(state, block_data.terminator(), location); - } - - /// Applies the cumulative effect of a sequence of statements (and possibly a terminator) - /// within a single basic block. - /// - /// When called with `0..block_data.statements.len() + 1` as the statement range, this function - /// is equivalent to `apply_whole_block_effect`. - fn apply_partial_block_effect( - &self, - state: &mut BitSet, - block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - mut range: ops::Range, - ) { - if range.is_empty() { - return; - } - - // The final location might be a terminator, so iterate through all statements until the - // final one, then check to see whether the final one is a statement or terminator. - // - // This can't cause the range to wrap-around since we check that the range contains at - // least one element above. - range.end -= 1; - let final_location = Location { block, statement_index: range.end }; - - for statement_index in range { - let location = Location { block, statement_index }; - let stmt = &block_data.statements[statement_index]; - self.apply_statement_effect(state, stmt, location); - } - - if final_location.statement_index == block_data.statements.len() { - let terminator = block_data.terminator(); - self.apply_terminator_effect(state, terminator, final_location); - } else { - let stmt = &block_data.statements[final_location.statement_index]; - self.apply_statement_effect(state, stmt, final_location); - } - } -} - -#[derive(Clone, Copy, Debug)] -enum CursorPosition { - AtBlockStart(BasicBlock), - After(Location), -} - -impl CursorPosition { - fn block(&self) -> BasicBlock { - match *self { - Self::AtBlockStart(block) => block, - Self::After(Location { block, .. }) => block, - } - } -} - -type ResultsRefCursor<'a, 'mir, 'tcx, A> = ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>; - -/// Inspect the results of dataflow analysis. -/// -/// This cursor has linear performance when visiting statements in a block in order. Visiting -/// statements within a block in reverse order is `O(n^2)`, where `n` is the number of statements -/// in that block. -pub struct ResultsCursor<'mir, 'tcx, A, R = Results<'tcx, A>> -where - A: Analysis<'tcx>, -{ - body: &'mir mir::Body<'tcx>, - results: R, - state: BitSet, - - pos: CursorPosition, - - /// Whether the effects of `apply_call_return_effect` are currently stored in `state`. - /// - /// This flag ensures that multiple calls to `seek_after_assume_call_returns` with the same - /// target only result in one invocation of `apply_call_return_effect`. - is_call_return_effect_applied: bool, -} - -impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R> -where - A: Analysis<'tcx>, - R: Borrow>, -{ - /// Returns a new cursor for `results` that points to the start of the `START_BLOCK`. - pub fn new(body: &'mir mir::Body<'tcx>, results: R) -> Self { - ResultsCursor { - body, - pos: CursorPosition::AtBlockStart(mir::START_BLOCK), - is_call_return_effect_applied: false, - state: results.borrow().entry_sets[mir::START_BLOCK].clone(), - results, - } - } - - pub fn analysis(&self) -> &A { - &self.results.borrow().analysis - } - - /// Resets the cursor to the start of the given `block`. - pub fn seek_to_block_start(&mut self, block: BasicBlock) { - self.state.overwrite(&self.results.borrow().entry_sets[block]); - self.pos = CursorPosition::AtBlockStart(block); - self.is_call_return_effect_applied = false; - } - - /// Updates the cursor to hold the dataflow state immediately before `target`. - pub fn seek_before(&mut self, target: Location) { - assert!(target <= self.body.terminator_loc(target.block)); - - if target.statement_index == 0 { - self.seek_to_block_start(target.block); - } else { - self._seek_after(Location { - block: target.block, - statement_index: target.statement_index - 1, - }); - } - } - - /// Updates the cursor to hold the dataflow state at `target`. - /// - /// If `target` is a `Call` terminator, `apply_call_return_effect` will not be called. See - /// `seek_after_assume_call_returns` if you wish to observe the dataflow state upon a - /// successful return. - pub fn seek_after(&mut self, target: Location) { - assert!(target <= self.body.terminator_loc(target.block)); - - // This check ensures the correctness of a call to `seek_after_assume_call_returns` - // followed by one to `seek_after` with the same target. - if self.is_call_return_effect_applied { - self.seek_to_block_start(target.block); - } - - self._seek_after(target); - } - - /// Equivalent to `seek_after`, but also calls `apply_call_return_effect` if `target` is a - /// `Call` terminator whose callee is convergent. - pub fn seek_after_assume_call_returns(&mut self, target: Location) { - assert!(target <= self.body.terminator_loc(target.block)); - - self._seek_after(target); - - if target != self.body.terminator_loc(target.block) { - return; - } - - let term = self.body.basic_blocks()[target.block].terminator(); - if let mir::TerminatorKind::Call { - destination: Some((return_place, _)), func, args, .. - } = &term.kind - { - if !self.is_call_return_effect_applied { - self.is_call_return_effect_applied = true; - self.results.borrow().analysis.apply_call_return_effect( - &mut self.state, - target.block, - func, - args, - return_place, - ); - } - } - } - - fn _seek_after(&mut self, target: Location) { - let Location { block: target_block, statement_index: target_index } = target; - - if self.pos.block() != target_block { - self.seek_to_block_start(target_block); - } - - // If we're in the same block but after the target statement, we need to reset to the start - // of the block. - if let CursorPosition::After(Location { statement_index: curr_index, .. }) = self.pos { - match curr_index.cmp(&target_index) { - Ordering::Equal => return, - Ordering::Less => {} - Ordering::Greater => self.seek_to_block_start(target_block), - } - } - - // The cursor is now in the same block as the target location pointing at an earlier - // statement. - debug_assert_eq!(self.pos.block(), target_block); - if let CursorPosition::After(Location { statement_index, .. }) = self.pos { - debug_assert!(statement_index < target_index); - } - - let first_unapplied_statement = match self.pos { - CursorPosition::AtBlockStart(_) => 0, - CursorPosition::After(Location { statement_index, .. }) => statement_index + 1, - }; - - let block_data = &self.body.basic_blocks()[target_block]; - self.results.borrow().analysis.apply_partial_block_effect( - &mut self.state, - target_block, - block_data, - first_unapplied_statement..target_index + 1, - ); - - self.pos = CursorPosition::After(target); - self.is_call_return_effect_applied = false; - } - - /// Gets the dataflow state at the current location. - pub fn get(&self) -> &BitSet { - &self.state - } -} - -/// A completed dataflow analysis. -pub struct Results<'tcx, A> -where - A: Analysis<'tcx>, -{ - analysis: A, - entry_sets: IndexVec>, -} - -/// All information required to iterate a dataflow analysis to fixpoint. -pub struct Engine<'a, 'tcx, A> -where - A: Analysis<'tcx>, -{ - analysis: A, - bits_per_block: usize, - tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, - def_id: DefId, - dead_unwinds: &'a BitSet, - entry_sets: IndexVec>, -} - -impl Engine<'a, 'tcx, A> -where - A: Analysis<'tcx>, -{ - pub fn new( - tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, - def_id: DefId, - dead_unwinds: &'a BitSet, - analysis: A, - ) -> Self { - let bits_per_block = analysis.bits_per_block(body); - - let bottom_value_set = if A::BOTTOM_VALUE == true { - BitSet::new_filled(bits_per_block) - } else { - BitSet::new_empty(bits_per_block) - }; - - let mut entry_sets = IndexVec::from_elem(bottom_value_set, body.basic_blocks()); - analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); - - Engine { analysis, bits_per_block, tcx, body, def_id, dead_unwinds, entry_sets } - } - - pub fn iterate_to_fixpoint(mut self) -> Results<'tcx, A> { - let mut temp_state = BitSet::new_empty(self.bits_per_block); - - let mut dirty_queue: WorkQueue = - WorkQueue::with_none(self.body.basic_blocks().len()); - - for (bb, _) in traversal::reverse_postorder(self.body) { - dirty_queue.insert(bb); - } - - // Add blocks that are not reachable from START_BLOCK to the work queue. These blocks will - // be processed after the ones added above. - for bb in self.body.basic_blocks().indices() { - dirty_queue.insert(bb); - } - - while let Some(bb) = dirty_queue.pop() { - let bb_data = &self.body[bb]; - let on_entry = &self.entry_sets[bb]; - - temp_state.overwrite(on_entry); - self.analysis.apply_whole_block_effect(&mut temp_state, bb, bb_data); - - self.propagate_bits_into_graph_successors_of( - &mut temp_state, - (bb, bb_data), - &mut dirty_queue, - ); - } - - let Engine { tcx, body, def_id, analysis, entry_sets, .. } = self; - - let results = Results { analysis, entry_sets }; - - let attrs = tcx.get_attrs(def_id); - if let Some(path) = get_dataflow_graphviz_output_path(tcx, attrs, A::NAME) { - let result = write_dataflow_graphviz_results(body, def_id, &path, &results); - if let Err(e) = result { - warn!("Failed to write dataflow results to {}: {}", path.display(), e); - } - } - - results - } - - fn propagate_bits_into_graph_successors_of( - &mut self, - in_out: &mut BitSet, - (bb, bb_data): (BasicBlock, &'a mir::BasicBlockData<'tcx>), - dirty_list: &mut WorkQueue, - ) { - match bb_data.terminator().kind { - mir::TerminatorKind::Return - | mir::TerminatorKind::Resume - | mir::TerminatorKind::Abort - | mir::TerminatorKind::GeneratorDrop - | mir::TerminatorKind::Unreachable => {} - - mir::TerminatorKind::Goto { target } - | mir::TerminatorKind::Assert { target, cleanup: None, .. } - | mir::TerminatorKind::Yield { resume: target, drop: None, .. } - | mir::TerminatorKind::Drop { target, location: _, unwind: None } - | mir::TerminatorKind::DropAndReplace { target, value: _, location: _, unwind: None } => - { - self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); - } - - mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => { - self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); - self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list); - } - - mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } - | mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } - | mir::TerminatorKind::DropAndReplace { - target, - value: _, - location: _, - unwind: Some(unwind), - } => { - self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); - if !self.dead_unwinds.contains(bb) { - self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); - } - } - - mir::TerminatorKind::SwitchInt { ref targets, .. } => { - for target in targets { - self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list); - } - } - - mir::TerminatorKind::Call { cleanup, ref destination, ref func, ref args, .. } => { - if let Some(unwind) = cleanup { - if !self.dead_unwinds.contains(bb) { - self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); - } - } - - if let Some((ref dest_place, dest_bb)) = *destination { - // N.B.: This must be done *last*, after all other - // propagation, as documented in comment above. - self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place); - self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list); - } - } - - mir::TerminatorKind::FalseEdges { real_target, imaginary_target } => { - self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list); - self.propagate_bits_into_entry_set_for(in_out, imaginary_target, dirty_list); - } - - mir::TerminatorKind::FalseUnwind { real_target, unwind } => { - self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list); - if let Some(unwind) = unwind { - if !self.dead_unwinds.contains(bb) { - self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list); - } - } - } - } - } - - fn propagate_bits_into_entry_set_for( - &mut self, - in_out: &BitSet, - bb: BasicBlock, - dirty_queue: &mut WorkQueue, - ) { - let entry_set = &mut self.entry_sets[bb]; - let set_changed = self.analysis.join(entry_set, &in_out); - if set_changed { - dirty_queue.insert(bb); - } - } -} - -/// Looks for attributes like `#[rustc_mir(borrowck_graphviz_postflow="./path/to/suffix.dot")]` and -/// extracts the path with the given analysis name prepended to the suffix. -/// -/// Returns `None` if no such attribute exists. -fn get_dataflow_graphviz_output_path( - tcx: TyCtxt<'tcx>, - attrs: ty::Attributes<'tcx>, - analysis: &str, -) -> Option { - let mut rustc_mir_attrs = attrs - .into_iter() - .filter(|attr| attr.check_name(sym::rustc_mir)) - .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); - - let borrowck_graphviz_postflow = - rustc_mir_attrs.find(|attr| attr.check_name(sym::borrowck_graphviz_postflow))?; - - let path_and_suffix = match borrowck_graphviz_postflow.value_str() { - Some(p) => p, - None => { - tcx.sess.span_err( - borrowck_graphviz_postflow.span(), - "borrowck_graphviz_postflow requires a path", - ); - - return None; - } - }; - - // Change "path/suffix.dot" to "path/analysis_name_suffix.dot" - let mut ret = PathBuf::from(path_and_suffix.to_string()); - let suffix = ret.file_name().unwrap(); - - let mut file_name: OsString = analysis.into(); - file_name.push("_"); - file_name.push(suffix); - ret.set_file_name(file_name); - - Some(ret) -} - -fn write_dataflow_graphviz_results>( - body: &mir::Body<'tcx>, - def_id: DefId, - path: &Path, - results: &Results<'tcx, A>, -) -> io::Result<()> { - debug!("printing dataflow results for {:?} to {}", def_id, path.display()); - - let mut buf = Vec::new(); - let graphviz = graphviz::Formatter::new(body, def_id, results); - - dot::render(&graphviz, &mut buf)?; - fs::write(path, buf) -} From 355cfcdf433c47bfb2365752d33f2a24dfc6e78f Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 11 Nov 2019 11:50:27 -0800 Subject: [PATCH 0342/1253] Use unified dataflow framework in `check_consts` --- .../transform/check_consts/resolver.rs | 7 ++++++- .../transform/check_consts/validation.rs | 15 ++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index c445568dd2a9b..2cd2495eef8a2 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -158,7 +158,7 @@ impl old_dataflow::BottomValue for FlowSensitiveAnalysis<'_, '_, '_, Q> { const BOTTOM_VALUE: bool = false; } -impl dataflow::Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> +impl dataflow::AnalysisDomain<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> where Q: Qualif, { @@ -173,7 +173,12 @@ where fn initialize_start_block(&self, _body: &mir::Body<'tcx>, state: &mut BitSet) { self.transfer_function(state).initialize_state(); } +} +impl dataflow::Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> +where + Q: Qualif, +{ fn apply_statement_effect( &self, state: &mut BitSet, diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 10a4b7d92b764..243077a7c2fbe 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -33,11 +33,10 @@ struct QualifCursor<'a, 'mir, 'tcx, Q: Qualif> { } impl QualifCursor<'a, 'mir, 'tcx, Q> { - pub fn new(q: Q, item: &'a Item<'mir, 'tcx>, dead_unwinds: &BitSet) -> Self { + pub fn new(q: Q, item: &'a Item<'mir, 'tcx>) -> Self { let analysis = FlowSensitiveAnalysis::new(q, item); - let results = - dataflow::Engine::new(item.tcx, &item.body, item.def_id, dead_unwinds, analysis) - .iterate_to_fixpoint(); + let results = dataflow::Engine::new_generic(item.tcx, &item.body, item.def_id, analysis) + .iterate_to_fixpoint(); let cursor = dataflow::ResultsCursor::new(*item.body, results); let mut in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len()); @@ -146,12 +145,10 @@ impl Deref for Validator<'_, 'mir, 'tcx> { impl Validator<'a, 'mir, 'tcx> { pub fn new(item: &'a Item<'mir, 'tcx>) -> Self { - let dead_unwinds = BitSet::new_empty(item.body.basic_blocks().len()); - - let needs_drop = QualifCursor::new(NeedsDrop, item, &dead_unwinds); - - let has_mut_interior = QualifCursor::new(HasMutInterior, item, &dead_unwinds); + let needs_drop = QualifCursor::new(NeedsDrop, item); + let has_mut_interior = QualifCursor::new(HasMutInterior, item); + let dead_unwinds = BitSet::new_empty(item.body.basic_blocks().len()); let indirectly_mutable = old_dataflow::do_dataflow( item.tcx, &*item.body, From 064f8885d5e1d38673783d626d9d3fc1b7b909f4 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:40:19 -0500 Subject: [PATCH 0343/1253] Add unicode table generator --- .gitignore | 9 +- Cargo.lock | 17 ++ Cargo.toml | 1 + src/tools/unicode-table-generator/Cargo.toml | 10 + .../src/case_mapping.rs | 62 +++++ src/tools/unicode-table-generator/src/main.rs | 261 ++++++++++++++++++ .../src/raw_emitter.rs | 170 ++++++++++++ .../src/unicode_download.rs | 42 +++ 8 files changed, 564 insertions(+), 8 deletions(-) create mode 100644 src/tools/unicode-table-generator/Cargo.toml create mode 100644 src/tools/unicode-table-generator/src/case_mapping.rs create mode 100644 src/tools/unicode-table-generator/src/main.rs create mode 100644 src/tools/unicode-table-generator/src/raw_emitter.rs create mode 100644 src/tools/unicode-table-generator/src/unicode_download.rs diff --git a/.gitignore b/.gitignore index 1428ee6c9bc23..d9761ce40927c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,14 +34,7 @@ __pycache__/ # Created by default with `src/ci/docker/run.sh`: /obj/ /rustllvm/ -/src/libcore/unicode/DerivedCoreProperties.txt -/src/libcore/unicode/DerivedNormalizationProps.txt -/src/libcore/unicode/PropList.txt -/src/libcore/unicode/ReadMe.txt -/src/libcore/unicode/Scripts.txt -/src/libcore/unicode/SpecialCasing.txt -/src/libcore/unicode/UnicodeData.txt -/src/libcore/unicode/downloaded +/unicode-downloads /target/ # Generated by compiletest for incremental: /tmp/ diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..3f1058645d264 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4930,6 +4930,16 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +[[package]] +name = "ucd-parse" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6b52bf4da6512f0f07785a04769222e50d29639e7ecd016b7806fd2de306b4" +dependencies = [ + "lazy_static 1.3.0", + "regex", +] + [[package]] name = "ucd-trie" version = "0.1.1" @@ -4951,6 +4961,13 @@ dependencies = [ "version_check 0.1.5", ] +[[package]] +name = "unicode-bdd" +version = "0.1.0" +dependencies = [ + "ucd-parse", +] + [[package]] name = "unicode-bidi" version = "0.3.4" diff --git a/Cargo.toml b/Cargo.toml index a242f090fbc07..9d5c27b96df5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "src/tools/rustfmt", "src/tools/miri", "src/tools/rustdoc-themes", + "src/tools/unicode-table-generator", ] exclude = [ "build", diff --git a/src/tools/unicode-table-generator/Cargo.toml b/src/tools/unicode-table-generator/Cargo.toml new file mode 100644 index 0000000000000..92344cdfc89ee --- /dev/null +++ b/src/tools/unicode-table-generator/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "unicode-bdd" +version = "0.1.0" +authors = ["Mark Rousskov "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ucd-parse = "0.1.3" diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs new file mode 100644 index 0000000000000..01f199c213e02 --- /dev/null +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -0,0 +1,62 @@ +use crate::{fmt_list, UnicodeData}; +use std::fmt; + +pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { + let mut file = String::new(); + + file.push_str(HEADER.trim_start()); + + let decl_type = "&[(char, [char; 3])]"; + + file.push_str(&format!( + "static LOWERCASE_TABLE: {} = &[{}];", + decl_type, + fmt_list(data.to_lower.iter().map(to_mapping)) + )); + file.push_str("\n\n"); + file.push_str(&format!( + "static UPPERCASE_TABLE: {} = &[{}];", + decl_type, + fmt_list(data.to_upper.iter().map(to_mapping)) + )); + file +} + +fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) { + ( + CharEscape(std::char::from_u32(*key).unwrap()), + [ + CharEscape(std::char::from_u32(*a).unwrap()), + CharEscape(std::char::from_u32(*b).unwrap()), + CharEscape(std::char::from_u32(*c).unwrap()), + ], + ) +} + +struct CharEscape(char); + +impl fmt::Debug for CharEscape { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'{}'", self.0.escape_default()) + } +} + +static HEADER: &str = " +pub fn to_lower(c: char) -> [char; 3] { + match bsearch_case_table(c, LOWERCASE_TABLE) { + None => [c, '\\0', '\\0'], + Some(index) => LOWERCASE_TABLE[index].1, + } +} + +pub fn to_upper(c: char) -> [char; 3] { + match bsearch_case_table(c, UPPERCASE_TABLE) { + None => [c, '\\0', '\\0'], + Some(index) => UPPERCASE_TABLE[index].1, + } +} + +fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { + table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() +} +"; diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs new file mode 100644 index 0000000000000..be8508e3973a2 --- /dev/null +++ b/src/tools/unicode-table-generator/src/main.rs @@ -0,0 +1,261 @@ +use std::collections::{BTreeMap, HashMap}; +use std::ops::Range; +use ucd_parse::Codepoints; + +mod case_mapping; +mod raw_emitter; +mod unicode_download; + +use raw_emitter::{emit_codepoints, RawEmitter}; + +static PROPERTIES: &[&str] = &[ + "Alphabetic", + "Lowercase", + "Uppercase", + "Cased", + "Case_Ignorable", + "Grapheme_Extend", + "White_Space", + "Cc", + "N", +]; + +struct UnicodeData { + ranges: Vec<(&'static str, Vec>)>, + to_upper: BTreeMap, + to_lower: BTreeMap, +} + +fn to_mapping(origin: u32, codepoints: Vec) -> Option<(u32, u32, u32)> { + let mut a = None; + let mut b = None; + let mut c = None; + + for codepoint in codepoints { + if origin == codepoint.value() { + return None; + } + + if a.is_none() { + a = Some(codepoint.value()); + } else if b.is_none() { + b = Some(codepoint.value()); + } else if c.is_none() { + c = Some(codepoint.value()); + } else { + panic!("more than 3 mapped codepoints") + } + } + + Some((a.unwrap(), b.unwrap_or(0), c.unwrap_or(0))) +} + +static UNICODE_DIRECTORY: &str = "unicode-downloads"; + +fn load_data() -> UnicodeData { + unicode_download::fetch_latest(); + + let mut properties = HashMap::new(); + for row in ucd_parse::parse::<_, ucd_parse::CoreProperty>(&UNICODE_DIRECTORY).unwrap() { + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == row.property.as_str()) { + properties.entry(*name).or_insert_with(Vec::new).push(row.codepoints); + } + } + for row in ucd_parse::parse::<_, ucd_parse::Property>(&UNICODE_DIRECTORY).unwrap() { + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == row.property.as_str()) { + properties.entry(*name).or_insert_with(Vec::new).push(row.codepoints); + } + } + + let mut to_lower = BTreeMap::new(); + let mut to_upper = BTreeMap::new(); + for row in ucd_parse::UnicodeDataExpander::new( + ucd_parse::parse::<_, ucd_parse::UnicodeData>(&UNICODE_DIRECTORY).unwrap(), + ) { + let general_category = if ["Nd", "Nl", "No"].contains(&row.general_category.as_str()) { + "N" + } else { + row.general_category.as_str() + }; + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == general_category) { + properties + .entry(*name) + .or_insert_with(Vec::new) + .push(Codepoints::Single(row.codepoint)); + } + + if let Some(mapped) = row.simple_lowercase_mapping { + if mapped != row.codepoint { + to_lower.insert(row.codepoint.value(), (mapped.value(), 0, 0)); + } + } + if let Some(mapped) = row.simple_uppercase_mapping { + if mapped != row.codepoint { + to_upper.insert(row.codepoint.value(), (mapped.value(), 0, 0)); + } + } + } + + for row in ucd_parse::parse::<_, ucd_parse::SpecialCaseMapping>(&UNICODE_DIRECTORY).unwrap() { + if !row.conditions.is_empty() { + // Skip conditional case mappings + continue; + } + + let key = row.codepoint.value(); + if let Some(lower) = to_mapping(key, row.lowercase) { + to_lower.insert(key, lower); + } + if let Some(upper) = to_mapping(key, row.uppercase) { + to_upper.insert(key, upper); + } + } + + let mut properties: HashMap<&'static str, Vec>> = properties + .into_iter() + .map(|(k, v)| { + ( + k, + v.into_iter() + .flat_map(|codepoints| match codepoints { + Codepoints::Single(c) => c + .scalar() + .map(|ch| (ch as u32..ch as u32 + 1)) + .into_iter() + .collect::>(), + Codepoints::Range(c) => c + .into_iter() + .flat_map(|c| c.scalar().map(|ch| (ch as u32..ch as u32 + 1))) + .collect::>(), + }) + .collect::>>(), + ) + }) + .collect(); + + for ranges in properties.values_mut() { + merge_ranges(ranges); + } + + let mut properties = properties.into_iter().collect::>(); + properties.sort_by_key(|p| p.0); + UnicodeData { ranges: properties, to_lower, to_upper } +} + +fn main() { + let write_location = std::env::args().nth(1).unwrap_or_else(|| { + eprintln!("Must provide path to write unicode tables to"); + eprintln!( + "e.g. {} src/libcore/unicode/unicode_data.rs", + std::env::args().nth(0).unwrap_or_default() + ); + std::process::exit(1); + }); + + let unicode_data = load_data(); + let ranges_by_property = &unicode_data.ranges; + + let mut total_bytes = 0; + let mut modules = Vec::new(); + for (property, ranges) in ranges_by_property { + let datapoints = ranges.iter().map(|r| r.end - r.start).sum::(); + let mut emitter = RawEmitter::new(); + emit_codepoints(&mut emitter, &ranges); + + modules.push((property.to_lowercase().to_string(), emitter.file)); + println!("{:15}: {} bytes, {} codepoints", property, emitter.bytes_used, datapoints,); + total_bytes += emitter.bytes_used; + } + + let mut table_file = String::new(); + + table_file.push_str( + "///! This file is generated by src/tools/unicode-table-generator; do not edit manually!\n", + ); + + table_file.push_str("use super::range_search;\n\n"); + + table_file.push_str(&version()); + + table_file.push('\n'); + + modules.push((String::from("conversions"), case_mapping::generate_case_mapping(&unicode_data))); + + for (name, contents) in modules { + table_file.push_str("#[rustfmt::skip]\n"); + table_file.push_str(&format!("pub mod {} {{\n", name)); + for line in contents.lines() { + if !line.trim().is_empty() { + table_file.push_str(" "); + table_file.push_str(&line); + } + table_file.push('\n'); + } + table_file.push_str("}\n\n"); + } + + std::fs::write(&write_location, format!("{}\n", table_file.trim_end())).unwrap(); + + println!("Total table sizes: {} bytes", total_bytes); +} + +fn version() -> String { + let mut out = String::new(); + out.push_str("pub const UNICODE_VERSION: (u32, u32, u32) = "); + + let readme = + std::fs::read_to_string(std::path::Path::new(UNICODE_DIRECTORY).join("ReadMe.txt")) + .unwrap(); + + let prefix = "for Version "; + let start = readme.find(prefix).unwrap() + prefix.len(); + let end = readme.find(" of the Unicode Standard.").unwrap(); + let version = + readme[start..end].split('.').map(|v| v.parse::().expect(&v)).collect::>(); + let [major, minor, micro] = [version[0], version[1], version[2]]; + + out.push_str(&format!("({}, {}, {});\n", major, minor, micro)); + out +} + +fn fmt_list(values: impl IntoIterator) -> String { + let pieces = values.into_iter().map(|b| format!("{:?}, ", b)).collect::>(); + let mut out = String::new(); + let mut line = format!("\n "); + for piece in pieces { + if line.len() + piece.len() < 98 { + line.push_str(&piece); + } else { + out.push_str(line.trim_end()); + out.push('\n'); + line = format!(" {}", piece); + } + } + out.push_str(line.trim_end()); + out.push('\n'); + out +} + +fn merge_ranges(ranges: &mut Vec>) { + loop { + let mut new_ranges = Vec::new(); + let mut idx_iter = 0..(ranges.len() - 1); + while let Some(idx) = idx_iter.next() { + let cur = ranges[idx].clone(); + let next = ranges[idx + 1].clone(); + if cur.end == next.start { + let _ = idx_iter.next(); // skip next as we're merging it in + new_ranges.push(cur.start..next.end); + } else { + new_ranges.push(cur); + } + } + new_ranges.push(ranges.last().unwrap().clone()); + if new_ranges.len() == ranges.len() { + *ranges = new_ranges; + break; + } else { + *ranges = new_ranges; + } + } +} diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs new file mode 100644 index 0000000000000..3e60ce13f9223 --- /dev/null +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -0,0 +1,170 @@ +//! This implements the core logic of the compression scheme used to compactly +//! encode the Unicode character classes. +//! +//! The primary idea is that we 'flatten' the Unicode ranges into an enormous +//! bitset. To represent any arbitrary codepoint in a raw bitset, we would need +//! over 17 kilobytes of data per character set -- way too much for our +//! purposes. +//! +//! We have two primary goals with the encoding: we want to be compact, because +//! these tables often end up in ~every Rust program (especially the +//! grapheme_extend table, used for str debugging), including those for embedded +//! targets (where space is important). We also want to be relatively fast, +//! though this is more of a nice to have rather than a key design constraint. +//! In practice, due to modern processor design these two are closely related. +//! +//! The encoding scheme here compresses the bitset by first deduplicating the +//! "words" (64 bits on all platforms). In practice very few words are present +//! in most data sets. +//! +//! This gives us an array that maps `u8 -> word` (if we ever went beyond 256 +//! words, we could go to u16 -> word or have some dual compression scheme +//! mapping into two separate sets; currently this is not dealt with). +//! +//! With that scheme, we now have a single byte for every 64 codepoints. We +//! further group these by 16 (arbitrarily chosen), and again deduplicate and +//! store in an array (u8 -> [u8; 16]). +//! +//! The indices into this array represent ranges of 64*16 = 1024 codepoints. +//! +//! This already reduces the top-level array to at most 1,086 bytes, but in +//! practice we usually can encode in far fewer (the first couple Unicode planes +//! are dense). +//! +//! The last byte of this top-level array is pulled out to a separate static +//! and trailing zeros are dropped; this is simply because grapheme_extend and +//! case_ignorable have a single entry in the 896th entry, so this shrinks them +//! down considerably. + +use crate::fmt_list; +use std::collections::{BTreeSet, HashMap}; +use std::convert::TryFrom; +use std::fmt::Write; +use std::ops::Range; + +pub struct RawEmitter { + pub file: String, + pub bytes_used: usize, +} + +impl RawEmitter { + pub fn new() -> RawEmitter { + RawEmitter { file: String::new(), bytes_used: 0 } + } + + fn blank_line(&mut self) { + if self.file.is_empty() || self.file.ends_with("\n\n") { + return; + } + writeln!(&mut self.file, "").unwrap(); + } + + fn emit_bitset(&mut self, words: &[u64]) { + let unique_words = + words.iter().cloned().collect::>().into_iter().collect::>(); + if unique_words.len() > u8::max_value() as usize { + panic!("cannot pack {} into 8 bits", unique_words.len()); + } + + let word_indices = unique_words + .iter() + .cloned() + .enumerate() + .map(|(idx, word)| (word, u8::try_from(idx).unwrap())) + .collect::>(); + + let mut idx = words.iter().map(|w| word_indices[w]).collect::>(); + let chunk_length = 16; + for _ in 0..(chunk_length - (idx.len() % chunk_length)) { + assert_eq!(unique_words[0], 0, "first word is all zeros"); + // pad out bitset index with zero words so we have all chunks of 16 + idx.push(0); + } + + let mut chunks = BTreeSet::new(); + for chunk in idx.chunks(chunk_length) { + chunks.insert(chunk); + } + let chunk_map = chunks + .clone() + .into_iter() + .enumerate() + .map(|(idx, chunk)| (chunk, idx)) + .collect::>(); + let mut chunk_indices = Vec::new(); + for chunk in idx.chunks(chunk_length) { + chunk_indices.push(chunk_map[chunk]); + } + writeln!( + &mut self.file, + "static BITSET_LAST_CHUNK_MAP: (u16, u8) = ({}, {});", + chunk_indices.len() - 1, + chunk_indices.pop().unwrap(), + ) + .unwrap(); + self.bytes_used += 3; + // Strip out the empty pieces, presuming our above pop() made us now + // have some trailing zeros. + assert_eq!(unique_words[0], 0, "first word is all zeros"); + while let Some(0) = chunk_indices.last() { + chunk_indices.pop(); + } + writeln!( + &mut self.file, + "static BITSET_CHUNKS_MAP: [u8; {}] = [{}];", + chunk_indices.len(), + fmt_list(&chunk_indices), + ) + .unwrap(); + self.bytes_used += chunk_indices.len(); + writeln!( + &mut self.file, + "static BITSET_INDEX_CHUNKS: [[u8; 16]; {}] = [{}];", + chunks.len(), + fmt_list(chunks.iter()), + ) + .unwrap(); + self.bytes_used += 16 * chunks.len(); + writeln!( + &mut self.file, + "static BITSET: [u64; {}] = [{}];", + unique_words.len(), + fmt_list(&unique_words), + ) + .unwrap(); + self.bytes_used += 8 * unique_words.len(); + } + + pub fn emit_lookup(&mut self) { + writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " super::range_search(",).unwrap(); + writeln!(&mut self.file, " c as u32,").unwrap(); + writeln!(&mut self.file, " &BITSET_CHUNKS_MAP,").unwrap(); + writeln!(&mut self.file, " BITSET_LAST_CHUNK_MAP,").unwrap(); + writeln!(&mut self.file, " &BITSET_INDEX_CHUNKS,").unwrap(); + writeln!(&mut self.file, " &BITSET,").unwrap(); + writeln!(&mut self.file, " )").unwrap(); + writeln!(&mut self.file, "}}").unwrap(); + } +} + +pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { + emitter.blank_line(); + + let last_code_point = ranges.last().unwrap().end; + // bitset for every bit in the codepoint range + // + // + 2 to ensure an all zero word to use for padding + let mut buckets = vec![0u64; (last_code_point as usize / 64) + 2]; + for range in ranges { + for codepoint in range.clone() { + let bucket = codepoint as usize / 64; + let bit = codepoint as u64 % 64; + buckets[bucket] |= 1 << bit; + } + } + + emitter.emit_bitset(&buckets); + emitter.blank_line(); + emitter.emit_lookup(); +} diff --git a/src/tools/unicode-table-generator/src/unicode_download.rs b/src/tools/unicode-table-generator/src/unicode_download.rs new file mode 100644 index 0000000000000..3f6de9ea3bbd7 --- /dev/null +++ b/src/tools/unicode-table-generator/src/unicode_download.rs @@ -0,0 +1,42 @@ +use crate::UNICODE_DIRECTORY; +use std::path::Path; +use std::process::Command; + +static URL_PREFIX: &str = "https://www.unicode.org/Public/UCD/latest/ucd/"; + +static README: &str = "ReadMe.txt"; + +static RESOURCES: &[&str] = + &["DerivedCoreProperties.txt", "PropList.txt", "UnicodeData.txt", "SpecialCasing.txt"]; + +pub fn fetch_latest() { + let directory = Path::new(UNICODE_DIRECTORY); + if let Err(e) = std::fs::create_dir_all(directory) { + if e.kind() != std::io::ErrorKind::AlreadyExists { + panic!("Failed to create {:?}: {}", UNICODE_DIRECTORY, e); + } + } + let output = Command::new("curl").arg(URL_PREFIX.to_owned() + README).output().unwrap(); + if !output.status.success() { + panic!( + "Failed to run curl to fetch readme: stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + let current = std::fs::read_to_string(directory.join(README)).unwrap_or_default(); + if current.as_bytes() != &output.stdout[..] { + std::fs::write(directory.join(README), output.stdout).unwrap(); + } + + for resource in RESOURCES { + let output = Command::new("curl").arg(URL_PREFIX.to_owned() + resource).output().unwrap(); + if !output.status.success() { + panic!( + "Failed to run curl to fetch {}: stderr: {}", + resource, + String::from_utf8_lossy(&output.stderr) + ); + } + std::fs::write(directory.join(resource), output.stdout).unwrap(); + } +} From 40ad8778513185c3597e99170371181d1e1d694c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:58:50 -0500 Subject: [PATCH 0344/1253] Add support code for new unicode_data module --- src/libcore/unicode/mod.rs | 54 ++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/libcore/unicode/mod.rs b/src/libcore/unicode/mod.rs index e424174f55469..b6eaf06aa7f63 100644 --- a/src/libcore/unicode/mod.rs +++ b/src/libcore/unicode/mod.rs @@ -1,15 +1,59 @@ #![unstable(feature = "unicode_internals", issue = "none")] #![allow(missing_docs)] -mod bool_trie; pub(crate) mod printable; -pub(crate) mod tables; +mod unicode_data; pub(crate) mod version; +use version::UnicodeVersion; + +/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of +/// `char` and `str` methods are based on. +#[unstable(feature = "unicode_version", issue = "49726")] +pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion { + major: unicode_data::UNICODE_VERSION.0, + minor: unicode_data::UNICODE_VERSION.1, + micro: unicode_data::UNICODE_VERSION.2, + _priv: (), +}; + // For use in liballoc, not re-exported in libstd. pub mod derived_property { - pub use crate::unicode::tables::derived_property::{Case_Ignorable, Cased}; + pub use super::{Case_Ignorable, Cased}; } -pub mod conversions { - pub use crate::unicode::tables::conversions::{to_lower, to_upper}; + +pub use unicode_data::alphabetic::lookup as Alphabetic; +pub use unicode_data::case_ignorable::lookup as Case_Ignorable; +pub use unicode_data::cased::lookup as Cased; +pub use unicode_data::cc::lookup as Cc; +pub use unicode_data::conversions; +pub use unicode_data::grapheme_extend::lookup as Grapheme_Extend; +pub use unicode_data::lowercase::lookup as Lowercase; +pub use unicode_data::n::lookup as N; +pub use unicode_data::uppercase::lookup as Uppercase; +pub use unicode_data::white_space::lookup as White_Space; + +#[inline(always)] +fn range_search( + needle: u32, + chunk_idx_map: &[u8; N], + (last_chunk_idx, last_chunk_mapping): (u16, u8), + bitset_chunk_idx: &[[u8; 16]; N1], + bitset: &[u64; N2], +) -> bool { + let bucket_idx = (needle / 64) as usize; + let chunk_map_idx = bucket_idx / 16; + let chunk_piece = bucket_idx % 16; + let chunk_idx = if chunk_map_idx >= N { + if chunk_map_idx == last_chunk_idx as usize { + last_chunk_mapping + } else { + return false; + } + } else { + chunk_idx_map[chunk_map_idx] + }; + let idx = bitset_chunk_idx[(chunk_idx as usize)][chunk_piece]; + let word = bitset[(idx as usize)]; + (word & (1 << (needle % 64) as u64)) != 0 } From efcda047397262f403df54d9f5e569dd32704168 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:59:33 -0500 Subject: [PATCH 0345/1253] Replace old tables with new unicode data --- src/libcore/char/methods.rs | 16 +- src/libcore/char/mod.rs | 4 +- src/libcore/unicode/bool_trie.rs | 66 - src/libcore/unicode/tables.rs | 2235 ------------------------- src/libcore/unicode/unicode.py | 878 ---------- src/libcore/unicode/unicode_data.rs | 2343 +++++++++++++++++++++++++++ 6 files changed, 2353 insertions(+), 3189 deletions(-) delete mode 100644 src/libcore/unicode/bool_trie.rs delete mode 100644 src/libcore/unicode/tables.rs delete mode 100755 src/libcore/unicode/unicode.py create mode 100644 src/libcore/unicode/unicode_data.rs diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs index fe5d16862a6a6..c341bb552a1ea 100644 --- a/src/libcore/char/methods.rs +++ b/src/libcore/char/methods.rs @@ -3,7 +3,7 @@ use crate::slice; use crate::str::from_utf8_unchecked_mut; use crate::unicode::printable::is_printable; -use crate::unicode::tables::{conversions, derived_property, general_category, property}; +use crate::unicode::{self, conversions}; use super::*; @@ -552,7 +552,7 @@ impl char { pub fn is_alphabetic(self) -> bool { match self { 'a'..='z' | 'A'..='Z' => true, - c => c > '\x7f' && derived_property::Alphabetic(c), + c => c > '\x7f' && unicode::Alphabetic(c), } } @@ -583,7 +583,7 @@ impl char { pub fn is_lowercase(self) -> bool { match self { 'a'..='z' => true, - c => c > '\x7f' && derived_property::Lowercase(c), + c => c > '\x7f' && unicode::Lowercase(c), } } @@ -614,7 +614,7 @@ impl char { pub fn is_uppercase(self) -> bool { match self { 'A'..='Z' => true, - c => c > '\x7f' && derived_property::Uppercase(c), + c => c > '\x7f' && unicode::Uppercase(c), } } @@ -642,7 +642,7 @@ impl char { pub fn is_whitespace(self) -> bool { match self { ' ' | '\x09'..='\x0d' => true, - c => c > '\x7f' && property::White_Space(c), + c => c > '\x7f' && unicode::White_Space(c), } } @@ -693,7 +693,7 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_control(self) -> bool { - general_category::Cc(self) + unicode::Cc(self) } /// Returns `true` if this `char` has the `Grapheme_Extend` property. @@ -707,7 +707,7 @@ impl char { /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - derived_property::Grapheme_Extend(self) + unicode::Grapheme_Extend(self) } /// Returns `true` if this `char` has one of the general categories for numbers. @@ -739,7 +739,7 @@ impl char { pub fn is_numeric(self) -> bool { match self { '0'..='9' => true, - c => c > '\x7f' && general_category::N(c), + c => c > '\x7f' && unicode::N(c), } } diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index a655ee6e7e32a..cf5576e549cdf 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -37,9 +37,9 @@ pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error}; // unstable re-exports #[unstable(feature = "unicode_version", issue = "49726")] -pub use crate::unicode::tables::UNICODE_VERSION; -#[unstable(feature = "unicode_version", issue = "49726")] pub use crate::unicode::version::UnicodeVersion; +#[unstable(feature = "unicode_version", issue = "49726")] +pub use crate::unicode::UNICODE_VERSION; use crate::fmt::{self, Write}; use crate::iter::FusedIterator; diff --git a/src/libcore/unicode/bool_trie.rs b/src/libcore/unicode/bool_trie.rs deleted file mode 100644 index b7fba88a540f9..0000000000000 --- a/src/libcore/unicode/bool_trie.rs +++ /dev/null @@ -1,66 +0,0 @@ -/// BoolTrie is a trie for representing a set of Unicode codepoints. It is -/// implemented with postfix compression (sharing of identical child nodes), -/// which gives both compact size and fast lookup. -/// -/// The space of Unicode codepoints is divided into 3 subareas, each -/// represented by a trie with different depth. In the first (0..0x800), there -/// is no trie structure at all; each u64 entry corresponds to a bitvector -/// effectively holding 64 bool values. -/// -/// In the second (0x800..0x10000), each child of the root node represents a -/// 64-wide subrange, but instead of storing the full 64-bit value of the leaf, -/// the trie stores an 8-bit index into a shared table of leaf values. This -/// exploits the fact that in reasonable sets, many such leaves can be shared. -/// -/// In the third (0x10000..0x110000), each child of the root node represents a -/// 4096-wide subrange, and the trie stores an 8-bit index into a 64-byte slice -/// of a child tree. Each of these 64 bytes represents an index into the table -/// of shared 64-bit leaf values. This exploits the sparse structure in the -/// non-BMP range of most Unicode sets. -pub struct BoolTrie { - // 0..0x800 (corresponding to 1 and 2 byte utf-8 sequences) - pub r1: [u64; 32], // leaves - - // 0x800..0x10000 (corresponding to 3 byte utf-8 sequences) - pub r2: [u8; 992], // first level - pub r3: &'static [u64], // leaves - - // 0x10000..0x110000 (corresponding to 4 byte utf-8 sequences) - pub r4: [u8; 256], // first level - pub r5: &'static [u8], // second level - pub r6: &'static [u64], // leaves -} -impl BoolTrie { - pub fn lookup(&self, c: char) -> bool { - let c = c as u32; - if c < 0x800 { - trie_range_leaf(c, self.r1[(c >> 6) as usize]) - } else if c < 0x10000 { - let child = self.r2[(c >> 6) as usize - 0x20]; - trie_range_leaf(c, self.r3[child as usize]) - } else { - let child = self.r4[(c >> 12) as usize - 0x10]; - let leaf = self.r5[((child as usize) << 6) + ((c >> 6) as usize & 0x3f)]; - trie_range_leaf(c, self.r6[leaf as usize]) - } - } -} - -pub struct SmallBoolTrie { - pub(crate) r1: &'static [u8], // first level - pub(crate) r2: &'static [u64], // leaves -} - -impl SmallBoolTrie { - pub fn lookup(&self, c: char) -> bool { - let c = c as u32; - match self.r1.get((c >> 6) as usize) { - Some(&child) => trie_range_leaf(c, self.r2[child as usize]), - None => false, - } - } -} - -fn trie_range_leaf(c: u32, bitmap_chunk: u64) -> bool { - ((bitmap_chunk >> (c & 63)) & 1) != 0 -} diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs deleted file mode 100644 index 3fa125e8fea15..0000000000000 --- a/src/libcore/unicode/tables.rs +++ /dev/null @@ -1,2235 +0,0 @@ -// NOTE: The following code was generated by "./unicode.py", do not edit directly - -#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] - -use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; -use crate::unicode::version::UnicodeVersion; - -/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of -/// `char` and `str` methods are based on. -#[unstable(feature = "unicode_version", issue = "49726")] -pub const UNICODE_VERSION: UnicodeVersion = - UnicodeVersion { major: 12, minor: 1, micro: 0, _priv: () }; -pub(crate) mod general_category { - #[rustfmt::skip] - const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie { - r1: &[ - 0, 1, 0 - ], - r2: &[ - 0x00000000ffffffff, 0x8000000000000000 - ], - }; - - pub fn Cc(c: char) -> bool { - Cc_table.lookup(c) - } - - #[rustfmt::skip] - const N_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x000003ff00000000, 0x0000000000000000, 0x03ff000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x00000000000003ff - ], - r2: [ - 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0, 1, 0, 6, 0, 1, 0, 7, 0, 7, 8, - 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 0, 0, 0, 12, 7, 0, 0, 0, 0, 13, 0, 14, 0, 0, 15, 0, 0, 7, 16, 0, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 9, 0, 0, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 27, 0, 28, - 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, - 0, 0, 1, 0, 0, 0, 0, 31, 0, 0, 7, 9, 0, 0, 32, 0, 7, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0x0000ffc000000000, 0x03f0ffc000000000, 0x00fcffc000000000, - 0x0007ffc000000000, 0x7f00ffc000000000, 0x01ffffc07f000000, 0x0000000003ff0000, - 0x000fffff00000000, 0x00000000000003ff, 0x1ffffe0000000000, 0x0001c00000000000, - 0x03ff03ff00000000, 0x000000000000ffc0, 0x0000000007ff0000, 0x0000000003ff03ff, - 0x03ff000000000000, 0x03f1000000000000, 0xffffffffffff0000, 0x00000000000003e7, - 0xffffffff00000000, 0x000000000fffffff, 0xfffffc0000000000, 0xffc0000000000000, - 0x00000000000fffff, 0x2000000000000000, 0x070003fe00000080, 0x00000000003c0000, - 0x000003ff00000000, 0x00000000fffeff00, 0xfffe0000000003ff, 0x003f000000000000, - 0x03ff000003ff0000 - ], - r4: [ - 0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - ], - r5: &[ - 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 10, 11, 12, 0, 13, 14, 0, 15, 16, 17, 0, 18, 19, 0, 0, 0, 0, 20, 21, 0, - 0, 0, 0, 22, 0, 0, 23, 24, 0, 0, 0, 25, 0, 21, 26, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, - 28, 0, 28, 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 21, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 28, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 - ], - r6: &[ - 0x0000000000000000, 0x000fffffffffff80, 0x01ffffffffffffff, 0x0000000000000c00, - 0x0ffffffe00000000, 0x0000000f00000000, 0x0000000000000402, 0x00000000003e0000, - 0x000003ff00000000, 0xfe000000ff000000, 0x0000ff8000000000, 0xf800000000000000, - 0x000000000fc00000, 0x3000000000000000, 0xfffffffffffcffff, 0x60000000000001ff, - 0x00000000e0000000, 0x0000f80000000000, 0xff000000ff000000, 0x0000fe0000000000, - 0xfc00000000000000, 0x03ff000000000000, 0x7fffffff00000000, 0x0000007fe0000000, - 0x00000000001e0000, 0x0000fffffffc0000, 0xffc0000000000000, 0x001ffffe03ff0000, - 0x0000000003ff0000, 0x00000000000003ff, 0x0fff000000000000, 0x0007ffff00000000, - 0x00001fffffff0000, 0x00000000001fffff, 0xffffffffffffffff, 0x00007fffffffffff, - 0x00000003fbff0000, 0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000, - 0xffffffffffffc000, 0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff, - 0x3fffbffffffffffe, 0x0000000000001fff - ], - }; - - pub fn N(c: char) -> bool { - N_table.lookup(c) - } -} - -pub(crate) mod derived_property { - #[rustfmt::skip] - const Alphabetic_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3, - 0x0000000000000000, 0xbcdf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff, - 0xfffeffffffffffff, 0xffffffff027fffff, 0xbfff0000000001ff, 0x000787ffffff00b6, - 0xffffffff07ff0000, 0xffffc000feffffff, 0xffffffffffffffff, 0x9c00e1fe1fefffff, - 0xffffffffffff0000, 0xffffffffffffe000, 0x0003ffffffffffff, 0x043007fffffffc00 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 67, 68, 69, 70, 36, 36, 36, 71, 36, 36, - 36, 36, 72, 73, 74, 75, 31, 76, 77, 31, 78, 79, 80, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 81, 82, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 84, 36, 85, 86, 87, 88, 89, 90, 31, 31, 31, - 31, 31, 31, 31, 91, 44, 92, 93, 94, 36, 95, 96, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 55, 31, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 97, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 98, 99, 36, 36, 36, 36, 100, 101, 36, 97, 102, 36, 103, - 104, 105, 106, 36, 107, 108, 109, 110, 111, 67, 112, 113, 114, 115, 116, 36, 117, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 118, 119, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 33, 127, 128, - 31, 129, 36, 130, 131, 132, 113, 133 - ], - r3: &[ - 0x00001ffffcffffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0xffff03f8fff00000, - 0xefffffffffffffff, 0xfffe000fffe1dfff, 0xe3c5fdfffff99fef, 0x1003000fb080599f, - 0xc36dfdfffff987ee, 0x003f00005e021987, 0xe3edfdfffffbbfee, 0x1e00000f00011bbf, - 0xe3edfdfffff99fee, 0x0002000fb0c0199f, 0xc3ffc718d63dc7ec, 0x0000000000811dc7, - 0xe3fffdfffffddfef, 0x0000000f07601ddf, 0xe3effdfffffddfef, 0x0006000f40601ddf, - 0xe7fffffffffddfef, 0xfc00000f80f05ddf, 0x2ffbfffffc7fffec, 0x000c0000ff5f807f, - 0x07fffffffffffffe, 0x000000000000207f, 0x3bffffaffffff7d6, 0x00000000f000205f, - 0x0000000000000001, 0xfffe1ffffffffeff, 0x1ffffffffeffff03, 0x0000000000000000, - 0xf97fffffffffffff, 0xffffffffffff0000, 0xffffffff3c00ffff, 0xf7ffffffffff20bf, - 0xffffffffffffffff, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d, - 0xffffffffff3dffff, 0x0000000007ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff, - 0xfffffffffffffffe, 0xffff9fffffffffff, 0xffffffff07fffffe, 0x01ffc7ffffffffff, - 0x000fffff000fdfff, 0x000ddfff000fffff, 0xffcfffffffffffff, 0x00000000108001ff, - 0xffffffff00000000, 0x01ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff, - 0x01ff0fff7fffffff, 0x001f3fffffff0000, 0xffff0fffffffffff, 0x00000000000003ff, - 0xffffffff0fffffff, 0x001ffffe7fffffff, 0x0000008000000000, 0xffefffffffffffff, - 0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x007fffffffffffff, - 0x3ffffffffc00e000, 0xe7ffffffffff01ff, 0x046fde0000000000, 0x001fff8000000000, - 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, - 0x8002000000000000, 0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, - 0x00000000000001ff, 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, - 0xffffffff7fffffff, 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, - 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, - 0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, - 0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, - 0x00000c00ffff1fff, 0x8ff07fffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, - 0xff8000000000007c, 0x000000ffffffffbf, 0x000fffffffffffff, 0xe8fc00000000002f, - 0xffff07fffffffc00, 0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffff00008000, - 0xfc7fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e, - 0xffff00fff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, - 0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, - 0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xfffffffffffcffff, - 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, 0x07fffffe00000000, - 0xffffffc007fffffe, 0x000000001cfcfcfc - ], - r4: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 14, - 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - ], - r5: &[ - 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2, - 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32, - 32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 36, 2, 35, 37, 38, 32, 39, 2, 40, 41, 4, 42, 43, - 44, 45, 4, 4, 2, 46, 2, 47, 4, 4, 48, 49, 50, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, - 4, 57, 58, 59, 60, 61, 54, 4, 4, 4, 4, 62, 63, 64, 4, 65, 66, 67, 4, 4, 4, 4, 36, 4, 4, - 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 54, 20, 4, 72, 73, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, - 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2, 2, 2, 2, - 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90, 91, 92, - 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 95, 4, 4, 4, 96, 97, 4, 4, 4, 4, 4, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 99, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 101, 102, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, - 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, - 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 - ], - r6: &[ - 0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff, - 0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff, - 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f, - 0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff, - 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff, - 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff, - 0x003ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff, - 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff, - 0x0007ffffffffffff, 0x000000ffffffffff, 0xffff00801fffffff, 0x000000000000003f, - 0x007fffff00000000, 0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, - 0x000000001400001e, 0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, - 0xe3edfdfffff99fef, 0x0000000fe081199f, 0x00000000800007bb, 0x00000000000000b3, - 0x7f3fffffffffffff, 0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, - 0x013fffffffffffff, 0x000007ffe7ffffff, 0x01ffffffffffffff, 0xffffffff00000000, - 0x80000000ffffffff, 0xfffffcff00000000, 0x0000001afcffffff, 0x7fe7ffffffffffff, - 0xffffffffffff0000, 0x0000000020ffffff, 0x7f7ffffffffffdff, 0xfffc000000000001, - 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf000000cb, 0x00000000017b7fff, - 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f, - 0x00003fffffff0000, 0x0000ffffffffffff, 0xe0fffff80000000f, 0x000000000000ffff, - 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000, 0x00ffffffffffffff, - 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff, - 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, - 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, - 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000007dbf9ffff7f, - 0x3f801fffffffffff, 0x0000000000004000, 0x00000fffffffffff, 0x000000000000001f, - 0x000000000000088f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, - 0xffff000000000000, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff, - 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff - ], - }; - - pub fn Alphabetic(c: char) -> bool { - Alphabetic_table.lookup(c) - } - - #[rustfmt::skip] - const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xffff000000000000, 0xffffffffffffffff, - 0xffffffffffffffff, 0x0430ffffffffffff, 0x00000000000000b0, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000, - 0x0000000000000000, 0x0000000002000000, 0xbffffffffffe0000, 0x00100000000000b6, - 0x0000000017ff003f, 0x00010000fffff801, 0x0000000000000000, 0x00003dffbfc00000, - 0xffff000000028000, 0x00000000000007ff, 0x0001ffc000000000, 0x243ff80000000000 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 19, 2, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 39, 40, 2, 41, 2, 2, 2, 42, 43, 44, 2, - 45, 46, 47, 48, 49, 50, 2, 51, 52, 53, 54, 55, 2, 2, 2, 2, 2, 2, 56, 57, 58, 59, 60, 61, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 2, 63, 2, 64, 2, 65, 66, 2, 2, 2, 2, - 2, 2, 2, 67, 2, 68, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 2, 2, 71, 72, 73, 74, 75, 76, 77, 78, 79, 2, 2, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 92, 93, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 96, - 97, 98, 99, 100 - ], - r3: &[ - 0x00003fffffc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffffff80000, - 0x1400000000000007, 0x0002000c00fe21fe, 0x1000000000000002, 0x4000000c0000201e, - 0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002, - 0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000011, - 0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x0000000c0000201e, - 0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1ff2000000000000, - 0x0000000000003f40, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, - 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, - 0x1000000000000000, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, - 0x3fb0000000000000, 0x00000000208ffe40, 0x0000000000007800, 0x0000000000000008, - 0x0000020000000060, 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, - 0x7fff008000000000, 0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, - 0x0003a34000000000, 0x00cff00000000000, 0x3f00000000000000, 0x031021fdfff70000, - 0xfffff00000000000, 0x010007ffffffffff, 0xfffffffff8000000, 0xfbffffffffffffff, - 0xa000000000000000, 0x6000e000e000e003, 0x00007c900300f800, 0x8002ffdf00000000, - 0x000000001fff0000, 0x0001ffffffff0000, 0x3000000000000000, 0x0003800000000000, - 0x8000800000000000, 0xffffffff00000000, 0x0000800000000000, 0x083e3c0000000020, - 0x000000007e000000, 0x7000000000000000, 0x0000000000200000, 0x0000000000001000, - 0xbff7800000000000, 0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff, - 0x0001000000000000, 0x0000000000000700, 0x0300000000000000, 0x0000006000000844, - 0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x33c8000000000007, - 0x0000006000008000, 0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000, - 0x0058300020000002, 0x00000000f8000000, 0x0000212000000000, 0x0000000040000000, - 0xfffc000000000000, 0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000, - 0x8000000000000000, 0x4000000004004080, 0x0001000000000001, 0x00000000c0000000, - 0x0e00000800000000 - ], - r4: [ - 0, 1, 2, 3, 2, 2, 4, 2, 2, 2, 2, 5, 2, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22, - 23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, - 0, 0, 0, 0, 35, 0, 36, 0, 37, 38, 39, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, - 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 52, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 56, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 58, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 62, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, - 0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0, - 0xff00000000000002, 0x800000000000007f, 0x2678000000000003, 0x0000000000002000, - 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00, - 0x40d3800000000000, 0x000007f880000000, 0x1800000000000003, 0x001f1fc000000001, - 0xff00000000000000, 0x000000004000005c, 0x85f8000000000000, 0x000000000000000d, - 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, - 0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, - 0x79f80000000007fe, 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, - 0x006dfcfffffc0000, 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, - 0x0018000000000000, 0x01ff000000000000, 0x001f000000000000, 0x007f000000000000, - 0x000000000000000f, 0x0000000000008000, 0x00000000ffff8000, 0x0000000b00000000, - 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7, 0x000000000000001c, - 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, - 0x3fff000000000000, 0x0000f00000000000, 0x00000000007f0000, 0x0000000000000ff0, - 0xf800000000000000, 0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff - ], - }; - - pub fn Case_Ignorable(c: char) -> bool { - Case_Ignorable_table.lookup(c) - } - - #[rustfmt::skip] - const Cased_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0, - 0xffffffffffffffff, 0xffffffffffffffff, 0x01ffffffffefffff, 0x0000001f00000003, - 0x0000000000000000, 0xbccf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff, - 0xfffeffffffffffff, 0xffffffff007fffff, 0x00000000000001ff, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 5, 5, - 0, 5, 5, 5, 5, 6, 7, 8, 9, 0, 10, 11, 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, - 0, 23, 5, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 30, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xffffffff00000000, 0xe7ffffffffff20bf, 0x3f3fffffffffffff, - 0xe7ffffffffff01ff, 0xffffffffffffffff, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, - 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, - 0xf21fbd503e2ffc84, 0xffffffff000043e0, 0x0000000000000018, 0xffc0000000000000, - 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff, - 0x000020bfffffffff, 0x00003fffffffffff, 0x000000003fffffff, 0xfffffffc00000000, - 0xffffffffffff78ff, 0x070000000000007c, 0xffff000000000000, 0xffff00fff7ffffff, - 0x0000000000f8007f, 0x07fffffe00000000, 0x0000000007fffffe - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 9, 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0xffffffffffffffff, 0x000000000000ffff, 0xffff000000000000, - 0x0fffffffff0fffff, 0x0007ffffffffffff, 0xffffffff00000000, 0x00000000ffffffff, - 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, - 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, - 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000000000000000f, - 0xffff03ffffff03ff, 0x00000000000003ff - ], - }; - - pub fn Cased(c: char) -> bool { - Cased_table.lookup(c) - } - - #[rustfmt::skip] - const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0xffffffffffffffff, 0x0000ffffffffffff, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6, - 0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000, - 0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x200ff80000000000 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 2, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 2, 39, 2, 40, 2, 2, 2, 41, 42, 43, 2, 44, - 45, 46, 47, 48, 2, 2, 49, 2, 2, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 2, 52, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53, 2, 54, 2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 56, - 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 58, 59, 60, 2, 2, 2, 2, 61, 2, 2, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 2, 2, 2, 2, 59, 2 - ], - r3: &[ - 0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff80000, - 0x1400000000000007, 0x0000000c00fe21fe, 0x5000000000000002, 0x4000000c0080201e, - 0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0xd000000000000002, - 0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000011, - 0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003, - 0x0000000c0080201e, 0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80, - 0x1ff2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, - 0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, - 0x0000000020002064, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, - 0x3fb0000000000000, 0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060, - 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000, - 0x17f000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, - 0x00cff00000000000, 0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000, - 0x0001ffffffff0000, 0x0003800000000000, 0x8000000000000000, 0xffffffff00000000, - 0x0000fc0000000000, 0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000, - 0x0003000000000000, 0x0000006000000844, 0x8003ffff00000030, 0x00003fc000000000, - 0x000000000003ff80, 0x33c8000000000007, 0x0000002000000000, 0x00667e0000000000, - 0x1000000000001008, 0xc19d000000000000, 0x0040300000000002, 0x0000212000000000, - 0x0000000040000000, 0x0000ffff0000ffff - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, - 22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 0, - 0, 0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 0, - 0, 56, 56, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, - 0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0, - 0xff00000000000002, 0x800000000000007f, 0x0678000000000003, 0x001fef8000000007, - 0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00, 0x40d3800000000000, - 0x000007f880000000, 0x5800000000000003, 0x001f1fc000800001, 0xff00000000000000, - 0x000000004000005c, 0xa5f9000000000000, 0x000000000000000d, 0xb03c800000000000, - 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, 0x00bf280000000000, - 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, 0x79f80000000007fe, - 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, - 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, - 0x001f000000000000, 0x007f000000000000, 0x0000000000008000, 0x0000000000078000, - 0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7, 0x000000000000001c, - 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, - 0x0000f00000000000, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000, - 0xffffffffffffffff, 0x0000ffffffffffff - ], - }; - - pub fn Grapheme_Extend(c: char) -> bool { - Grapheme_Extend_table.lookup(c) - } - - #[rustfmt::skip] - const Lowercase_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000, - 0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240, - 0x93faaaaaaaaaaaaa, 0xffffffffffffaa85, 0x01ffffffffefffff, 0x0000001f00000003, - 0x0000000000000000, 0x3c8a000000000020, 0xfffff00000010000, 0x192faaaaaae37fff, - 0xffff000000000000, 0xaaaaaaaaffffffff, 0xaaaaaaaaaaaaa802, 0xaaaaaaaaaaaad554, - 0x0000aaaaaaaaaaaa, 0xffffffff00000000, 0x00000000000001ff, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 4, 4, - 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 11, 12, 0, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, - 0, 23, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 27, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xe7ffffffffff0000, 0x3f00000000000000, 0x00000000000001ff, - 0xffffffffffffffff, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabfeaaaaa, 0x00ff00ff003f00ff, - 0x3fff00ff00ff003f, 0x40df00ff00ff00ff, 0x00dc00ff00cf00dc, 0x8002000000000000, - 0x000000001fff0000, 0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010, - 0x000003ffffff0000, 0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa, - 0x000020bfffffffff, 0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000, - 0x95ffaaaaaaaaaaaa, 0xaaa082aaaaba50aa, 0x0700000000000008, 0xffff00fff7ffffff, - 0x0000000000f8007f, 0x0000000007fffffe - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0xffffff0000000000, 0x000000000000ffff, 0x0fffffffff000000, - 0x0007ffffffffffff, 0x00000000ffffffff, 0xffffffff00000000, 0x000ffffffc000000, - 0x000000ffffdfc000, 0xebc000000ffffffc, 0xfffffc000000ffef, 0x00ffffffc000000f, - 0x00000ffffffc0000, 0xfc000000ffffffc0, 0xffffc000000fffff, 0x0ffffffc000000ff, - 0x0000ffffffc00000, 0x0000003ffffffc00, 0xf0000003f7fffffc, 0xffc000000fdfffff, - 0xffff0000003f7fff, 0xfffffc000000fdff, 0x0000000000000bf7, 0xfffffffc00000000, - 0x000000000000000f - ], - }; - - pub fn Lowercase(c: char) -> bool { - Lowercase_table.lookup(c) - } - - #[rustfmt::skip] - const Uppercase_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff, - 0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490, - 0x6c05555555555555, 0x000000000000557a, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x8045000000000000, 0x00000ffbfffed740, 0xe6905555551c8000, - 0x0000ffffffffffff, 0x5555555500000000, 0x5555555555555401, 0x5555555555552aab, - 0xfffe555555555555, 0x00000000007fffff, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, - 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 16, 17, 5, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, - 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 25, 0, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x003fffffffffffff, - 0xe7ffffffffff0000, 0x5555555555555555, 0x5555555540155555, 0xff00ff003f00ff00, - 0x0000ff00aa003f00, 0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884, - 0x0000ffff00000020, 0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff, - 0x00007fffffffffff, 0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555, - 0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x555f7d5555452855, - 0x0000000000000074, 0x07fffffe00000000 - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x000000ffffffffff, 0xffff000000000000, 0x00000000000fffff, - 0x0007ffffffffffff, 0xffffffff00000000, 0x00000000ffffffff, 0xfff0000003ffffff, - 0xffffff0000003fff, 0x003fde64d0000003, 0x000003ffffff0000, 0x7b0000001fdfe7b0, - 0xfffff0000001fc5f, 0x03ffffff0000003f, 0x00003ffffff00000, 0xf0000003ffffff00, - 0xffff0000003fffff, 0xffffff00000003ff, 0x07fffffc00000001, 0x001ffffff0000000, - 0x00007fffffc00000, 0x000001ffffff0000, 0x0000000000000400, 0x00000003ffffffff, - 0xffff03ffffff03ff, 0x00000000000003ff - ], - }; - - pub fn Uppercase(c: char) -> bool { - Uppercase_table.lookup(c) - } -} - -pub(crate) mod property { - #[rustfmt::skip] - const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { - r1: &[ - 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 - ], - r2: &[ - 0x0000000100003e00, 0x0000000000000000, 0x0000000100000020, 0x0000000000000001, - 0x00008300000007ff, 0x0000000080000000 - ], - }; - - pub fn White_Space(c: char) -> bool { - White_Space_table.lookup(c) - } -} - -pub(crate) mod conversions { - pub fn to_lower(c: char) -> [char; 3] { - match bsearch_case_table(c, to_lowercase_table) { - None => [c, '\0', '\0'], - Some(index) => to_lowercase_table[index].1, - } - } - - pub fn to_upper(c: char) -> [char; 3] { - match bsearch_case_table(c, to_uppercase_table) { - None => [c, '\0', '\0'], - Some(index) => to_uppercase_table[index].1, - } - } - - fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { - table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() - } - - #[rustfmt::skip] - const to_lowercase_table: &[(char, [char; 3])] = &[ - ('\u{41}', ['\u{61}', '\0', '\0']), ('\u{42}', ['\u{62}', '\0', '\0']), ('\u{43}', - ['\u{63}', '\0', '\0']), ('\u{44}', ['\u{64}', '\0', '\0']), ('\u{45}', ['\u{65}', '\0', - '\0']), ('\u{46}', ['\u{66}', '\0', '\0']), ('\u{47}', ['\u{67}', '\0', '\0']), ('\u{48}', - ['\u{68}', '\0', '\0']), ('\u{49}', ['\u{69}', '\0', '\0']), ('\u{4a}', ['\u{6a}', '\0', - '\0']), ('\u{4b}', ['\u{6b}', '\0', '\0']), ('\u{4c}', ['\u{6c}', '\0', '\0']), ('\u{4d}', - ['\u{6d}', '\0', '\0']), ('\u{4e}', ['\u{6e}', '\0', '\0']), ('\u{4f}', ['\u{6f}', '\0', - '\0']), ('\u{50}', ['\u{70}', '\0', '\0']), ('\u{51}', ['\u{71}', '\0', '\0']), ('\u{52}', - ['\u{72}', '\0', '\0']), ('\u{53}', ['\u{73}', '\0', '\0']), ('\u{54}', ['\u{74}', '\0', - '\0']), ('\u{55}', ['\u{75}', '\0', '\0']), ('\u{56}', ['\u{76}', '\0', '\0']), ('\u{57}', - ['\u{77}', '\0', '\0']), ('\u{58}', ['\u{78}', '\0', '\0']), ('\u{59}', ['\u{79}', '\0', - '\0']), ('\u{5a}', ['\u{7a}', '\0', '\0']), ('\u{c0}', ['\u{e0}', '\0', '\0']), ('\u{c1}', - ['\u{e1}', '\0', '\0']), ('\u{c2}', ['\u{e2}', '\0', '\0']), ('\u{c3}', ['\u{e3}', '\0', - '\0']), ('\u{c4}', ['\u{e4}', '\0', '\0']), ('\u{c5}', ['\u{e5}', '\0', '\0']), ('\u{c6}', - ['\u{e6}', '\0', '\0']), ('\u{c7}', ['\u{e7}', '\0', '\0']), ('\u{c8}', ['\u{e8}', '\0', - '\0']), ('\u{c9}', ['\u{e9}', '\0', '\0']), ('\u{ca}', ['\u{ea}', '\0', '\0']), ('\u{cb}', - ['\u{eb}', '\0', '\0']), ('\u{cc}', ['\u{ec}', '\0', '\0']), ('\u{cd}', ['\u{ed}', '\0', - '\0']), ('\u{ce}', ['\u{ee}', '\0', '\0']), ('\u{cf}', ['\u{ef}', '\0', '\0']), ('\u{d0}', - ['\u{f0}', '\0', '\0']), ('\u{d1}', ['\u{f1}', '\0', '\0']), ('\u{d2}', ['\u{f2}', '\0', - '\0']), ('\u{d3}', ['\u{f3}', '\0', '\0']), ('\u{d4}', ['\u{f4}', '\0', '\0']), ('\u{d5}', - ['\u{f5}', '\0', '\0']), ('\u{d6}', ['\u{f6}', '\0', '\0']), ('\u{d8}', ['\u{f8}', '\0', - '\0']), ('\u{d9}', ['\u{f9}', '\0', '\0']), ('\u{da}', ['\u{fa}', '\0', '\0']), ('\u{db}', - ['\u{fb}', '\0', '\0']), ('\u{dc}', ['\u{fc}', '\0', '\0']), ('\u{dd}', ['\u{fd}', '\0', - '\0']), ('\u{de}', ['\u{fe}', '\0', '\0']), ('\u{100}', ['\u{101}', '\0', '\0']), - ('\u{102}', ['\u{103}', '\0', '\0']), ('\u{104}', ['\u{105}', '\0', '\0']), ('\u{106}', - ['\u{107}', '\0', '\0']), ('\u{108}', ['\u{109}', '\0', '\0']), ('\u{10a}', ['\u{10b}', - '\0', '\0']), ('\u{10c}', ['\u{10d}', '\0', '\0']), ('\u{10e}', ['\u{10f}', '\0', '\0']), - ('\u{110}', ['\u{111}', '\0', '\0']), ('\u{112}', ['\u{113}', '\0', '\0']), ('\u{114}', - ['\u{115}', '\0', '\0']), ('\u{116}', ['\u{117}', '\0', '\0']), ('\u{118}', ['\u{119}', - '\0', '\0']), ('\u{11a}', ['\u{11b}', '\0', '\0']), ('\u{11c}', ['\u{11d}', '\0', '\0']), - ('\u{11e}', ['\u{11f}', '\0', '\0']), ('\u{120}', ['\u{121}', '\0', '\0']), ('\u{122}', - ['\u{123}', '\0', '\0']), ('\u{124}', ['\u{125}', '\0', '\0']), ('\u{126}', ['\u{127}', - '\0', '\0']), ('\u{128}', ['\u{129}', '\0', '\0']), ('\u{12a}', ['\u{12b}', '\0', '\0']), - ('\u{12c}', ['\u{12d}', '\0', '\0']), ('\u{12e}', ['\u{12f}', '\0', '\0']), ('\u{130}', - ['\u{69}', '\u{307}', '\0']), ('\u{132}', ['\u{133}', '\0', '\0']), ('\u{134}', ['\u{135}', - '\0', '\0']), ('\u{136}', ['\u{137}', '\0', '\0']), ('\u{139}', ['\u{13a}', '\0', '\0']), - ('\u{13b}', ['\u{13c}', '\0', '\0']), ('\u{13d}', ['\u{13e}', '\0', '\0']), ('\u{13f}', - ['\u{140}', '\0', '\0']), ('\u{141}', ['\u{142}', '\0', '\0']), ('\u{143}', ['\u{144}', - '\0', '\0']), ('\u{145}', ['\u{146}', '\0', '\0']), ('\u{147}', ['\u{148}', '\0', '\0']), - ('\u{14a}', ['\u{14b}', '\0', '\0']), ('\u{14c}', ['\u{14d}', '\0', '\0']), ('\u{14e}', - ['\u{14f}', '\0', '\0']), ('\u{150}', ['\u{151}', '\0', '\0']), ('\u{152}', ['\u{153}', - '\0', '\0']), ('\u{154}', ['\u{155}', '\0', '\0']), ('\u{156}', ['\u{157}', '\0', '\0']), - ('\u{158}', ['\u{159}', '\0', '\0']), ('\u{15a}', ['\u{15b}', '\0', '\0']), ('\u{15c}', - ['\u{15d}', '\0', '\0']), ('\u{15e}', ['\u{15f}', '\0', '\0']), ('\u{160}', ['\u{161}', - '\0', '\0']), ('\u{162}', ['\u{163}', '\0', '\0']), ('\u{164}', ['\u{165}', '\0', '\0']), - ('\u{166}', ['\u{167}', '\0', '\0']), ('\u{168}', ['\u{169}', '\0', '\0']), ('\u{16a}', - ['\u{16b}', '\0', '\0']), ('\u{16c}', ['\u{16d}', '\0', '\0']), ('\u{16e}', ['\u{16f}', - '\0', '\0']), ('\u{170}', ['\u{171}', '\0', '\0']), ('\u{172}', ['\u{173}', '\0', '\0']), - ('\u{174}', ['\u{175}', '\0', '\0']), ('\u{176}', ['\u{177}', '\0', '\0']), ('\u{178}', - ['\u{ff}', '\0', '\0']), ('\u{179}', ['\u{17a}', '\0', '\0']), ('\u{17b}', ['\u{17c}', '\0', - '\0']), ('\u{17d}', ['\u{17e}', '\0', '\0']), ('\u{181}', ['\u{253}', '\0', '\0']), - ('\u{182}', ['\u{183}', '\0', '\0']), ('\u{184}', ['\u{185}', '\0', '\0']), ('\u{186}', - ['\u{254}', '\0', '\0']), ('\u{187}', ['\u{188}', '\0', '\0']), ('\u{189}', ['\u{256}', - '\0', '\0']), ('\u{18a}', ['\u{257}', '\0', '\0']), ('\u{18b}', ['\u{18c}', '\0', '\0']), - ('\u{18e}', ['\u{1dd}', '\0', '\0']), ('\u{18f}', ['\u{259}', '\0', '\0']), ('\u{190}', - ['\u{25b}', '\0', '\0']), ('\u{191}', ['\u{192}', '\0', '\0']), ('\u{193}', ['\u{260}', - '\0', '\0']), ('\u{194}', ['\u{263}', '\0', '\0']), ('\u{196}', ['\u{269}', '\0', '\0']), - ('\u{197}', ['\u{268}', '\0', '\0']), ('\u{198}', ['\u{199}', '\0', '\0']), ('\u{19c}', - ['\u{26f}', '\0', '\0']), ('\u{19d}', ['\u{272}', '\0', '\0']), ('\u{19f}', ['\u{275}', - '\0', '\0']), ('\u{1a0}', ['\u{1a1}', '\0', '\0']), ('\u{1a2}', ['\u{1a3}', '\0', '\0']), - ('\u{1a4}', ['\u{1a5}', '\0', '\0']), ('\u{1a6}', ['\u{280}', '\0', '\0']), ('\u{1a7}', - ['\u{1a8}', '\0', '\0']), ('\u{1a9}', ['\u{283}', '\0', '\0']), ('\u{1ac}', ['\u{1ad}', - '\0', '\0']), ('\u{1ae}', ['\u{288}', '\0', '\0']), ('\u{1af}', ['\u{1b0}', '\0', '\0']), - ('\u{1b1}', ['\u{28a}', '\0', '\0']), ('\u{1b2}', ['\u{28b}', '\0', '\0']), ('\u{1b3}', - ['\u{1b4}', '\0', '\0']), ('\u{1b5}', ['\u{1b6}', '\0', '\0']), ('\u{1b7}', ['\u{292}', - '\0', '\0']), ('\u{1b8}', ['\u{1b9}', '\0', '\0']), ('\u{1bc}', ['\u{1bd}', '\0', '\0']), - ('\u{1c4}', ['\u{1c6}', '\0', '\0']), ('\u{1c5}', ['\u{1c6}', '\0', '\0']), ('\u{1c7}', - ['\u{1c9}', '\0', '\0']), ('\u{1c8}', ['\u{1c9}', '\0', '\0']), ('\u{1ca}', ['\u{1cc}', - '\0', '\0']), ('\u{1cb}', ['\u{1cc}', '\0', '\0']), ('\u{1cd}', ['\u{1ce}', '\0', '\0']), - ('\u{1cf}', ['\u{1d0}', '\0', '\0']), ('\u{1d1}', ['\u{1d2}', '\0', '\0']), ('\u{1d3}', - ['\u{1d4}', '\0', '\0']), ('\u{1d5}', ['\u{1d6}', '\0', '\0']), ('\u{1d7}', ['\u{1d8}', - '\0', '\0']), ('\u{1d9}', ['\u{1da}', '\0', '\0']), ('\u{1db}', ['\u{1dc}', '\0', '\0']), - ('\u{1de}', ['\u{1df}', '\0', '\0']), ('\u{1e0}', ['\u{1e1}', '\0', '\0']), ('\u{1e2}', - ['\u{1e3}', '\0', '\0']), ('\u{1e4}', ['\u{1e5}', '\0', '\0']), ('\u{1e6}', ['\u{1e7}', - '\0', '\0']), ('\u{1e8}', ['\u{1e9}', '\0', '\0']), ('\u{1ea}', ['\u{1eb}', '\0', '\0']), - ('\u{1ec}', ['\u{1ed}', '\0', '\0']), ('\u{1ee}', ['\u{1ef}', '\0', '\0']), ('\u{1f1}', - ['\u{1f3}', '\0', '\0']), ('\u{1f2}', ['\u{1f3}', '\0', '\0']), ('\u{1f4}', ['\u{1f5}', - '\0', '\0']), ('\u{1f6}', ['\u{195}', '\0', '\0']), ('\u{1f7}', ['\u{1bf}', '\0', '\0']), - ('\u{1f8}', ['\u{1f9}', '\0', '\0']), ('\u{1fa}', ['\u{1fb}', '\0', '\0']), ('\u{1fc}', - ['\u{1fd}', '\0', '\0']), ('\u{1fe}', ['\u{1ff}', '\0', '\0']), ('\u{200}', ['\u{201}', - '\0', '\0']), ('\u{202}', ['\u{203}', '\0', '\0']), ('\u{204}', ['\u{205}', '\0', '\0']), - ('\u{206}', ['\u{207}', '\0', '\0']), ('\u{208}', ['\u{209}', '\0', '\0']), ('\u{20a}', - ['\u{20b}', '\0', '\0']), ('\u{20c}', ['\u{20d}', '\0', '\0']), ('\u{20e}', ['\u{20f}', - '\0', '\0']), ('\u{210}', ['\u{211}', '\0', '\0']), ('\u{212}', ['\u{213}', '\0', '\0']), - ('\u{214}', ['\u{215}', '\0', '\0']), ('\u{216}', ['\u{217}', '\0', '\0']), ('\u{218}', - ['\u{219}', '\0', '\0']), ('\u{21a}', ['\u{21b}', '\0', '\0']), ('\u{21c}', ['\u{21d}', - '\0', '\0']), ('\u{21e}', ['\u{21f}', '\0', '\0']), ('\u{220}', ['\u{19e}', '\0', '\0']), - ('\u{222}', ['\u{223}', '\0', '\0']), ('\u{224}', ['\u{225}', '\0', '\0']), ('\u{226}', - ['\u{227}', '\0', '\0']), ('\u{228}', ['\u{229}', '\0', '\0']), ('\u{22a}', ['\u{22b}', - '\0', '\0']), ('\u{22c}', ['\u{22d}', '\0', '\0']), ('\u{22e}', ['\u{22f}', '\0', '\0']), - ('\u{230}', ['\u{231}', '\0', '\0']), ('\u{232}', ['\u{233}', '\0', '\0']), ('\u{23a}', - ['\u{2c65}', '\0', '\0']), ('\u{23b}', ['\u{23c}', '\0', '\0']), ('\u{23d}', ['\u{19a}', - '\0', '\0']), ('\u{23e}', ['\u{2c66}', '\0', '\0']), ('\u{241}', ['\u{242}', '\0', '\0']), - ('\u{243}', ['\u{180}', '\0', '\0']), ('\u{244}', ['\u{289}', '\0', '\0']), ('\u{245}', - ['\u{28c}', '\0', '\0']), ('\u{246}', ['\u{247}', '\0', '\0']), ('\u{248}', ['\u{249}', - '\0', '\0']), ('\u{24a}', ['\u{24b}', '\0', '\0']), ('\u{24c}', ['\u{24d}', '\0', '\0']), - ('\u{24e}', ['\u{24f}', '\0', '\0']), ('\u{370}', ['\u{371}', '\0', '\0']), ('\u{372}', - ['\u{373}', '\0', '\0']), ('\u{376}', ['\u{377}', '\0', '\0']), ('\u{37f}', ['\u{3f3}', - '\0', '\0']), ('\u{386}', ['\u{3ac}', '\0', '\0']), ('\u{388}', ['\u{3ad}', '\0', '\0']), - ('\u{389}', ['\u{3ae}', '\0', '\0']), ('\u{38a}', ['\u{3af}', '\0', '\0']), ('\u{38c}', - ['\u{3cc}', '\0', '\0']), ('\u{38e}', ['\u{3cd}', '\0', '\0']), ('\u{38f}', ['\u{3ce}', - '\0', '\0']), ('\u{391}', ['\u{3b1}', '\0', '\0']), ('\u{392}', ['\u{3b2}', '\0', '\0']), - ('\u{393}', ['\u{3b3}', '\0', '\0']), ('\u{394}', ['\u{3b4}', '\0', '\0']), ('\u{395}', - ['\u{3b5}', '\0', '\0']), ('\u{396}', ['\u{3b6}', '\0', '\0']), ('\u{397}', ['\u{3b7}', - '\0', '\0']), ('\u{398}', ['\u{3b8}', '\0', '\0']), ('\u{399}', ['\u{3b9}', '\0', '\0']), - ('\u{39a}', ['\u{3ba}', '\0', '\0']), ('\u{39b}', ['\u{3bb}', '\0', '\0']), ('\u{39c}', - ['\u{3bc}', '\0', '\0']), ('\u{39d}', ['\u{3bd}', '\0', '\0']), ('\u{39e}', ['\u{3be}', - '\0', '\0']), ('\u{39f}', ['\u{3bf}', '\0', '\0']), ('\u{3a0}', ['\u{3c0}', '\0', '\0']), - ('\u{3a1}', ['\u{3c1}', '\0', '\0']), ('\u{3a3}', ['\u{3c3}', '\0', '\0']), ('\u{3a4}', - ['\u{3c4}', '\0', '\0']), ('\u{3a5}', ['\u{3c5}', '\0', '\0']), ('\u{3a6}', ['\u{3c6}', - '\0', '\0']), ('\u{3a7}', ['\u{3c7}', '\0', '\0']), ('\u{3a8}', ['\u{3c8}', '\0', '\0']), - ('\u{3a9}', ['\u{3c9}', '\0', '\0']), ('\u{3aa}', ['\u{3ca}', '\0', '\0']), ('\u{3ab}', - ['\u{3cb}', '\0', '\0']), ('\u{3cf}', ['\u{3d7}', '\0', '\0']), ('\u{3d8}', ['\u{3d9}', - '\0', '\0']), ('\u{3da}', ['\u{3db}', '\0', '\0']), ('\u{3dc}', ['\u{3dd}', '\0', '\0']), - ('\u{3de}', ['\u{3df}', '\0', '\0']), ('\u{3e0}', ['\u{3e1}', '\0', '\0']), ('\u{3e2}', - ['\u{3e3}', '\0', '\0']), ('\u{3e4}', ['\u{3e5}', '\0', '\0']), ('\u{3e6}', ['\u{3e7}', - '\0', '\0']), ('\u{3e8}', ['\u{3e9}', '\0', '\0']), ('\u{3ea}', ['\u{3eb}', '\0', '\0']), - ('\u{3ec}', ['\u{3ed}', '\0', '\0']), ('\u{3ee}', ['\u{3ef}', '\0', '\0']), ('\u{3f4}', - ['\u{3b8}', '\0', '\0']), ('\u{3f7}', ['\u{3f8}', '\0', '\0']), ('\u{3f9}', ['\u{3f2}', - '\0', '\0']), ('\u{3fa}', ['\u{3fb}', '\0', '\0']), ('\u{3fd}', ['\u{37b}', '\0', '\0']), - ('\u{3fe}', ['\u{37c}', '\0', '\0']), ('\u{3ff}', ['\u{37d}', '\0', '\0']), ('\u{400}', - ['\u{450}', '\0', '\0']), ('\u{401}', ['\u{451}', '\0', '\0']), ('\u{402}', ['\u{452}', - '\0', '\0']), ('\u{403}', ['\u{453}', '\0', '\0']), ('\u{404}', ['\u{454}', '\0', '\0']), - ('\u{405}', ['\u{455}', '\0', '\0']), ('\u{406}', ['\u{456}', '\0', '\0']), ('\u{407}', - ['\u{457}', '\0', '\0']), ('\u{408}', ['\u{458}', '\0', '\0']), ('\u{409}', ['\u{459}', - '\0', '\0']), ('\u{40a}', ['\u{45a}', '\0', '\0']), ('\u{40b}', ['\u{45b}', '\0', '\0']), - ('\u{40c}', ['\u{45c}', '\0', '\0']), ('\u{40d}', ['\u{45d}', '\0', '\0']), ('\u{40e}', - ['\u{45e}', '\0', '\0']), ('\u{40f}', ['\u{45f}', '\0', '\0']), ('\u{410}', ['\u{430}', - '\0', '\0']), ('\u{411}', ['\u{431}', '\0', '\0']), ('\u{412}', ['\u{432}', '\0', '\0']), - ('\u{413}', ['\u{433}', '\0', '\0']), ('\u{414}', ['\u{434}', '\0', '\0']), ('\u{415}', - ['\u{435}', '\0', '\0']), ('\u{416}', ['\u{436}', '\0', '\0']), ('\u{417}', ['\u{437}', - '\0', '\0']), ('\u{418}', ['\u{438}', '\0', '\0']), ('\u{419}', ['\u{439}', '\0', '\0']), - ('\u{41a}', ['\u{43a}', '\0', '\0']), ('\u{41b}', ['\u{43b}', '\0', '\0']), ('\u{41c}', - ['\u{43c}', '\0', '\0']), ('\u{41d}', ['\u{43d}', '\0', '\0']), ('\u{41e}', ['\u{43e}', - '\0', '\0']), ('\u{41f}', ['\u{43f}', '\0', '\0']), ('\u{420}', ['\u{440}', '\0', '\0']), - ('\u{421}', ['\u{441}', '\0', '\0']), ('\u{422}', ['\u{442}', '\0', '\0']), ('\u{423}', - ['\u{443}', '\0', '\0']), ('\u{424}', ['\u{444}', '\0', '\0']), ('\u{425}', ['\u{445}', - '\0', '\0']), ('\u{426}', ['\u{446}', '\0', '\0']), ('\u{427}', ['\u{447}', '\0', '\0']), - ('\u{428}', ['\u{448}', '\0', '\0']), ('\u{429}', ['\u{449}', '\0', '\0']), ('\u{42a}', - ['\u{44a}', '\0', '\0']), ('\u{42b}', ['\u{44b}', '\0', '\0']), ('\u{42c}', ['\u{44c}', - '\0', '\0']), ('\u{42d}', ['\u{44d}', '\0', '\0']), ('\u{42e}', ['\u{44e}', '\0', '\0']), - ('\u{42f}', ['\u{44f}', '\0', '\0']), ('\u{460}', ['\u{461}', '\0', '\0']), ('\u{462}', - ['\u{463}', '\0', '\0']), ('\u{464}', ['\u{465}', '\0', '\0']), ('\u{466}', ['\u{467}', - '\0', '\0']), ('\u{468}', ['\u{469}', '\0', '\0']), ('\u{46a}', ['\u{46b}', '\0', '\0']), - ('\u{46c}', ['\u{46d}', '\0', '\0']), ('\u{46e}', ['\u{46f}', '\0', '\0']), ('\u{470}', - ['\u{471}', '\0', '\0']), ('\u{472}', ['\u{473}', '\0', '\0']), ('\u{474}', ['\u{475}', - '\0', '\0']), ('\u{476}', ['\u{477}', '\0', '\0']), ('\u{478}', ['\u{479}', '\0', '\0']), - ('\u{47a}', ['\u{47b}', '\0', '\0']), ('\u{47c}', ['\u{47d}', '\0', '\0']), ('\u{47e}', - ['\u{47f}', '\0', '\0']), ('\u{480}', ['\u{481}', '\0', '\0']), ('\u{48a}', ['\u{48b}', - '\0', '\0']), ('\u{48c}', ['\u{48d}', '\0', '\0']), ('\u{48e}', ['\u{48f}', '\0', '\0']), - ('\u{490}', ['\u{491}', '\0', '\0']), ('\u{492}', ['\u{493}', '\0', '\0']), ('\u{494}', - ['\u{495}', '\0', '\0']), ('\u{496}', ['\u{497}', '\0', '\0']), ('\u{498}', ['\u{499}', - '\0', '\0']), ('\u{49a}', ['\u{49b}', '\0', '\0']), ('\u{49c}', ['\u{49d}', '\0', '\0']), - ('\u{49e}', ['\u{49f}', '\0', '\0']), ('\u{4a0}', ['\u{4a1}', '\0', '\0']), ('\u{4a2}', - ['\u{4a3}', '\0', '\0']), ('\u{4a4}', ['\u{4a5}', '\0', '\0']), ('\u{4a6}', ['\u{4a7}', - '\0', '\0']), ('\u{4a8}', ['\u{4a9}', '\0', '\0']), ('\u{4aa}', ['\u{4ab}', '\0', '\0']), - ('\u{4ac}', ['\u{4ad}', '\0', '\0']), ('\u{4ae}', ['\u{4af}', '\0', '\0']), ('\u{4b0}', - ['\u{4b1}', '\0', '\0']), ('\u{4b2}', ['\u{4b3}', '\0', '\0']), ('\u{4b4}', ['\u{4b5}', - '\0', '\0']), ('\u{4b6}', ['\u{4b7}', '\0', '\0']), ('\u{4b8}', ['\u{4b9}', '\0', '\0']), - ('\u{4ba}', ['\u{4bb}', '\0', '\0']), ('\u{4bc}', ['\u{4bd}', '\0', '\0']), ('\u{4be}', - ['\u{4bf}', '\0', '\0']), ('\u{4c0}', ['\u{4cf}', '\0', '\0']), ('\u{4c1}', ['\u{4c2}', - '\0', '\0']), ('\u{4c3}', ['\u{4c4}', '\0', '\0']), ('\u{4c5}', ['\u{4c6}', '\0', '\0']), - ('\u{4c7}', ['\u{4c8}', '\0', '\0']), ('\u{4c9}', ['\u{4ca}', '\0', '\0']), ('\u{4cb}', - ['\u{4cc}', '\0', '\0']), ('\u{4cd}', ['\u{4ce}', '\0', '\0']), ('\u{4d0}', ['\u{4d1}', - '\0', '\0']), ('\u{4d2}', ['\u{4d3}', '\0', '\0']), ('\u{4d4}', ['\u{4d5}', '\0', '\0']), - ('\u{4d6}', ['\u{4d7}', '\0', '\0']), ('\u{4d8}', ['\u{4d9}', '\0', '\0']), ('\u{4da}', - ['\u{4db}', '\0', '\0']), ('\u{4dc}', ['\u{4dd}', '\0', '\0']), ('\u{4de}', ['\u{4df}', - '\0', '\0']), ('\u{4e0}', ['\u{4e1}', '\0', '\0']), ('\u{4e2}', ['\u{4e3}', '\0', '\0']), - ('\u{4e4}', ['\u{4e5}', '\0', '\0']), ('\u{4e6}', ['\u{4e7}', '\0', '\0']), ('\u{4e8}', - ['\u{4e9}', '\0', '\0']), ('\u{4ea}', ['\u{4eb}', '\0', '\0']), ('\u{4ec}', ['\u{4ed}', - '\0', '\0']), ('\u{4ee}', ['\u{4ef}', '\0', '\0']), ('\u{4f0}', ['\u{4f1}', '\0', '\0']), - ('\u{4f2}', ['\u{4f3}', '\0', '\0']), ('\u{4f4}', ['\u{4f5}', '\0', '\0']), ('\u{4f6}', - ['\u{4f7}', '\0', '\0']), ('\u{4f8}', ['\u{4f9}', '\0', '\0']), ('\u{4fa}', ['\u{4fb}', - '\0', '\0']), ('\u{4fc}', ['\u{4fd}', '\0', '\0']), ('\u{4fe}', ['\u{4ff}', '\0', '\0']), - ('\u{500}', ['\u{501}', '\0', '\0']), ('\u{502}', ['\u{503}', '\0', '\0']), ('\u{504}', - ['\u{505}', '\0', '\0']), ('\u{506}', ['\u{507}', '\0', '\0']), ('\u{508}', ['\u{509}', - '\0', '\0']), ('\u{50a}', ['\u{50b}', '\0', '\0']), ('\u{50c}', ['\u{50d}', '\0', '\0']), - ('\u{50e}', ['\u{50f}', '\0', '\0']), ('\u{510}', ['\u{511}', '\0', '\0']), ('\u{512}', - ['\u{513}', '\0', '\0']), ('\u{514}', ['\u{515}', '\0', '\0']), ('\u{516}', ['\u{517}', - '\0', '\0']), ('\u{518}', ['\u{519}', '\0', '\0']), ('\u{51a}', ['\u{51b}', '\0', '\0']), - ('\u{51c}', ['\u{51d}', '\0', '\0']), ('\u{51e}', ['\u{51f}', '\0', '\0']), ('\u{520}', - ['\u{521}', '\0', '\0']), ('\u{522}', ['\u{523}', '\0', '\0']), ('\u{524}', ['\u{525}', - '\0', '\0']), ('\u{526}', ['\u{527}', '\0', '\0']), ('\u{528}', ['\u{529}', '\0', '\0']), - ('\u{52a}', ['\u{52b}', '\0', '\0']), ('\u{52c}', ['\u{52d}', '\0', '\0']), ('\u{52e}', - ['\u{52f}', '\0', '\0']), ('\u{531}', ['\u{561}', '\0', '\0']), ('\u{532}', ['\u{562}', - '\0', '\0']), ('\u{533}', ['\u{563}', '\0', '\0']), ('\u{534}', ['\u{564}', '\0', '\0']), - ('\u{535}', ['\u{565}', '\0', '\0']), ('\u{536}', ['\u{566}', '\0', '\0']), ('\u{537}', - ['\u{567}', '\0', '\0']), ('\u{538}', ['\u{568}', '\0', '\0']), ('\u{539}', ['\u{569}', - '\0', '\0']), ('\u{53a}', ['\u{56a}', '\0', '\0']), ('\u{53b}', ['\u{56b}', '\0', '\0']), - ('\u{53c}', ['\u{56c}', '\0', '\0']), ('\u{53d}', ['\u{56d}', '\0', '\0']), ('\u{53e}', - ['\u{56e}', '\0', '\0']), ('\u{53f}', ['\u{56f}', '\0', '\0']), ('\u{540}', ['\u{570}', - '\0', '\0']), ('\u{541}', ['\u{571}', '\0', '\0']), ('\u{542}', ['\u{572}', '\0', '\0']), - ('\u{543}', ['\u{573}', '\0', '\0']), ('\u{544}', ['\u{574}', '\0', '\0']), ('\u{545}', - ['\u{575}', '\0', '\0']), ('\u{546}', ['\u{576}', '\0', '\0']), ('\u{547}', ['\u{577}', - '\0', '\0']), ('\u{548}', ['\u{578}', '\0', '\0']), ('\u{549}', ['\u{579}', '\0', '\0']), - ('\u{54a}', ['\u{57a}', '\0', '\0']), ('\u{54b}', ['\u{57b}', '\0', '\0']), ('\u{54c}', - ['\u{57c}', '\0', '\0']), ('\u{54d}', ['\u{57d}', '\0', '\0']), ('\u{54e}', ['\u{57e}', - '\0', '\0']), ('\u{54f}', ['\u{57f}', '\0', '\0']), ('\u{550}', ['\u{580}', '\0', '\0']), - ('\u{551}', ['\u{581}', '\0', '\0']), ('\u{552}', ['\u{582}', '\0', '\0']), ('\u{553}', - ['\u{583}', '\0', '\0']), ('\u{554}', ['\u{584}', '\0', '\0']), ('\u{555}', ['\u{585}', - '\0', '\0']), ('\u{556}', ['\u{586}', '\0', '\0']), ('\u{10a0}', ['\u{2d00}', '\0', '\0']), - ('\u{10a1}', ['\u{2d01}', '\0', '\0']), ('\u{10a2}', ['\u{2d02}', '\0', '\0']), ('\u{10a3}', - ['\u{2d03}', '\0', '\0']), ('\u{10a4}', ['\u{2d04}', '\0', '\0']), ('\u{10a5}', ['\u{2d05}', - '\0', '\0']), ('\u{10a6}', ['\u{2d06}', '\0', '\0']), ('\u{10a7}', ['\u{2d07}', '\0', - '\0']), ('\u{10a8}', ['\u{2d08}', '\0', '\0']), ('\u{10a9}', ['\u{2d09}', '\0', '\0']), - ('\u{10aa}', ['\u{2d0a}', '\0', '\0']), ('\u{10ab}', ['\u{2d0b}', '\0', '\0']), ('\u{10ac}', - ['\u{2d0c}', '\0', '\0']), ('\u{10ad}', ['\u{2d0d}', '\0', '\0']), ('\u{10ae}', ['\u{2d0e}', - '\0', '\0']), ('\u{10af}', ['\u{2d0f}', '\0', '\0']), ('\u{10b0}', ['\u{2d10}', '\0', - '\0']), ('\u{10b1}', ['\u{2d11}', '\0', '\0']), ('\u{10b2}', ['\u{2d12}', '\0', '\0']), - ('\u{10b3}', ['\u{2d13}', '\0', '\0']), ('\u{10b4}', ['\u{2d14}', '\0', '\0']), ('\u{10b5}', - ['\u{2d15}', '\0', '\0']), ('\u{10b6}', ['\u{2d16}', '\0', '\0']), ('\u{10b7}', ['\u{2d17}', - '\0', '\0']), ('\u{10b8}', ['\u{2d18}', '\0', '\0']), ('\u{10b9}', ['\u{2d19}', '\0', - '\0']), ('\u{10ba}', ['\u{2d1a}', '\0', '\0']), ('\u{10bb}', ['\u{2d1b}', '\0', '\0']), - ('\u{10bc}', ['\u{2d1c}', '\0', '\0']), ('\u{10bd}', ['\u{2d1d}', '\0', '\0']), ('\u{10be}', - ['\u{2d1e}', '\0', '\0']), ('\u{10bf}', ['\u{2d1f}', '\0', '\0']), ('\u{10c0}', ['\u{2d20}', - '\0', '\0']), ('\u{10c1}', ['\u{2d21}', '\0', '\0']), ('\u{10c2}', ['\u{2d22}', '\0', - '\0']), ('\u{10c3}', ['\u{2d23}', '\0', '\0']), ('\u{10c4}', ['\u{2d24}', '\0', '\0']), - ('\u{10c5}', ['\u{2d25}', '\0', '\0']), ('\u{10c7}', ['\u{2d27}', '\0', '\0']), ('\u{10cd}', - ['\u{2d2d}', '\0', '\0']), ('\u{13a0}', ['\u{ab70}', '\0', '\0']), ('\u{13a1}', ['\u{ab71}', - '\0', '\0']), ('\u{13a2}', ['\u{ab72}', '\0', '\0']), ('\u{13a3}', ['\u{ab73}', '\0', - '\0']), ('\u{13a4}', ['\u{ab74}', '\0', '\0']), ('\u{13a5}', ['\u{ab75}', '\0', '\0']), - ('\u{13a6}', ['\u{ab76}', '\0', '\0']), ('\u{13a7}', ['\u{ab77}', '\0', '\0']), ('\u{13a8}', - ['\u{ab78}', '\0', '\0']), ('\u{13a9}', ['\u{ab79}', '\0', '\0']), ('\u{13aa}', ['\u{ab7a}', - '\0', '\0']), ('\u{13ab}', ['\u{ab7b}', '\0', '\0']), ('\u{13ac}', ['\u{ab7c}', '\0', - '\0']), ('\u{13ad}', ['\u{ab7d}', '\0', '\0']), ('\u{13ae}', ['\u{ab7e}', '\0', '\0']), - ('\u{13af}', ['\u{ab7f}', '\0', '\0']), ('\u{13b0}', ['\u{ab80}', '\0', '\0']), ('\u{13b1}', - ['\u{ab81}', '\0', '\0']), ('\u{13b2}', ['\u{ab82}', '\0', '\0']), ('\u{13b3}', ['\u{ab83}', - '\0', '\0']), ('\u{13b4}', ['\u{ab84}', '\0', '\0']), ('\u{13b5}', ['\u{ab85}', '\0', - '\0']), ('\u{13b6}', ['\u{ab86}', '\0', '\0']), ('\u{13b7}', ['\u{ab87}', '\0', '\0']), - ('\u{13b8}', ['\u{ab88}', '\0', '\0']), ('\u{13b9}', ['\u{ab89}', '\0', '\0']), ('\u{13ba}', - ['\u{ab8a}', '\0', '\0']), ('\u{13bb}', ['\u{ab8b}', '\0', '\0']), ('\u{13bc}', ['\u{ab8c}', - '\0', '\0']), ('\u{13bd}', ['\u{ab8d}', '\0', '\0']), ('\u{13be}', ['\u{ab8e}', '\0', - '\0']), ('\u{13bf}', ['\u{ab8f}', '\0', '\0']), ('\u{13c0}', ['\u{ab90}', '\0', '\0']), - ('\u{13c1}', ['\u{ab91}', '\0', '\0']), ('\u{13c2}', ['\u{ab92}', '\0', '\0']), ('\u{13c3}', - ['\u{ab93}', '\0', '\0']), ('\u{13c4}', ['\u{ab94}', '\0', '\0']), ('\u{13c5}', ['\u{ab95}', - '\0', '\0']), ('\u{13c6}', ['\u{ab96}', '\0', '\0']), ('\u{13c7}', ['\u{ab97}', '\0', - '\0']), ('\u{13c8}', ['\u{ab98}', '\0', '\0']), ('\u{13c9}', ['\u{ab99}', '\0', '\0']), - ('\u{13ca}', ['\u{ab9a}', '\0', '\0']), ('\u{13cb}', ['\u{ab9b}', '\0', '\0']), ('\u{13cc}', - ['\u{ab9c}', '\0', '\0']), ('\u{13cd}', ['\u{ab9d}', '\0', '\0']), ('\u{13ce}', ['\u{ab9e}', - '\0', '\0']), ('\u{13cf}', ['\u{ab9f}', '\0', '\0']), ('\u{13d0}', ['\u{aba0}', '\0', - '\0']), ('\u{13d1}', ['\u{aba1}', '\0', '\0']), ('\u{13d2}', ['\u{aba2}', '\0', '\0']), - ('\u{13d3}', ['\u{aba3}', '\0', '\0']), ('\u{13d4}', ['\u{aba4}', '\0', '\0']), ('\u{13d5}', - ['\u{aba5}', '\0', '\0']), ('\u{13d6}', ['\u{aba6}', '\0', '\0']), ('\u{13d7}', ['\u{aba7}', - '\0', '\0']), ('\u{13d8}', ['\u{aba8}', '\0', '\0']), ('\u{13d9}', ['\u{aba9}', '\0', - '\0']), ('\u{13da}', ['\u{abaa}', '\0', '\0']), ('\u{13db}', ['\u{abab}', '\0', '\0']), - ('\u{13dc}', ['\u{abac}', '\0', '\0']), ('\u{13dd}', ['\u{abad}', '\0', '\0']), ('\u{13de}', - ['\u{abae}', '\0', '\0']), ('\u{13df}', ['\u{abaf}', '\0', '\0']), ('\u{13e0}', ['\u{abb0}', - '\0', '\0']), ('\u{13e1}', ['\u{abb1}', '\0', '\0']), ('\u{13e2}', ['\u{abb2}', '\0', - '\0']), ('\u{13e3}', ['\u{abb3}', '\0', '\0']), ('\u{13e4}', ['\u{abb4}', '\0', '\0']), - ('\u{13e5}', ['\u{abb5}', '\0', '\0']), ('\u{13e6}', ['\u{abb6}', '\0', '\0']), ('\u{13e7}', - ['\u{abb7}', '\0', '\0']), ('\u{13e8}', ['\u{abb8}', '\0', '\0']), ('\u{13e9}', ['\u{abb9}', - '\0', '\0']), ('\u{13ea}', ['\u{abba}', '\0', '\0']), ('\u{13eb}', ['\u{abbb}', '\0', - '\0']), ('\u{13ec}', ['\u{abbc}', '\0', '\0']), ('\u{13ed}', ['\u{abbd}', '\0', '\0']), - ('\u{13ee}', ['\u{abbe}', '\0', '\0']), ('\u{13ef}', ['\u{abbf}', '\0', '\0']), ('\u{13f0}', - ['\u{13f8}', '\0', '\0']), ('\u{13f1}', ['\u{13f9}', '\0', '\0']), ('\u{13f2}', ['\u{13fa}', - '\0', '\0']), ('\u{13f3}', ['\u{13fb}', '\0', '\0']), ('\u{13f4}', ['\u{13fc}', '\0', - '\0']), ('\u{13f5}', ['\u{13fd}', '\0', '\0']), ('\u{1c90}', ['\u{10d0}', '\0', '\0']), - ('\u{1c91}', ['\u{10d1}', '\0', '\0']), ('\u{1c92}', ['\u{10d2}', '\0', '\0']), ('\u{1c93}', - ['\u{10d3}', '\0', '\0']), ('\u{1c94}', ['\u{10d4}', '\0', '\0']), ('\u{1c95}', ['\u{10d5}', - '\0', '\0']), ('\u{1c96}', ['\u{10d6}', '\0', '\0']), ('\u{1c97}', ['\u{10d7}', '\0', - '\0']), ('\u{1c98}', ['\u{10d8}', '\0', '\0']), ('\u{1c99}', ['\u{10d9}', '\0', '\0']), - ('\u{1c9a}', ['\u{10da}', '\0', '\0']), ('\u{1c9b}', ['\u{10db}', '\0', '\0']), ('\u{1c9c}', - ['\u{10dc}', '\0', '\0']), ('\u{1c9d}', ['\u{10dd}', '\0', '\0']), ('\u{1c9e}', ['\u{10de}', - '\0', '\0']), ('\u{1c9f}', ['\u{10df}', '\0', '\0']), ('\u{1ca0}', ['\u{10e0}', '\0', - '\0']), ('\u{1ca1}', ['\u{10e1}', '\0', '\0']), ('\u{1ca2}', ['\u{10e2}', '\0', '\0']), - ('\u{1ca3}', ['\u{10e3}', '\0', '\0']), ('\u{1ca4}', ['\u{10e4}', '\0', '\0']), ('\u{1ca5}', - ['\u{10e5}', '\0', '\0']), ('\u{1ca6}', ['\u{10e6}', '\0', '\0']), ('\u{1ca7}', ['\u{10e7}', - '\0', '\0']), ('\u{1ca8}', ['\u{10e8}', '\0', '\0']), ('\u{1ca9}', ['\u{10e9}', '\0', - '\0']), ('\u{1caa}', ['\u{10ea}', '\0', '\0']), ('\u{1cab}', ['\u{10eb}', '\0', '\0']), - ('\u{1cac}', ['\u{10ec}', '\0', '\0']), ('\u{1cad}', ['\u{10ed}', '\0', '\0']), ('\u{1cae}', - ['\u{10ee}', '\0', '\0']), ('\u{1caf}', ['\u{10ef}', '\0', '\0']), ('\u{1cb0}', ['\u{10f0}', - '\0', '\0']), ('\u{1cb1}', ['\u{10f1}', '\0', '\0']), ('\u{1cb2}', ['\u{10f2}', '\0', - '\0']), ('\u{1cb3}', ['\u{10f3}', '\0', '\0']), ('\u{1cb4}', ['\u{10f4}', '\0', '\0']), - ('\u{1cb5}', ['\u{10f5}', '\0', '\0']), ('\u{1cb6}', ['\u{10f6}', '\0', '\0']), ('\u{1cb7}', - ['\u{10f7}', '\0', '\0']), ('\u{1cb8}', ['\u{10f8}', '\0', '\0']), ('\u{1cb9}', ['\u{10f9}', - '\0', '\0']), ('\u{1cba}', ['\u{10fa}', '\0', '\0']), ('\u{1cbd}', ['\u{10fd}', '\0', - '\0']), ('\u{1cbe}', ['\u{10fe}', '\0', '\0']), ('\u{1cbf}', ['\u{10ff}', '\0', '\0']), - ('\u{1e00}', ['\u{1e01}', '\0', '\0']), ('\u{1e02}', ['\u{1e03}', '\0', '\0']), ('\u{1e04}', - ['\u{1e05}', '\0', '\0']), ('\u{1e06}', ['\u{1e07}', '\0', '\0']), ('\u{1e08}', ['\u{1e09}', - '\0', '\0']), ('\u{1e0a}', ['\u{1e0b}', '\0', '\0']), ('\u{1e0c}', ['\u{1e0d}', '\0', - '\0']), ('\u{1e0e}', ['\u{1e0f}', '\0', '\0']), ('\u{1e10}', ['\u{1e11}', '\0', '\0']), - ('\u{1e12}', ['\u{1e13}', '\0', '\0']), ('\u{1e14}', ['\u{1e15}', '\0', '\0']), ('\u{1e16}', - ['\u{1e17}', '\0', '\0']), ('\u{1e18}', ['\u{1e19}', '\0', '\0']), ('\u{1e1a}', ['\u{1e1b}', - '\0', '\0']), ('\u{1e1c}', ['\u{1e1d}', '\0', '\0']), ('\u{1e1e}', ['\u{1e1f}', '\0', - '\0']), ('\u{1e20}', ['\u{1e21}', '\0', '\0']), ('\u{1e22}', ['\u{1e23}', '\0', '\0']), - ('\u{1e24}', ['\u{1e25}', '\0', '\0']), ('\u{1e26}', ['\u{1e27}', '\0', '\0']), ('\u{1e28}', - ['\u{1e29}', '\0', '\0']), ('\u{1e2a}', ['\u{1e2b}', '\0', '\0']), ('\u{1e2c}', ['\u{1e2d}', - '\0', '\0']), ('\u{1e2e}', ['\u{1e2f}', '\0', '\0']), ('\u{1e30}', ['\u{1e31}', '\0', - '\0']), ('\u{1e32}', ['\u{1e33}', '\0', '\0']), ('\u{1e34}', ['\u{1e35}', '\0', '\0']), - ('\u{1e36}', ['\u{1e37}', '\0', '\0']), ('\u{1e38}', ['\u{1e39}', '\0', '\0']), ('\u{1e3a}', - ['\u{1e3b}', '\0', '\0']), ('\u{1e3c}', ['\u{1e3d}', '\0', '\0']), ('\u{1e3e}', ['\u{1e3f}', - '\0', '\0']), ('\u{1e40}', ['\u{1e41}', '\0', '\0']), ('\u{1e42}', ['\u{1e43}', '\0', - '\0']), ('\u{1e44}', ['\u{1e45}', '\0', '\0']), ('\u{1e46}', ['\u{1e47}', '\0', '\0']), - ('\u{1e48}', ['\u{1e49}', '\0', '\0']), ('\u{1e4a}', ['\u{1e4b}', '\0', '\0']), ('\u{1e4c}', - ['\u{1e4d}', '\0', '\0']), ('\u{1e4e}', ['\u{1e4f}', '\0', '\0']), ('\u{1e50}', ['\u{1e51}', - '\0', '\0']), ('\u{1e52}', ['\u{1e53}', '\0', '\0']), ('\u{1e54}', ['\u{1e55}', '\0', - '\0']), ('\u{1e56}', ['\u{1e57}', '\0', '\0']), ('\u{1e58}', ['\u{1e59}', '\0', '\0']), - ('\u{1e5a}', ['\u{1e5b}', '\0', '\0']), ('\u{1e5c}', ['\u{1e5d}', '\0', '\0']), ('\u{1e5e}', - ['\u{1e5f}', '\0', '\0']), ('\u{1e60}', ['\u{1e61}', '\0', '\0']), ('\u{1e62}', ['\u{1e63}', - '\0', '\0']), ('\u{1e64}', ['\u{1e65}', '\0', '\0']), ('\u{1e66}', ['\u{1e67}', '\0', - '\0']), ('\u{1e68}', ['\u{1e69}', '\0', '\0']), ('\u{1e6a}', ['\u{1e6b}', '\0', '\0']), - ('\u{1e6c}', ['\u{1e6d}', '\0', '\0']), ('\u{1e6e}', ['\u{1e6f}', '\0', '\0']), ('\u{1e70}', - ['\u{1e71}', '\0', '\0']), ('\u{1e72}', ['\u{1e73}', '\0', '\0']), ('\u{1e74}', ['\u{1e75}', - '\0', '\0']), ('\u{1e76}', ['\u{1e77}', '\0', '\0']), ('\u{1e78}', ['\u{1e79}', '\0', - '\0']), ('\u{1e7a}', ['\u{1e7b}', '\0', '\0']), ('\u{1e7c}', ['\u{1e7d}', '\0', '\0']), - ('\u{1e7e}', ['\u{1e7f}', '\0', '\0']), ('\u{1e80}', ['\u{1e81}', '\0', '\0']), ('\u{1e82}', - ['\u{1e83}', '\0', '\0']), ('\u{1e84}', ['\u{1e85}', '\0', '\0']), ('\u{1e86}', ['\u{1e87}', - '\0', '\0']), ('\u{1e88}', ['\u{1e89}', '\0', '\0']), ('\u{1e8a}', ['\u{1e8b}', '\0', - '\0']), ('\u{1e8c}', ['\u{1e8d}', '\0', '\0']), ('\u{1e8e}', ['\u{1e8f}', '\0', '\0']), - ('\u{1e90}', ['\u{1e91}', '\0', '\0']), ('\u{1e92}', ['\u{1e93}', '\0', '\0']), ('\u{1e94}', - ['\u{1e95}', '\0', '\0']), ('\u{1e9e}', ['\u{df}', '\0', '\0']), ('\u{1ea0}', ['\u{1ea1}', - '\0', '\0']), ('\u{1ea2}', ['\u{1ea3}', '\0', '\0']), ('\u{1ea4}', ['\u{1ea5}', '\0', - '\0']), ('\u{1ea6}', ['\u{1ea7}', '\0', '\0']), ('\u{1ea8}', ['\u{1ea9}', '\0', '\0']), - ('\u{1eaa}', ['\u{1eab}', '\0', '\0']), ('\u{1eac}', ['\u{1ead}', '\0', '\0']), ('\u{1eae}', - ['\u{1eaf}', '\0', '\0']), ('\u{1eb0}', ['\u{1eb1}', '\0', '\0']), ('\u{1eb2}', ['\u{1eb3}', - '\0', '\0']), ('\u{1eb4}', ['\u{1eb5}', '\0', '\0']), ('\u{1eb6}', ['\u{1eb7}', '\0', - '\0']), ('\u{1eb8}', ['\u{1eb9}', '\0', '\0']), ('\u{1eba}', ['\u{1ebb}', '\0', '\0']), - ('\u{1ebc}', ['\u{1ebd}', '\0', '\0']), ('\u{1ebe}', ['\u{1ebf}', '\0', '\0']), ('\u{1ec0}', - ['\u{1ec1}', '\0', '\0']), ('\u{1ec2}', ['\u{1ec3}', '\0', '\0']), ('\u{1ec4}', ['\u{1ec5}', - '\0', '\0']), ('\u{1ec6}', ['\u{1ec7}', '\0', '\0']), ('\u{1ec8}', ['\u{1ec9}', '\0', - '\0']), ('\u{1eca}', ['\u{1ecb}', '\0', '\0']), ('\u{1ecc}', ['\u{1ecd}', '\0', '\0']), - ('\u{1ece}', ['\u{1ecf}', '\0', '\0']), ('\u{1ed0}', ['\u{1ed1}', '\0', '\0']), ('\u{1ed2}', - ['\u{1ed3}', '\0', '\0']), ('\u{1ed4}', ['\u{1ed5}', '\0', '\0']), ('\u{1ed6}', ['\u{1ed7}', - '\0', '\0']), ('\u{1ed8}', ['\u{1ed9}', '\0', '\0']), ('\u{1eda}', ['\u{1edb}', '\0', - '\0']), ('\u{1edc}', ['\u{1edd}', '\0', '\0']), ('\u{1ede}', ['\u{1edf}', '\0', '\0']), - ('\u{1ee0}', ['\u{1ee1}', '\0', '\0']), ('\u{1ee2}', ['\u{1ee3}', '\0', '\0']), ('\u{1ee4}', - ['\u{1ee5}', '\0', '\0']), ('\u{1ee6}', ['\u{1ee7}', '\0', '\0']), ('\u{1ee8}', ['\u{1ee9}', - '\0', '\0']), ('\u{1eea}', ['\u{1eeb}', '\0', '\0']), ('\u{1eec}', ['\u{1eed}', '\0', - '\0']), ('\u{1eee}', ['\u{1eef}', '\0', '\0']), ('\u{1ef0}', ['\u{1ef1}', '\0', '\0']), - ('\u{1ef2}', ['\u{1ef3}', '\0', '\0']), ('\u{1ef4}', ['\u{1ef5}', '\0', '\0']), ('\u{1ef6}', - ['\u{1ef7}', '\0', '\0']), ('\u{1ef8}', ['\u{1ef9}', '\0', '\0']), ('\u{1efa}', ['\u{1efb}', - '\0', '\0']), ('\u{1efc}', ['\u{1efd}', '\0', '\0']), ('\u{1efe}', ['\u{1eff}', '\0', - '\0']), ('\u{1f08}', ['\u{1f00}', '\0', '\0']), ('\u{1f09}', ['\u{1f01}', '\0', '\0']), - ('\u{1f0a}', ['\u{1f02}', '\0', '\0']), ('\u{1f0b}', ['\u{1f03}', '\0', '\0']), ('\u{1f0c}', - ['\u{1f04}', '\0', '\0']), ('\u{1f0d}', ['\u{1f05}', '\0', '\0']), ('\u{1f0e}', ['\u{1f06}', - '\0', '\0']), ('\u{1f0f}', ['\u{1f07}', '\0', '\0']), ('\u{1f18}', ['\u{1f10}', '\0', - '\0']), ('\u{1f19}', ['\u{1f11}', '\0', '\0']), ('\u{1f1a}', ['\u{1f12}', '\0', '\0']), - ('\u{1f1b}', ['\u{1f13}', '\0', '\0']), ('\u{1f1c}', ['\u{1f14}', '\0', '\0']), ('\u{1f1d}', - ['\u{1f15}', '\0', '\0']), ('\u{1f28}', ['\u{1f20}', '\0', '\0']), ('\u{1f29}', ['\u{1f21}', - '\0', '\0']), ('\u{1f2a}', ['\u{1f22}', '\0', '\0']), ('\u{1f2b}', ['\u{1f23}', '\0', - '\0']), ('\u{1f2c}', ['\u{1f24}', '\0', '\0']), ('\u{1f2d}', ['\u{1f25}', '\0', '\0']), - ('\u{1f2e}', ['\u{1f26}', '\0', '\0']), ('\u{1f2f}', ['\u{1f27}', '\0', '\0']), ('\u{1f38}', - ['\u{1f30}', '\0', '\0']), ('\u{1f39}', ['\u{1f31}', '\0', '\0']), ('\u{1f3a}', ['\u{1f32}', - '\0', '\0']), ('\u{1f3b}', ['\u{1f33}', '\0', '\0']), ('\u{1f3c}', ['\u{1f34}', '\0', - '\0']), ('\u{1f3d}', ['\u{1f35}', '\0', '\0']), ('\u{1f3e}', ['\u{1f36}', '\0', '\0']), - ('\u{1f3f}', ['\u{1f37}', '\0', '\0']), ('\u{1f48}', ['\u{1f40}', '\0', '\0']), ('\u{1f49}', - ['\u{1f41}', '\0', '\0']), ('\u{1f4a}', ['\u{1f42}', '\0', '\0']), ('\u{1f4b}', ['\u{1f43}', - '\0', '\0']), ('\u{1f4c}', ['\u{1f44}', '\0', '\0']), ('\u{1f4d}', ['\u{1f45}', '\0', - '\0']), ('\u{1f59}', ['\u{1f51}', '\0', '\0']), ('\u{1f5b}', ['\u{1f53}', '\0', '\0']), - ('\u{1f5d}', ['\u{1f55}', '\0', '\0']), ('\u{1f5f}', ['\u{1f57}', '\0', '\0']), ('\u{1f68}', - ['\u{1f60}', '\0', '\0']), ('\u{1f69}', ['\u{1f61}', '\0', '\0']), ('\u{1f6a}', ['\u{1f62}', - '\0', '\0']), ('\u{1f6b}', ['\u{1f63}', '\0', '\0']), ('\u{1f6c}', ['\u{1f64}', '\0', - '\0']), ('\u{1f6d}', ['\u{1f65}', '\0', '\0']), ('\u{1f6e}', ['\u{1f66}', '\0', '\0']), - ('\u{1f6f}', ['\u{1f67}', '\0', '\0']), ('\u{1f88}', ['\u{1f80}', '\0', '\0']), ('\u{1f89}', - ['\u{1f81}', '\0', '\0']), ('\u{1f8a}', ['\u{1f82}', '\0', '\0']), ('\u{1f8b}', ['\u{1f83}', - '\0', '\0']), ('\u{1f8c}', ['\u{1f84}', '\0', '\0']), ('\u{1f8d}', ['\u{1f85}', '\0', - '\0']), ('\u{1f8e}', ['\u{1f86}', '\0', '\0']), ('\u{1f8f}', ['\u{1f87}', '\0', '\0']), - ('\u{1f98}', ['\u{1f90}', '\0', '\0']), ('\u{1f99}', ['\u{1f91}', '\0', '\0']), ('\u{1f9a}', - ['\u{1f92}', '\0', '\0']), ('\u{1f9b}', ['\u{1f93}', '\0', '\0']), ('\u{1f9c}', ['\u{1f94}', - '\0', '\0']), ('\u{1f9d}', ['\u{1f95}', '\0', '\0']), ('\u{1f9e}', ['\u{1f96}', '\0', - '\0']), ('\u{1f9f}', ['\u{1f97}', '\0', '\0']), ('\u{1fa8}', ['\u{1fa0}', '\0', '\0']), - ('\u{1fa9}', ['\u{1fa1}', '\0', '\0']), ('\u{1faa}', ['\u{1fa2}', '\0', '\0']), ('\u{1fab}', - ['\u{1fa3}', '\0', '\0']), ('\u{1fac}', ['\u{1fa4}', '\0', '\0']), ('\u{1fad}', ['\u{1fa5}', - '\0', '\0']), ('\u{1fae}', ['\u{1fa6}', '\0', '\0']), ('\u{1faf}', ['\u{1fa7}', '\0', - '\0']), ('\u{1fb8}', ['\u{1fb0}', '\0', '\0']), ('\u{1fb9}', ['\u{1fb1}', '\0', '\0']), - ('\u{1fba}', ['\u{1f70}', '\0', '\0']), ('\u{1fbb}', ['\u{1f71}', '\0', '\0']), ('\u{1fbc}', - ['\u{1fb3}', '\0', '\0']), ('\u{1fc8}', ['\u{1f72}', '\0', '\0']), ('\u{1fc9}', ['\u{1f73}', - '\0', '\0']), ('\u{1fca}', ['\u{1f74}', '\0', '\0']), ('\u{1fcb}', ['\u{1f75}', '\0', - '\0']), ('\u{1fcc}', ['\u{1fc3}', '\0', '\0']), ('\u{1fd8}', ['\u{1fd0}', '\0', '\0']), - ('\u{1fd9}', ['\u{1fd1}', '\0', '\0']), ('\u{1fda}', ['\u{1f76}', '\0', '\0']), ('\u{1fdb}', - ['\u{1f77}', '\0', '\0']), ('\u{1fe8}', ['\u{1fe0}', '\0', '\0']), ('\u{1fe9}', ['\u{1fe1}', - '\0', '\0']), ('\u{1fea}', ['\u{1f7a}', '\0', '\0']), ('\u{1feb}', ['\u{1f7b}', '\0', - '\0']), ('\u{1fec}', ['\u{1fe5}', '\0', '\0']), ('\u{1ff8}', ['\u{1f78}', '\0', '\0']), - ('\u{1ff9}', ['\u{1f79}', '\0', '\0']), ('\u{1ffa}', ['\u{1f7c}', '\0', '\0']), ('\u{1ffb}', - ['\u{1f7d}', '\0', '\0']), ('\u{1ffc}', ['\u{1ff3}', '\0', '\0']), ('\u{2126}', ['\u{3c9}', - '\0', '\0']), ('\u{212a}', ['\u{6b}', '\0', '\0']), ('\u{212b}', ['\u{e5}', '\0', '\0']), - ('\u{2132}', ['\u{214e}', '\0', '\0']), ('\u{2160}', ['\u{2170}', '\0', '\0']), ('\u{2161}', - ['\u{2171}', '\0', '\0']), ('\u{2162}', ['\u{2172}', '\0', '\0']), ('\u{2163}', ['\u{2173}', - '\0', '\0']), ('\u{2164}', ['\u{2174}', '\0', '\0']), ('\u{2165}', ['\u{2175}', '\0', - '\0']), ('\u{2166}', ['\u{2176}', '\0', '\0']), ('\u{2167}', ['\u{2177}', '\0', '\0']), - ('\u{2168}', ['\u{2178}', '\0', '\0']), ('\u{2169}', ['\u{2179}', '\0', '\0']), ('\u{216a}', - ['\u{217a}', '\0', '\0']), ('\u{216b}', ['\u{217b}', '\0', '\0']), ('\u{216c}', ['\u{217c}', - '\0', '\0']), ('\u{216d}', ['\u{217d}', '\0', '\0']), ('\u{216e}', ['\u{217e}', '\0', - '\0']), ('\u{216f}', ['\u{217f}', '\0', '\0']), ('\u{2183}', ['\u{2184}', '\0', '\0']), - ('\u{24b6}', ['\u{24d0}', '\0', '\0']), ('\u{24b7}', ['\u{24d1}', '\0', '\0']), ('\u{24b8}', - ['\u{24d2}', '\0', '\0']), ('\u{24b9}', ['\u{24d3}', '\0', '\0']), ('\u{24ba}', ['\u{24d4}', - '\0', '\0']), ('\u{24bb}', ['\u{24d5}', '\0', '\0']), ('\u{24bc}', ['\u{24d6}', '\0', - '\0']), ('\u{24bd}', ['\u{24d7}', '\0', '\0']), ('\u{24be}', ['\u{24d8}', '\0', '\0']), - ('\u{24bf}', ['\u{24d9}', '\0', '\0']), ('\u{24c0}', ['\u{24da}', '\0', '\0']), ('\u{24c1}', - ['\u{24db}', '\0', '\0']), ('\u{24c2}', ['\u{24dc}', '\0', '\0']), ('\u{24c3}', ['\u{24dd}', - '\0', '\0']), ('\u{24c4}', ['\u{24de}', '\0', '\0']), ('\u{24c5}', ['\u{24df}', '\0', - '\0']), ('\u{24c6}', ['\u{24e0}', '\0', '\0']), ('\u{24c7}', ['\u{24e1}', '\0', '\0']), - ('\u{24c8}', ['\u{24e2}', '\0', '\0']), ('\u{24c9}', ['\u{24e3}', '\0', '\0']), ('\u{24ca}', - ['\u{24e4}', '\0', '\0']), ('\u{24cb}', ['\u{24e5}', '\0', '\0']), ('\u{24cc}', ['\u{24e6}', - '\0', '\0']), ('\u{24cd}', ['\u{24e7}', '\0', '\0']), ('\u{24ce}', ['\u{24e8}', '\0', - '\0']), ('\u{24cf}', ['\u{24e9}', '\0', '\0']), ('\u{2c00}', ['\u{2c30}', '\0', '\0']), - ('\u{2c01}', ['\u{2c31}', '\0', '\0']), ('\u{2c02}', ['\u{2c32}', '\0', '\0']), ('\u{2c03}', - ['\u{2c33}', '\0', '\0']), ('\u{2c04}', ['\u{2c34}', '\0', '\0']), ('\u{2c05}', ['\u{2c35}', - '\0', '\0']), ('\u{2c06}', ['\u{2c36}', '\0', '\0']), ('\u{2c07}', ['\u{2c37}', '\0', - '\0']), ('\u{2c08}', ['\u{2c38}', '\0', '\0']), ('\u{2c09}', ['\u{2c39}', '\0', '\0']), - ('\u{2c0a}', ['\u{2c3a}', '\0', '\0']), ('\u{2c0b}', ['\u{2c3b}', '\0', '\0']), ('\u{2c0c}', - ['\u{2c3c}', '\0', '\0']), ('\u{2c0d}', ['\u{2c3d}', '\0', '\0']), ('\u{2c0e}', ['\u{2c3e}', - '\0', '\0']), ('\u{2c0f}', ['\u{2c3f}', '\0', '\0']), ('\u{2c10}', ['\u{2c40}', '\0', - '\0']), ('\u{2c11}', ['\u{2c41}', '\0', '\0']), ('\u{2c12}', ['\u{2c42}', '\0', '\0']), - ('\u{2c13}', ['\u{2c43}', '\0', '\0']), ('\u{2c14}', ['\u{2c44}', '\0', '\0']), ('\u{2c15}', - ['\u{2c45}', '\0', '\0']), ('\u{2c16}', ['\u{2c46}', '\0', '\0']), ('\u{2c17}', ['\u{2c47}', - '\0', '\0']), ('\u{2c18}', ['\u{2c48}', '\0', '\0']), ('\u{2c19}', ['\u{2c49}', '\0', - '\0']), ('\u{2c1a}', ['\u{2c4a}', '\0', '\0']), ('\u{2c1b}', ['\u{2c4b}', '\0', '\0']), - ('\u{2c1c}', ['\u{2c4c}', '\0', '\0']), ('\u{2c1d}', ['\u{2c4d}', '\0', '\0']), ('\u{2c1e}', - ['\u{2c4e}', '\0', '\0']), ('\u{2c1f}', ['\u{2c4f}', '\0', '\0']), ('\u{2c20}', ['\u{2c50}', - '\0', '\0']), ('\u{2c21}', ['\u{2c51}', '\0', '\0']), ('\u{2c22}', ['\u{2c52}', '\0', - '\0']), ('\u{2c23}', ['\u{2c53}', '\0', '\0']), ('\u{2c24}', ['\u{2c54}', '\0', '\0']), - ('\u{2c25}', ['\u{2c55}', '\0', '\0']), ('\u{2c26}', ['\u{2c56}', '\0', '\0']), ('\u{2c27}', - ['\u{2c57}', '\0', '\0']), ('\u{2c28}', ['\u{2c58}', '\0', '\0']), ('\u{2c29}', ['\u{2c59}', - '\0', '\0']), ('\u{2c2a}', ['\u{2c5a}', '\0', '\0']), ('\u{2c2b}', ['\u{2c5b}', '\0', - '\0']), ('\u{2c2c}', ['\u{2c5c}', '\0', '\0']), ('\u{2c2d}', ['\u{2c5d}', '\0', '\0']), - ('\u{2c2e}', ['\u{2c5e}', '\0', '\0']), ('\u{2c60}', ['\u{2c61}', '\0', '\0']), ('\u{2c62}', - ['\u{26b}', '\0', '\0']), ('\u{2c63}', ['\u{1d7d}', '\0', '\0']), ('\u{2c64}', ['\u{27d}', - '\0', '\0']), ('\u{2c67}', ['\u{2c68}', '\0', '\0']), ('\u{2c69}', ['\u{2c6a}', '\0', - '\0']), ('\u{2c6b}', ['\u{2c6c}', '\0', '\0']), ('\u{2c6d}', ['\u{251}', '\0', '\0']), - ('\u{2c6e}', ['\u{271}', '\0', '\0']), ('\u{2c6f}', ['\u{250}', '\0', '\0']), ('\u{2c70}', - ['\u{252}', '\0', '\0']), ('\u{2c72}', ['\u{2c73}', '\0', '\0']), ('\u{2c75}', ['\u{2c76}', - '\0', '\0']), ('\u{2c7e}', ['\u{23f}', '\0', '\0']), ('\u{2c7f}', ['\u{240}', '\0', '\0']), - ('\u{2c80}', ['\u{2c81}', '\0', '\0']), ('\u{2c82}', ['\u{2c83}', '\0', '\0']), ('\u{2c84}', - ['\u{2c85}', '\0', '\0']), ('\u{2c86}', ['\u{2c87}', '\0', '\0']), ('\u{2c88}', ['\u{2c89}', - '\0', '\0']), ('\u{2c8a}', ['\u{2c8b}', '\0', '\0']), ('\u{2c8c}', ['\u{2c8d}', '\0', - '\0']), ('\u{2c8e}', ['\u{2c8f}', '\0', '\0']), ('\u{2c90}', ['\u{2c91}', '\0', '\0']), - ('\u{2c92}', ['\u{2c93}', '\0', '\0']), ('\u{2c94}', ['\u{2c95}', '\0', '\0']), ('\u{2c96}', - ['\u{2c97}', '\0', '\0']), ('\u{2c98}', ['\u{2c99}', '\0', '\0']), ('\u{2c9a}', ['\u{2c9b}', - '\0', '\0']), ('\u{2c9c}', ['\u{2c9d}', '\0', '\0']), ('\u{2c9e}', ['\u{2c9f}', '\0', - '\0']), ('\u{2ca0}', ['\u{2ca1}', '\0', '\0']), ('\u{2ca2}', ['\u{2ca3}', '\0', '\0']), - ('\u{2ca4}', ['\u{2ca5}', '\0', '\0']), ('\u{2ca6}', ['\u{2ca7}', '\0', '\0']), ('\u{2ca8}', - ['\u{2ca9}', '\0', '\0']), ('\u{2caa}', ['\u{2cab}', '\0', '\0']), ('\u{2cac}', ['\u{2cad}', - '\0', '\0']), ('\u{2cae}', ['\u{2caf}', '\0', '\0']), ('\u{2cb0}', ['\u{2cb1}', '\0', - '\0']), ('\u{2cb2}', ['\u{2cb3}', '\0', '\0']), ('\u{2cb4}', ['\u{2cb5}', '\0', '\0']), - ('\u{2cb6}', ['\u{2cb7}', '\0', '\0']), ('\u{2cb8}', ['\u{2cb9}', '\0', '\0']), ('\u{2cba}', - ['\u{2cbb}', '\0', '\0']), ('\u{2cbc}', ['\u{2cbd}', '\0', '\0']), ('\u{2cbe}', ['\u{2cbf}', - '\0', '\0']), ('\u{2cc0}', ['\u{2cc1}', '\0', '\0']), ('\u{2cc2}', ['\u{2cc3}', '\0', - '\0']), ('\u{2cc4}', ['\u{2cc5}', '\0', '\0']), ('\u{2cc6}', ['\u{2cc7}', '\0', '\0']), - ('\u{2cc8}', ['\u{2cc9}', '\0', '\0']), ('\u{2cca}', ['\u{2ccb}', '\0', '\0']), ('\u{2ccc}', - ['\u{2ccd}', '\0', '\0']), ('\u{2cce}', ['\u{2ccf}', '\0', '\0']), ('\u{2cd0}', ['\u{2cd1}', - '\0', '\0']), ('\u{2cd2}', ['\u{2cd3}', '\0', '\0']), ('\u{2cd4}', ['\u{2cd5}', '\0', - '\0']), ('\u{2cd6}', ['\u{2cd7}', '\0', '\0']), ('\u{2cd8}', ['\u{2cd9}', '\0', '\0']), - ('\u{2cda}', ['\u{2cdb}', '\0', '\0']), ('\u{2cdc}', ['\u{2cdd}', '\0', '\0']), ('\u{2cde}', - ['\u{2cdf}', '\0', '\0']), ('\u{2ce0}', ['\u{2ce1}', '\0', '\0']), ('\u{2ce2}', ['\u{2ce3}', - '\0', '\0']), ('\u{2ceb}', ['\u{2cec}', '\0', '\0']), ('\u{2ced}', ['\u{2cee}', '\0', - '\0']), ('\u{2cf2}', ['\u{2cf3}', '\0', '\0']), ('\u{a640}', ['\u{a641}', '\0', '\0']), - ('\u{a642}', ['\u{a643}', '\0', '\0']), ('\u{a644}', ['\u{a645}', '\0', '\0']), ('\u{a646}', - ['\u{a647}', '\0', '\0']), ('\u{a648}', ['\u{a649}', '\0', '\0']), ('\u{a64a}', ['\u{a64b}', - '\0', '\0']), ('\u{a64c}', ['\u{a64d}', '\0', '\0']), ('\u{a64e}', ['\u{a64f}', '\0', - '\0']), ('\u{a650}', ['\u{a651}', '\0', '\0']), ('\u{a652}', ['\u{a653}', '\0', '\0']), - ('\u{a654}', ['\u{a655}', '\0', '\0']), ('\u{a656}', ['\u{a657}', '\0', '\0']), ('\u{a658}', - ['\u{a659}', '\0', '\0']), ('\u{a65a}', ['\u{a65b}', '\0', '\0']), ('\u{a65c}', ['\u{a65d}', - '\0', '\0']), ('\u{a65e}', ['\u{a65f}', '\0', '\0']), ('\u{a660}', ['\u{a661}', '\0', - '\0']), ('\u{a662}', ['\u{a663}', '\0', '\0']), ('\u{a664}', ['\u{a665}', '\0', '\0']), - ('\u{a666}', ['\u{a667}', '\0', '\0']), ('\u{a668}', ['\u{a669}', '\0', '\0']), ('\u{a66a}', - ['\u{a66b}', '\0', '\0']), ('\u{a66c}', ['\u{a66d}', '\0', '\0']), ('\u{a680}', ['\u{a681}', - '\0', '\0']), ('\u{a682}', ['\u{a683}', '\0', '\0']), ('\u{a684}', ['\u{a685}', '\0', - '\0']), ('\u{a686}', ['\u{a687}', '\0', '\0']), ('\u{a688}', ['\u{a689}', '\0', '\0']), - ('\u{a68a}', ['\u{a68b}', '\0', '\0']), ('\u{a68c}', ['\u{a68d}', '\0', '\0']), ('\u{a68e}', - ['\u{a68f}', '\0', '\0']), ('\u{a690}', ['\u{a691}', '\0', '\0']), ('\u{a692}', ['\u{a693}', - '\0', '\0']), ('\u{a694}', ['\u{a695}', '\0', '\0']), ('\u{a696}', ['\u{a697}', '\0', - '\0']), ('\u{a698}', ['\u{a699}', '\0', '\0']), ('\u{a69a}', ['\u{a69b}', '\0', '\0']), - ('\u{a722}', ['\u{a723}', '\0', '\0']), ('\u{a724}', ['\u{a725}', '\0', '\0']), ('\u{a726}', - ['\u{a727}', '\0', '\0']), ('\u{a728}', ['\u{a729}', '\0', '\0']), ('\u{a72a}', ['\u{a72b}', - '\0', '\0']), ('\u{a72c}', ['\u{a72d}', '\0', '\0']), ('\u{a72e}', ['\u{a72f}', '\0', - '\0']), ('\u{a732}', ['\u{a733}', '\0', '\0']), ('\u{a734}', ['\u{a735}', '\0', '\0']), - ('\u{a736}', ['\u{a737}', '\0', '\0']), ('\u{a738}', ['\u{a739}', '\0', '\0']), ('\u{a73a}', - ['\u{a73b}', '\0', '\0']), ('\u{a73c}', ['\u{a73d}', '\0', '\0']), ('\u{a73e}', ['\u{a73f}', - '\0', '\0']), ('\u{a740}', ['\u{a741}', '\0', '\0']), ('\u{a742}', ['\u{a743}', '\0', - '\0']), ('\u{a744}', ['\u{a745}', '\0', '\0']), ('\u{a746}', ['\u{a747}', '\0', '\0']), - ('\u{a748}', ['\u{a749}', '\0', '\0']), ('\u{a74a}', ['\u{a74b}', '\0', '\0']), ('\u{a74c}', - ['\u{a74d}', '\0', '\0']), ('\u{a74e}', ['\u{a74f}', '\0', '\0']), ('\u{a750}', ['\u{a751}', - '\0', '\0']), ('\u{a752}', ['\u{a753}', '\0', '\0']), ('\u{a754}', ['\u{a755}', '\0', - '\0']), ('\u{a756}', ['\u{a757}', '\0', '\0']), ('\u{a758}', ['\u{a759}', '\0', '\0']), - ('\u{a75a}', ['\u{a75b}', '\0', '\0']), ('\u{a75c}', ['\u{a75d}', '\0', '\0']), ('\u{a75e}', - ['\u{a75f}', '\0', '\0']), ('\u{a760}', ['\u{a761}', '\0', '\0']), ('\u{a762}', ['\u{a763}', - '\0', '\0']), ('\u{a764}', ['\u{a765}', '\0', '\0']), ('\u{a766}', ['\u{a767}', '\0', - '\0']), ('\u{a768}', ['\u{a769}', '\0', '\0']), ('\u{a76a}', ['\u{a76b}', '\0', '\0']), - ('\u{a76c}', ['\u{a76d}', '\0', '\0']), ('\u{a76e}', ['\u{a76f}', '\0', '\0']), ('\u{a779}', - ['\u{a77a}', '\0', '\0']), ('\u{a77b}', ['\u{a77c}', '\0', '\0']), ('\u{a77d}', ['\u{1d79}', - '\0', '\0']), ('\u{a77e}', ['\u{a77f}', '\0', '\0']), ('\u{a780}', ['\u{a781}', '\0', - '\0']), ('\u{a782}', ['\u{a783}', '\0', '\0']), ('\u{a784}', ['\u{a785}', '\0', '\0']), - ('\u{a786}', ['\u{a787}', '\0', '\0']), ('\u{a78b}', ['\u{a78c}', '\0', '\0']), ('\u{a78d}', - ['\u{265}', '\0', '\0']), ('\u{a790}', ['\u{a791}', '\0', '\0']), ('\u{a792}', ['\u{a793}', - '\0', '\0']), ('\u{a796}', ['\u{a797}', '\0', '\0']), ('\u{a798}', ['\u{a799}', '\0', - '\0']), ('\u{a79a}', ['\u{a79b}', '\0', '\0']), ('\u{a79c}', ['\u{a79d}', '\0', '\0']), - ('\u{a79e}', ['\u{a79f}', '\0', '\0']), ('\u{a7a0}', ['\u{a7a1}', '\0', '\0']), ('\u{a7a2}', - ['\u{a7a3}', '\0', '\0']), ('\u{a7a4}', ['\u{a7a5}', '\0', '\0']), ('\u{a7a6}', ['\u{a7a7}', - '\0', '\0']), ('\u{a7a8}', ['\u{a7a9}', '\0', '\0']), ('\u{a7aa}', ['\u{266}', '\0', '\0']), - ('\u{a7ab}', ['\u{25c}', '\0', '\0']), ('\u{a7ac}', ['\u{261}', '\0', '\0']), ('\u{a7ad}', - ['\u{26c}', '\0', '\0']), ('\u{a7ae}', ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}', - '\0', '\0']), ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']), - ('\u{a7b3}', ['\u{ab53}', '\0', '\0']), ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}', - ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{a7ba}', ['\u{a7bb}', - '\0', '\0']), ('\u{a7bc}', ['\u{a7bd}', '\0', '\0']), ('\u{a7be}', ['\u{a7bf}', '\0', - '\0']), ('\u{a7c2}', ['\u{a7c3}', '\0', '\0']), ('\u{a7c4}', ['\u{a794}', '\0', '\0']), - ('\u{a7c5}', ['\u{282}', '\0', '\0']), ('\u{a7c6}', ['\u{1d8e}', '\0', '\0']), ('\u{ff21}', - ['\u{ff41}', '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', - '\0', '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', - '\0']), ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), - ('\u{ff28}', ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', - ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', - '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', - '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), - ('\u{ff31}', ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', - ['\u{ff53}', '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', - '\0', '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', - '\0']), ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), - ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), - ('\u{10401}', ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), - ('\u{10403}', ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), - ('\u{10405}', ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), - ('\u{10407}', ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), - ('\u{10409}', ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), - ('\u{1040b}', ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), - ('\u{1040d}', ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), - ('\u{1040f}', ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), - ('\u{10411}', ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), - ('\u{10413}', ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), - ('\u{10415}', ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), - ('\u{10417}', ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), - ('\u{10419}', ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), - ('\u{1041b}', ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), - ('\u{1041d}', ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), - ('\u{1041f}', ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), - ('\u{10421}', ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), - ('\u{10423}', ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), - ('\u{10425}', ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), - ('\u{10427}', ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), - ('\u{104b1}', ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), - ('\u{104b3}', ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), - ('\u{104b5}', ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), - ('\u{104b7}', ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), - ('\u{104b9}', ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), - ('\u{104bb}', ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), - ('\u{104bd}', ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), - ('\u{104bf}', ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), - ('\u{104c1}', ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), - ('\u{104c3}', ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), - ('\u{104c5}', ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), - ('\u{104c7}', ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), - ('\u{104c9}', ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), - ('\u{104cb}', ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), - ('\u{104cd}', ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), - ('\u{104cf}', ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), - ('\u{104d1}', ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), - ('\u{104d3}', ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), - ('\u{10c81}', ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), - ('\u{10c83}', ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), - ('\u{10c85}', ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), - ('\u{10c87}', ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), - ('\u{10c89}', ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), - ('\u{10c8b}', ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), - ('\u{10c8d}', ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), - ('\u{10c8f}', ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), - ('\u{10c91}', ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), - ('\u{10c93}', ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), - ('\u{10c95}', ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), - ('\u{10c97}', ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), - ('\u{10c99}', ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), - ('\u{10c9b}', ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), - ('\u{10c9d}', ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), - ('\u{10c9f}', ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), - ('\u{10ca1}', ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), - ('\u{10ca3}', ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), - ('\u{10ca5}', ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), - ('\u{10ca7}', ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), - ('\u{10ca9}', ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), - ('\u{10cab}', ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), - ('\u{10cad}', ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), - ('\u{10caf}', ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), - ('\u{10cb1}', ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), - ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), - ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), - ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), - ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), - ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), - ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), - ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), - ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), - ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), - ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), - ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), - ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), - ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), - ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), - ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), - ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), - ('\u{16e40}', ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), - ('\u{16e42}', ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), - ('\u{16e44}', ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), - ('\u{16e46}', ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), - ('\u{16e48}', ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), - ('\u{16e4a}', ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), - ('\u{16e4c}', ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), - ('\u{16e4e}', ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), - ('\u{16e50}', ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), - ('\u{16e52}', ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), - ('\u{16e54}', ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), - ('\u{16e56}', ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), - ('\u{16e58}', ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), - ('\u{16e5a}', ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), - ('\u{16e5c}', ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), - ('\u{16e5e}', ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), - ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), - ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), - ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), - ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), - ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), - ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), - ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), - ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), - ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), - ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), - ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), - ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), - ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), - ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), - ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), - ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), - ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0']) - ]; - - #[rustfmt::skip] - const to_uppercase_table: &[(char, [char; 3])] = &[ - ('\u{61}', ['\u{41}', '\0', '\0']), ('\u{62}', ['\u{42}', '\0', '\0']), ('\u{63}', - ['\u{43}', '\0', '\0']), ('\u{64}', ['\u{44}', '\0', '\0']), ('\u{65}', ['\u{45}', '\0', - '\0']), ('\u{66}', ['\u{46}', '\0', '\0']), ('\u{67}', ['\u{47}', '\0', '\0']), ('\u{68}', - ['\u{48}', '\0', '\0']), ('\u{69}', ['\u{49}', '\0', '\0']), ('\u{6a}', ['\u{4a}', '\0', - '\0']), ('\u{6b}', ['\u{4b}', '\0', '\0']), ('\u{6c}', ['\u{4c}', '\0', '\0']), ('\u{6d}', - ['\u{4d}', '\0', '\0']), ('\u{6e}', ['\u{4e}', '\0', '\0']), ('\u{6f}', ['\u{4f}', '\0', - '\0']), ('\u{70}', ['\u{50}', '\0', '\0']), ('\u{71}', ['\u{51}', '\0', '\0']), ('\u{72}', - ['\u{52}', '\0', '\0']), ('\u{73}', ['\u{53}', '\0', '\0']), ('\u{74}', ['\u{54}', '\0', - '\0']), ('\u{75}', ['\u{55}', '\0', '\0']), ('\u{76}', ['\u{56}', '\0', '\0']), ('\u{77}', - ['\u{57}', '\0', '\0']), ('\u{78}', ['\u{58}', '\0', '\0']), ('\u{79}', ['\u{59}', '\0', - '\0']), ('\u{7a}', ['\u{5a}', '\0', '\0']), ('\u{b5}', ['\u{39c}', '\0', '\0']), ('\u{df}', - ['\u{53}', '\u{53}', '\0']), ('\u{e0}', ['\u{c0}', '\0', '\0']), ('\u{e1}', ['\u{c1}', '\0', - '\0']), ('\u{e2}', ['\u{c2}', '\0', '\0']), ('\u{e3}', ['\u{c3}', '\0', '\0']), ('\u{e4}', - ['\u{c4}', '\0', '\0']), ('\u{e5}', ['\u{c5}', '\0', '\0']), ('\u{e6}', ['\u{c6}', '\0', - '\0']), ('\u{e7}', ['\u{c7}', '\0', '\0']), ('\u{e8}', ['\u{c8}', '\0', '\0']), ('\u{e9}', - ['\u{c9}', '\0', '\0']), ('\u{ea}', ['\u{ca}', '\0', '\0']), ('\u{eb}', ['\u{cb}', '\0', - '\0']), ('\u{ec}', ['\u{cc}', '\0', '\0']), ('\u{ed}', ['\u{cd}', '\0', '\0']), ('\u{ee}', - ['\u{ce}', '\0', '\0']), ('\u{ef}', ['\u{cf}', '\0', '\0']), ('\u{f0}', ['\u{d0}', '\0', - '\0']), ('\u{f1}', ['\u{d1}', '\0', '\0']), ('\u{f2}', ['\u{d2}', '\0', '\0']), ('\u{f3}', - ['\u{d3}', '\0', '\0']), ('\u{f4}', ['\u{d4}', '\0', '\0']), ('\u{f5}', ['\u{d5}', '\0', - '\0']), ('\u{f6}', ['\u{d6}', '\0', '\0']), ('\u{f8}', ['\u{d8}', '\0', '\0']), ('\u{f9}', - ['\u{d9}', '\0', '\0']), ('\u{fa}', ['\u{da}', '\0', '\0']), ('\u{fb}', ['\u{db}', '\0', - '\0']), ('\u{fc}', ['\u{dc}', '\0', '\0']), ('\u{fd}', ['\u{dd}', '\0', '\0']), ('\u{fe}', - ['\u{de}', '\0', '\0']), ('\u{ff}', ['\u{178}', '\0', '\0']), ('\u{101}', ['\u{100}', '\0', - '\0']), ('\u{103}', ['\u{102}', '\0', '\0']), ('\u{105}', ['\u{104}', '\0', '\0']), - ('\u{107}', ['\u{106}', '\0', '\0']), ('\u{109}', ['\u{108}', '\0', '\0']), ('\u{10b}', - ['\u{10a}', '\0', '\0']), ('\u{10d}', ['\u{10c}', '\0', '\0']), ('\u{10f}', ['\u{10e}', - '\0', '\0']), ('\u{111}', ['\u{110}', '\0', '\0']), ('\u{113}', ['\u{112}', '\0', '\0']), - ('\u{115}', ['\u{114}', '\0', '\0']), ('\u{117}', ['\u{116}', '\0', '\0']), ('\u{119}', - ['\u{118}', '\0', '\0']), ('\u{11b}', ['\u{11a}', '\0', '\0']), ('\u{11d}', ['\u{11c}', - '\0', '\0']), ('\u{11f}', ['\u{11e}', '\0', '\0']), ('\u{121}', ['\u{120}', '\0', '\0']), - ('\u{123}', ['\u{122}', '\0', '\0']), ('\u{125}', ['\u{124}', '\0', '\0']), ('\u{127}', - ['\u{126}', '\0', '\0']), ('\u{129}', ['\u{128}', '\0', '\0']), ('\u{12b}', ['\u{12a}', - '\0', '\0']), ('\u{12d}', ['\u{12c}', '\0', '\0']), ('\u{12f}', ['\u{12e}', '\0', '\0']), - ('\u{131}', ['\u{49}', '\0', '\0']), ('\u{133}', ['\u{132}', '\0', '\0']), ('\u{135}', - ['\u{134}', '\0', '\0']), ('\u{137}', ['\u{136}', '\0', '\0']), ('\u{13a}', ['\u{139}', - '\0', '\0']), ('\u{13c}', ['\u{13b}', '\0', '\0']), ('\u{13e}', ['\u{13d}', '\0', '\0']), - ('\u{140}', ['\u{13f}', '\0', '\0']), ('\u{142}', ['\u{141}', '\0', '\0']), ('\u{144}', - ['\u{143}', '\0', '\0']), ('\u{146}', ['\u{145}', '\0', '\0']), ('\u{148}', ['\u{147}', - '\0', '\0']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\0']), ('\u{14b}', ['\u{14a}', '\0', - '\0']), ('\u{14d}', ['\u{14c}', '\0', '\0']), ('\u{14f}', ['\u{14e}', '\0', '\0']), - ('\u{151}', ['\u{150}', '\0', '\0']), ('\u{153}', ['\u{152}', '\0', '\0']), ('\u{155}', - ['\u{154}', '\0', '\0']), ('\u{157}', ['\u{156}', '\0', '\0']), ('\u{159}', ['\u{158}', - '\0', '\0']), ('\u{15b}', ['\u{15a}', '\0', '\0']), ('\u{15d}', ['\u{15c}', '\0', '\0']), - ('\u{15f}', ['\u{15e}', '\0', '\0']), ('\u{161}', ['\u{160}', '\0', '\0']), ('\u{163}', - ['\u{162}', '\0', '\0']), ('\u{165}', ['\u{164}', '\0', '\0']), ('\u{167}', ['\u{166}', - '\0', '\0']), ('\u{169}', ['\u{168}', '\0', '\0']), ('\u{16b}', ['\u{16a}', '\0', '\0']), - ('\u{16d}', ['\u{16c}', '\0', '\0']), ('\u{16f}', ['\u{16e}', '\0', '\0']), ('\u{171}', - ['\u{170}', '\0', '\0']), ('\u{173}', ['\u{172}', '\0', '\0']), ('\u{175}', ['\u{174}', - '\0', '\0']), ('\u{177}', ['\u{176}', '\0', '\0']), ('\u{17a}', ['\u{179}', '\0', '\0']), - ('\u{17c}', ['\u{17b}', '\0', '\0']), ('\u{17e}', ['\u{17d}', '\0', '\0']), ('\u{17f}', - ['\u{53}', '\0', '\0']), ('\u{180}', ['\u{243}', '\0', '\0']), ('\u{183}', ['\u{182}', '\0', - '\0']), ('\u{185}', ['\u{184}', '\0', '\0']), ('\u{188}', ['\u{187}', '\0', '\0']), - ('\u{18c}', ['\u{18b}', '\0', '\0']), ('\u{192}', ['\u{191}', '\0', '\0']), ('\u{195}', - ['\u{1f6}', '\0', '\0']), ('\u{199}', ['\u{198}', '\0', '\0']), ('\u{19a}', ['\u{23d}', - '\0', '\0']), ('\u{19e}', ['\u{220}', '\0', '\0']), ('\u{1a1}', ['\u{1a0}', '\0', '\0']), - ('\u{1a3}', ['\u{1a2}', '\0', '\0']), ('\u{1a5}', ['\u{1a4}', '\0', '\0']), ('\u{1a8}', - ['\u{1a7}', '\0', '\0']), ('\u{1ad}', ['\u{1ac}', '\0', '\0']), ('\u{1b0}', ['\u{1af}', - '\0', '\0']), ('\u{1b4}', ['\u{1b3}', '\0', '\0']), ('\u{1b6}', ['\u{1b5}', '\0', '\0']), - ('\u{1b9}', ['\u{1b8}', '\0', '\0']), ('\u{1bd}', ['\u{1bc}', '\0', '\0']), ('\u{1bf}', - ['\u{1f7}', '\0', '\0']), ('\u{1c5}', ['\u{1c4}', '\0', '\0']), ('\u{1c6}', ['\u{1c4}', - '\0', '\0']), ('\u{1c8}', ['\u{1c7}', '\0', '\0']), ('\u{1c9}', ['\u{1c7}', '\0', '\0']), - ('\u{1cb}', ['\u{1ca}', '\0', '\0']), ('\u{1cc}', ['\u{1ca}', '\0', '\0']), ('\u{1ce}', - ['\u{1cd}', '\0', '\0']), ('\u{1d0}', ['\u{1cf}', '\0', '\0']), ('\u{1d2}', ['\u{1d1}', - '\0', '\0']), ('\u{1d4}', ['\u{1d3}', '\0', '\0']), ('\u{1d6}', ['\u{1d5}', '\0', '\0']), - ('\u{1d8}', ['\u{1d7}', '\0', '\0']), ('\u{1da}', ['\u{1d9}', '\0', '\0']), ('\u{1dc}', - ['\u{1db}', '\0', '\0']), ('\u{1dd}', ['\u{18e}', '\0', '\0']), ('\u{1df}', ['\u{1de}', - '\0', '\0']), ('\u{1e1}', ['\u{1e0}', '\0', '\0']), ('\u{1e3}', ['\u{1e2}', '\0', '\0']), - ('\u{1e5}', ['\u{1e4}', '\0', '\0']), ('\u{1e7}', ['\u{1e6}', '\0', '\0']), ('\u{1e9}', - ['\u{1e8}', '\0', '\0']), ('\u{1eb}', ['\u{1ea}', '\0', '\0']), ('\u{1ed}', ['\u{1ec}', - '\0', '\0']), ('\u{1ef}', ['\u{1ee}', '\0', '\0']), ('\u{1f0}', ['\u{4a}', '\u{30c}', - '\0']), ('\u{1f2}', ['\u{1f1}', '\0', '\0']), ('\u{1f3}', ['\u{1f1}', '\0', '\0']), - ('\u{1f5}', ['\u{1f4}', '\0', '\0']), ('\u{1f9}', ['\u{1f8}', '\0', '\0']), ('\u{1fb}', - ['\u{1fa}', '\0', '\0']), ('\u{1fd}', ['\u{1fc}', '\0', '\0']), ('\u{1ff}', ['\u{1fe}', - '\0', '\0']), ('\u{201}', ['\u{200}', '\0', '\0']), ('\u{203}', ['\u{202}', '\0', '\0']), - ('\u{205}', ['\u{204}', '\0', '\0']), ('\u{207}', ['\u{206}', '\0', '\0']), ('\u{209}', - ['\u{208}', '\0', '\0']), ('\u{20b}', ['\u{20a}', '\0', '\0']), ('\u{20d}', ['\u{20c}', - '\0', '\0']), ('\u{20f}', ['\u{20e}', '\0', '\0']), ('\u{211}', ['\u{210}', '\0', '\0']), - ('\u{213}', ['\u{212}', '\0', '\0']), ('\u{215}', ['\u{214}', '\0', '\0']), ('\u{217}', - ['\u{216}', '\0', '\0']), ('\u{219}', ['\u{218}', '\0', '\0']), ('\u{21b}', ['\u{21a}', - '\0', '\0']), ('\u{21d}', ['\u{21c}', '\0', '\0']), ('\u{21f}', ['\u{21e}', '\0', '\0']), - ('\u{223}', ['\u{222}', '\0', '\0']), ('\u{225}', ['\u{224}', '\0', '\0']), ('\u{227}', - ['\u{226}', '\0', '\0']), ('\u{229}', ['\u{228}', '\0', '\0']), ('\u{22b}', ['\u{22a}', - '\0', '\0']), ('\u{22d}', ['\u{22c}', '\0', '\0']), ('\u{22f}', ['\u{22e}', '\0', '\0']), - ('\u{231}', ['\u{230}', '\0', '\0']), ('\u{233}', ['\u{232}', '\0', '\0']), ('\u{23c}', - ['\u{23b}', '\0', '\0']), ('\u{23f}', ['\u{2c7e}', '\0', '\0']), ('\u{240}', ['\u{2c7f}', - '\0', '\0']), ('\u{242}', ['\u{241}', '\0', '\0']), ('\u{247}', ['\u{246}', '\0', '\0']), - ('\u{249}', ['\u{248}', '\0', '\0']), ('\u{24b}', ['\u{24a}', '\0', '\0']), ('\u{24d}', - ['\u{24c}', '\0', '\0']), ('\u{24f}', ['\u{24e}', '\0', '\0']), ('\u{250}', ['\u{2c6f}', - '\0', '\0']), ('\u{251}', ['\u{2c6d}', '\0', '\0']), ('\u{252}', ['\u{2c70}', '\0', '\0']), - ('\u{253}', ['\u{181}', '\0', '\0']), ('\u{254}', ['\u{186}', '\0', '\0']), ('\u{256}', - ['\u{189}', '\0', '\0']), ('\u{257}', ['\u{18a}', '\0', '\0']), ('\u{259}', ['\u{18f}', - '\0', '\0']), ('\u{25b}', ['\u{190}', '\0', '\0']), ('\u{25c}', ['\u{a7ab}', '\0', '\0']), - ('\u{260}', ['\u{193}', '\0', '\0']), ('\u{261}', ['\u{a7ac}', '\0', '\0']), ('\u{263}', - ['\u{194}', '\0', '\0']), ('\u{265}', ['\u{a78d}', '\0', '\0']), ('\u{266}', ['\u{a7aa}', - '\0', '\0']), ('\u{268}', ['\u{197}', '\0', '\0']), ('\u{269}', ['\u{196}', '\0', '\0']), - ('\u{26a}', ['\u{a7ae}', '\0', '\0']), ('\u{26b}', ['\u{2c62}', '\0', '\0']), ('\u{26c}', - ['\u{a7ad}', '\0', '\0']), ('\u{26f}', ['\u{19c}', '\0', '\0']), ('\u{271}', ['\u{2c6e}', - '\0', '\0']), ('\u{272}', ['\u{19d}', '\0', '\0']), ('\u{275}', ['\u{19f}', '\0', '\0']), - ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{282}', - ['\u{a7c5}', '\0', '\0']), ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', - '\0', '\0']), ('\u{288}', ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), - ('\u{28a}', ['\u{1b1}', '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', - ['\u{245}', '\0', '\0']), ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}', - '\0', '\0']), ('\u{29e}', ['\u{a7b0}', '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), - ('\u{371}', ['\u{370}', '\0', '\0']), ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', - ['\u{376}', '\0', '\0']), ('\u{37b}', ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', - '\0', '\0']), ('\u{37d}', ['\u{3ff}', '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', - '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), - ('\u{3ae}', ['\u{389}', '\0', '\0']), ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', - ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', - ['\u{392}', '\0', '\0']), ('\u{3b3}', ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', - '\0', '\0']), ('\u{3b5}', ['\u{395}', '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), - ('\u{3b7}', ['\u{397}', '\0', '\0']), ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', - ['\u{399}', '\0', '\0']), ('\u{3ba}', ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', - '\0', '\0']), ('\u{3bc}', ['\u{39c}', '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), - ('\u{3be}', ['\u{39e}', '\0', '\0']), ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', - ['\u{3a0}', '\0', '\0']), ('\u{3c1}', ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', - '\0', '\0']), ('\u{3c3}', ['\u{3a3}', '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), - ('\u{3c5}', ['\u{3a5}', '\0', '\0']), ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', - ['\u{3a7}', '\0', '\0']), ('\u{3c8}', ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', - '\0', '\0']), ('\u{3ca}', ['\u{3aa}', '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), - ('\u{3cc}', ['\u{38c}', '\0', '\0']), ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', - ['\u{38f}', '\0', '\0']), ('\u{3d0}', ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', - '\0', '\0']), ('\u{3d5}', ['\u{3a6}', '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), - ('\u{3d7}', ['\u{3cf}', '\0', '\0']), ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', - ['\u{3da}', '\0', '\0']), ('\u{3dd}', ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', - '\0', '\0']), ('\u{3e1}', ['\u{3e0}', '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), - ('\u{3e5}', ['\u{3e4}', '\0', '\0']), ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', - ['\u{3e8}', '\0', '\0']), ('\u{3eb}', ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', - '\0', '\0']), ('\u{3ef}', ['\u{3ee}', '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), - ('\u{3f1}', ['\u{3a1}', '\0', '\0']), ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', - ['\u{37f}', '\0', '\0']), ('\u{3f5}', ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', - '\0', '\0']), ('\u{3fb}', ['\u{3fa}', '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), - ('\u{431}', ['\u{411}', '\0', '\0']), ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', - ['\u{413}', '\0', '\0']), ('\u{434}', ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', - '\0', '\0']), ('\u{436}', ['\u{416}', '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), - ('\u{438}', ['\u{418}', '\0', '\0']), ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', - ['\u{41a}', '\0', '\0']), ('\u{43b}', ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', - '\0', '\0']), ('\u{43d}', ['\u{41d}', '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), - ('\u{43f}', ['\u{41f}', '\0', '\0']), ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', - ['\u{421}', '\0', '\0']), ('\u{442}', ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', - '\0', '\0']), ('\u{444}', ['\u{424}', '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), - ('\u{446}', ['\u{426}', '\0', '\0']), ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', - ['\u{428}', '\0', '\0']), ('\u{449}', ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', - '\0', '\0']), ('\u{44b}', ['\u{42b}', '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), - ('\u{44d}', ['\u{42d}', '\0', '\0']), ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', - ['\u{42f}', '\0', '\0']), ('\u{450}', ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', - '\0', '\0']), ('\u{452}', ['\u{402}', '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), - ('\u{454}', ['\u{404}', '\0', '\0']), ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', - ['\u{406}', '\0', '\0']), ('\u{457}', ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', - '\0', '\0']), ('\u{459}', ['\u{409}', '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), - ('\u{45b}', ['\u{40b}', '\0', '\0']), ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', - ['\u{40d}', '\0', '\0']), ('\u{45e}', ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', - '\0', '\0']), ('\u{461}', ['\u{460}', '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), - ('\u{465}', ['\u{464}', '\0', '\0']), ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', - ['\u{468}', '\0', '\0']), ('\u{46b}', ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', - '\0', '\0']), ('\u{46f}', ['\u{46e}', '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), - ('\u{473}', ['\u{472}', '\0', '\0']), ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', - ['\u{476}', '\0', '\0']), ('\u{479}', ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', - '\0', '\0']), ('\u{47d}', ['\u{47c}', '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), - ('\u{481}', ['\u{480}', '\0', '\0']), ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', - ['\u{48c}', '\0', '\0']), ('\u{48f}', ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', - '\0', '\0']), ('\u{493}', ['\u{492}', '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), - ('\u{497}', ['\u{496}', '\0', '\0']), ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', - ['\u{49a}', '\0', '\0']), ('\u{49d}', ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', - '\0', '\0']), ('\u{4a1}', ['\u{4a0}', '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), - ('\u{4a5}', ['\u{4a4}', '\0', '\0']), ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', - ['\u{4a8}', '\0', '\0']), ('\u{4ab}', ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', - '\0', '\0']), ('\u{4af}', ['\u{4ae}', '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), - ('\u{4b3}', ['\u{4b2}', '\0', '\0']), ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', - ['\u{4b6}', '\0', '\0']), ('\u{4b9}', ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', - '\0', '\0']), ('\u{4bd}', ['\u{4bc}', '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), - ('\u{4c2}', ['\u{4c1}', '\0', '\0']), ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', - ['\u{4c5}', '\0', '\0']), ('\u{4c8}', ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', - '\0', '\0']), ('\u{4cc}', ['\u{4cb}', '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), - ('\u{4cf}', ['\u{4c0}', '\0', '\0']), ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', - ['\u{4d2}', '\0', '\0']), ('\u{4d5}', ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', - '\0', '\0']), ('\u{4d9}', ['\u{4d8}', '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), - ('\u{4dd}', ['\u{4dc}', '\0', '\0']), ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', - ['\u{4e0}', '\0', '\0']), ('\u{4e3}', ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', - '\0', '\0']), ('\u{4e7}', ['\u{4e6}', '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), - ('\u{4eb}', ['\u{4ea}', '\0', '\0']), ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', - ['\u{4ee}', '\0', '\0']), ('\u{4f1}', ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', - '\0', '\0']), ('\u{4f5}', ['\u{4f4}', '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), - ('\u{4f9}', ['\u{4f8}', '\0', '\0']), ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', - ['\u{4fc}', '\0', '\0']), ('\u{4ff}', ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', - '\0', '\0']), ('\u{503}', ['\u{502}', '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), - ('\u{507}', ['\u{506}', '\0', '\0']), ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', - ['\u{50a}', '\0', '\0']), ('\u{50d}', ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', - '\0', '\0']), ('\u{511}', ['\u{510}', '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), - ('\u{515}', ['\u{514}', '\0', '\0']), ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', - ['\u{518}', '\0', '\0']), ('\u{51b}', ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', - '\0', '\0']), ('\u{51f}', ['\u{51e}', '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), - ('\u{523}', ['\u{522}', '\0', '\0']), ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', - ['\u{526}', '\0', '\0']), ('\u{529}', ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', - '\0', '\0']), ('\u{52d}', ['\u{52c}', '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), - ('\u{561}', ['\u{531}', '\0', '\0']), ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', - ['\u{533}', '\0', '\0']), ('\u{564}', ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', - '\0', '\0']), ('\u{566}', ['\u{536}', '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), - ('\u{568}', ['\u{538}', '\0', '\0']), ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', - ['\u{53a}', '\0', '\0']), ('\u{56b}', ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', - '\0', '\0']), ('\u{56d}', ['\u{53d}', '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), - ('\u{56f}', ['\u{53f}', '\0', '\0']), ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', - ['\u{541}', '\0', '\0']), ('\u{572}', ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', - '\0', '\0']), ('\u{574}', ['\u{544}', '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), - ('\u{576}', ['\u{546}', '\0', '\0']), ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', - ['\u{548}', '\0', '\0']), ('\u{579}', ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', - '\0', '\0']), ('\u{57b}', ['\u{54b}', '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), - ('\u{57d}', ['\u{54d}', '\0', '\0']), ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', - ['\u{54f}', '\0', '\0']), ('\u{580}', ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', - '\0', '\0']), ('\u{582}', ['\u{552}', '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), - ('\u{584}', ['\u{554}', '\0', '\0']), ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', - ['\u{556}', '\0', '\0']), ('\u{587}', ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', - ['\u{1c90}', '\0', '\0']), ('\u{10d1}', ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', - '\0', '\0']), ('\u{10d3}', ['\u{1c93}', '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', - '\0']), ('\u{10d5}', ['\u{1c95}', '\0', '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), - ('\u{10d7}', ['\u{1c97}', '\0', '\0']), ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', - ['\u{1c99}', '\0', '\0']), ('\u{10da}', ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', - '\0', '\0']), ('\u{10dc}', ['\u{1c9c}', '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', - '\0']), ('\u{10de}', ['\u{1c9e}', '\0', '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), - ('\u{10e0}', ['\u{1ca0}', '\0', '\0']), ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', - ['\u{1ca2}', '\0', '\0']), ('\u{10e3}', ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', - '\0', '\0']), ('\u{10e5}', ['\u{1ca5}', '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', - '\0']), ('\u{10e7}', ['\u{1ca7}', '\0', '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), - ('\u{10e9}', ['\u{1ca9}', '\0', '\0']), ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', - ['\u{1cab}', '\0', '\0']), ('\u{10ec}', ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', - '\0', '\0']), ('\u{10ee}', ['\u{1cae}', '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', - '\0']), ('\u{10f0}', ['\u{1cb0}', '\0', '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), - ('\u{10f2}', ['\u{1cb2}', '\0', '\0']), ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', - ['\u{1cb4}', '\0', '\0']), ('\u{10f5}', ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', - '\0', '\0']), ('\u{10f7}', ['\u{1cb7}', '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', - '\0']), ('\u{10f9}', ['\u{1cb9}', '\0', '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), - ('\u{10fd}', ['\u{1cbd}', '\0', '\0']), ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', - ['\u{1cbf}', '\0', '\0']), ('\u{13f8}', ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', - '\0', '\0']), ('\u{13fa}', ['\u{13f2}', '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', - '\0']), ('\u{13fc}', ['\u{13f4}', '\0', '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), - ('\u{1c80}', ['\u{412}', '\0', '\0']), ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', - ['\u{41e}', '\0', '\0']), ('\u{1c83}', ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', - '\0', '\0']), ('\u{1c85}', ['\u{422}', '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), - ('\u{1c87}', ['\u{462}', '\0', '\0']), ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', - ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1d8e}', ['\u{a7c6}', - '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0', - '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']), - ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}', - ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}', - '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0', - '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']), - ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}', - ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}', - '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0', - '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']), - ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}', - ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}', - '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0', - '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']), - ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}', - ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}', - '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0', - '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']), - ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}', - ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}', - '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0', - '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']), - ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}', - ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}', - '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0', - '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']), - ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}', - ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}', - '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0', - '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']), - ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}', - ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}', - '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0', - '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']), - ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']), - ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']), - ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}', - ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}', - '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0', - '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']), - ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}', - ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}', - '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0', - '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']), - ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}', - ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}', - '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0', - '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']), - ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}', - ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}', - '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0', - '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']), - ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}', - ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}', - '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0', - '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']), - ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}', - ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}', - '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0', - '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']), - ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}', - ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}', - '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0', - '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']), - ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}', - ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}', - '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0', - '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']), - ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}', - ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}', - '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0', - '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']), - ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}', - ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}', - '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}', - '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}', - '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}', - '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}', - '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0', - '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']), - ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}', - ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}', - '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0', - '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']), - ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}', - ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}', - '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0', - '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', '\0']), - ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\0']), - ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\0']), - ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\0']), - ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', '\0']), - ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\0']), - ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\0']), - ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\0']), - ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', '\0']), - ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\0']), - ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\0']), - ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\0']), - ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', '\0']), - ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\0']), - ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\0']), - ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\0']), - ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\0']), - ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\0']), - ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\0']), - ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\0']), - ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\0']), - ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\0']), - ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\0']), - ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\0']), - ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), - ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']), - ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']), - ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), - ('\u{1fbc}', ['\u{391}', '\u{399}', '\0']), ('\u{1fbe}', ['\u{399}', '\0', '\0']), - ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\0']), ('\u{1fc3}', ['\u{397}', '\u{399}', '\0']), - ('\u{1fc4}', ['\u{389}', '\u{399}', '\0']), ('\u{1fc6}', ['\u{397}', '\u{342}', '\0']), - ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), ('\u{1fcc}', ['\u{397}', '\u{399}', '\0']), - ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']), ('\u{1fd1}', ['\u{1fd9}', '\0', '\0']), ('\u{1fd2}', - ['\u{399}', '\u{308}', '\u{300}']), ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), - ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']), ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), - ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']), ('\u{1fe1}', ['\u{1fe9}', '\0', '\0']), ('\u{1fe2}', - ['\u{3a5}', '\u{308}', '\u{300}']), ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']), ('\u{1fe5}', ['\u{1fec}', '\0', '\0']), - ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']), ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), - ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\0']), ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\0']), - ('\u{1ff4}', ['\u{38f}', '\u{399}', '\0']), ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\0']), - ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\0']), - ('\u{214e}', ['\u{2132}', '\0', '\0']), ('\u{2170}', ['\u{2160}', '\0', '\0']), ('\u{2171}', - ['\u{2161}', '\0', '\0']), ('\u{2172}', ['\u{2162}', '\0', '\0']), ('\u{2173}', ['\u{2163}', - '\0', '\0']), ('\u{2174}', ['\u{2164}', '\0', '\0']), ('\u{2175}', ['\u{2165}', '\0', - '\0']), ('\u{2176}', ['\u{2166}', '\0', '\0']), ('\u{2177}', ['\u{2167}', '\0', '\0']), - ('\u{2178}', ['\u{2168}', '\0', '\0']), ('\u{2179}', ['\u{2169}', '\0', '\0']), ('\u{217a}', - ['\u{216a}', '\0', '\0']), ('\u{217b}', ['\u{216b}', '\0', '\0']), ('\u{217c}', ['\u{216c}', - '\0', '\0']), ('\u{217d}', ['\u{216d}', '\0', '\0']), ('\u{217e}', ['\u{216e}', '\0', - '\0']), ('\u{217f}', ['\u{216f}', '\0', '\0']), ('\u{2184}', ['\u{2183}', '\0', '\0']), - ('\u{24d0}', ['\u{24b6}', '\0', '\0']), ('\u{24d1}', ['\u{24b7}', '\0', '\0']), ('\u{24d2}', - ['\u{24b8}', '\0', '\0']), ('\u{24d3}', ['\u{24b9}', '\0', '\0']), ('\u{24d4}', ['\u{24ba}', - '\0', '\0']), ('\u{24d5}', ['\u{24bb}', '\0', '\0']), ('\u{24d6}', ['\u{24bc}', '\0', - '\0']), ('\u{24d7}', ['\u{24bd}', '\0', '\0']), ('\u{24d8}', ['\u{24be}', '\0', '\0']), - ('\u{24d9}', ['\u{24bf}', '\0', '\0']), ('\u{24da}', ['\u{24c0}', '\0', '\0']), ('\u{24db}', - ['\u{24c1}', '\0', '\0']), ('\u{24dc}', ['\u{24c2}', '\0', '\0']), ('\u{24dd}', ['\u{24c3}', - '\0', '\0']), ('\u{24de}', ['\u{24c4}', '\0', '\0']), ('\u{24df}', ['\u{24c5}', '\0', - '\0']), ('\u{24e0}', ['\u{24c6}', '\0', '\0']), ('\u{24e1}', ['\u{24c7}', '\0', '\0']), - ('\u{24e2}', ['\u{24c8}', '\0', '\0']), ('\u{24e3}', ['\u{24c9}', '\0', '\0']), ('\u{24e4}', - ['\u{24ca}', '\0', '\0']), ('\u{24e5}', ['\u{24cb}', '\0', '\0']), ('\u{24e6}', ['\u{24cc}', - '\0', '\0']), ('\u{24e7}', ['\u{24cd}', '\0', '\0']), ('\u{24e8}', ['\u{24ce}', '\0', - '\0']), ('\u{24e9}', ['\u{24cf}', '\0', '\0']), ('\u{2c30}', ['\u{2c00}', '\0', '\0']), - ('\u{2c31}', ['\u{2c01}', '\0', '\0']), ('\u{2c32}', ['\u{2c02}', '\0', '\0']), ('\u{2c33}', - ['\u{2c03}', '\0', '\0']), ('\u{2c34}', ['\u{2c04}', '\0', '\0']), ('\u{2c35}', ['\u{2c05}', - '\0', '\0']), ('\u{2c36}', ['\u{2c06}', '\0', '\0']), ('\u{2c37}', ['\u{2c07}', '\0', - '\0']), ('\u{2c38}', ['\u{2c08}', '\0', '\0']), ('\u{2c39}', ['\u{2c09}', '\0', '\0']), - ('\u{2c3a}', ['\u{2c0a}', '\0', '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0', '\0']), ('\u{2c3c}', - ['\u{2c0c}', '\0', '\0']), ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']), ('\u{2c3e}', ['\u{2c0e}', - '\0', '\0']), ('\u{2c3f}', ['\u{2c0f}', '\0', '\0']), ('\u{2c40}', ['\u{2c10}', '\0', - '\0']), ('\u{2c41}', ['\u{2c11}', '\0', '\0']), ('\u{2c42}', ['\u{2c12}', '\0', '\0']), - ('\u{2c43}', ['\u{2c13}', '\0', '\0']), ('\u{2c44}', ['\u{2c14}', '\0', '\0']), ('\u{2c45}', - ['\u{2c15}', '\0', '\0']), ('\u{2c46}', ['\u{2c16}', '\0', '\0']), ('\u{2c47}', ['\u{2c17}', - '\0', '\0']), ('\u{2c48}', ['\u{2c18}', '\0', '\0']), ('\u{2c49}', ['\u{2c19}', '\0', - '\0']), ('\u{2c4a}', ['\u{2c1a}', '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}', '\0', '\0']), - ('\u{2c4c}', ['\u{2c1c}', '\0', '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0', '\0']), ('\u{2c4e}', - ['\u{2c1e}', '\0', '\0']), ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']), ('\u{2c50}', ['\u{2c20}', - '\0', '\0']), ('\u{2c51}', ['\u{2c21}', '\0', '\0']), ('\u{2c52}', ['\u{2c22}', '\0', - '\0']), ('\u{2c53}', ['\u{2c23}', '\0', '\0']), ('\u{2c54}', ['\u{2c24}', '\0', '\0']), - ('\u{2c55}', ['\u{2c25}', '\0', '\0']), ('\u{2c56}', ['\u{2c26}', '\0', '\0']), ('\u{2c57}', - ['\u{2c27}', '\0', '\0']), ('\u{2c58}', ['\u{2c28}', '\0', '\0']), ('\u{2c59}', ['\u{2c29}', - '\0', '\0']), ('\u{2c5a}', ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}', ['\u{2c2b}', '\0', - '\0']), ('\u{2c5c}', ['\u{2c2c}', '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}', '\0', '\0']), - ('\u{2c5e}', ['\u{2c2e}', '\0', '\0']), ('\u{2c61}', ['\u{2c60}', '\0', '\0']), ('\u{2c65}', - ['\u{23a}', '\0', '\0']), ('\u{2c66}', ['\u{23e}', '\0', '\0']), ('\u{2c68}', ['\u{2c67}', - '\0', '\0']), ('\u{2c6a}', ['\u{2c69}', '\0', '\0']), ('\u{2c6c}', ['\u{2c6b}', '\0', - '\0']), ('\u{2c73}', ['\u{2c72}', '\0', '\0']), ('\u{2c76}', ['\u{2c75}', '\0', '\0']), - ('\u{2c81}', ['\u{2c80}', '\0', '\0']), ('\u{2c83}', ['\u{2c82}', '\0', '\0']), ('\u{2c85}', - ['\u{2c84}', '\0', '\0']), ('\u{2c87}', ['\u{2c86}', '\0', '\0']), ('\u{2c89}', ['\u{2c88}', - '\0', '\0']), ('\u{2c8b}', ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}', ['\u{2c8c}', '\0', - '\0']), ('\u{2c8f}', ['\u{2c8e}', '\0', '\0']), ('\u{2c91}', ['\u{2c90}', '\0', '\0']), - ('\u{2c93}', ['\u{2c92}', '\0', '\0']), ('\u{2c95}', ['\u{2c94}', '\0', '\0']), ('\u{2c97}', - ['\u{2c96}', '\0', '\0']), ('\u{2c99}', ['\u{2c98}', '\0', '\0']), ('\u{2c9b}', ['\u{2c9a}', - '\0', '\0']), ('\u{2c9d}', ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}', ['\u{2c9e}', '\0', - '\0']), ('\u{2ca1}', ['\u{2ca0}', '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}', '\0', '\0']), - ('\u{2ca5}', ['\u{2ca4}', '\0', '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0', '\0']), ('\u{2ca9}', - ['\u{2ca8}', '\0', '\0']), ('\u{2cab}', ['\u{2caa}', '\0', '\0']), ('\u{2cad}', ['\u{2cac}', - '\0', '\0']), ('\u{2caf}', ['\u{2cae}', '\0', '\0']), ('\u{2cb1}', ['\u{2cb0}', '\0', - '\0']), ('\u{2cb3}', ['\u{2cb2}', '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}', '\0', '\0']), - ('\u{2cb7}', ['\u{2cb6}', '\0', '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0', '\0']), ('\u{2cbb}', - ['\u{2cba}', '\0', '\0']), ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']), ('\u{2cbf}', ['\u{2cbe}', - '\0', '\0']), ('\u{2cc1}', ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}', ['\u{2cc2}', '\0', - '\0']), ('\u{2cc5}', ['\u{2cc4}', '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}', '\0', '\0']), - ('\u{2cc9}', ['\u{2cc8}', '\0', '\0']), ('\u{2ccb}', ['\u{2cca}', '\0', '\0']), ('\u{2ccd}', - ['\u{2ccc}', '\0', '\0']), ('\u{2ccf}', ['\u{2cce}', '\0', '\0']), ('\u{2cd1}', ['\u{2cd0}', - '\0', '\0']), ('\u{2cd3}', ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}', ['\u{2cd4}', '\0', - '\0']), ('\u{2cd7}', ['\u{2cd6}', '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}', '\0', '\0']), - ('\u{2cdb}', ['\u{2cda}', '\0', '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0', '\0']), ('\u{2cdf}', - ['\u{2cde}', '\0', '\0']), ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']), ('\u{2ce3}', ['\u{2ce2}', - '\0', '\0']), ('\u{2cec}', ['\u{2ceb}', '\0', '\0']), ('\u{2cee}', ['\u{2ced}', '\0', - '\0']), ('\u{2cf3}', ['\u{2cf2}', '\0', '\0']), ('\u{2d00}', ['\u{10a0}', '\0', '\0']), - ('\u{2d01}', ['\u{10a1}', '\0', '\0']), ('\u{2d02}', ['\u{10a2}', '\0', '\0']), ('\u{2d03}', - ['\u{10a3}', '\0', '\0']), ('\u{2d04}', ['\u{10a4}', '\0', '\0']), ('\u{2d05}', ['\u{10a5}', - '\0', '\0']), ('\u{2d06}', ['\u{10a6}', '\0', '\0']), ('\u{2d07}', ['\u{10a7}', '\0', - '\0']), ('\u{2d08}', ['\u{10a8}', '\0', '\0']), ('\u{2d09}', ['\u{10a9}', '\0', '\0']), - ('\u{2d0a}', ['\u{10aa}', '\0', '\0']), ('\u{2d0b}', ['\u{10ab}', '\0', '\0']), ('\u{2d0c}', - ['\u{10ac}', '\0', '\0']), ('\u{2d0d}', ['\u{10ad}', '\0', '\0']), ('\u{2d0e}', ['\u{10ae}', - '\0', '\0']), ('\u{2d0f}', ['\u{10af}', '\0', '\0']), ('\u{2d10}', ['\u{10b0}', '\0', - '\0']), ('\u{2d11}', ['\u{10b1}', '\0', '\0']), ('\u{2d12}', ['\u{10b2}', '\0', '\0']), - ('\u{2d13}', ['\u{10b3}', '\0', '\0']), ('\u{2d14}', ['\u{10b4}', '\0', '\0']), ('\u{2d15}', - ['\u{10b5}', '\0', '\0']), ('\u{2d16}', ['\u{10b6}', '\0', '\0']), ('\u{2d17}', ['\u{10b7}', - '\0', '\0']), ('\u{2d18}', ['\u{10b8}', '\0', '\0']), ('\u{2d19}', ['\u{10b9}', '\0', - '\0']), ('\u{2d1a}', ['\u{10ba}', '\0', '\0']), ('\u{2d1b}', ['\u{10bb}', '\0', '\0']), - ('\u{2d1c}', ['\u{10bc}', '\0', '\0']), ('\u{2d1d}', ['\u{10bd}', '\0', '\0']), ('\u{2d1e}', - ['\u{10be}', '\0', '\0']), ('\u{2d1f}', ['\u{10bf}', '\0', '\0']), ('\u{2d20}', ['\u{10c0}', - '\0', '\0']), ('\u{2d21}', ['\u{10c1}', '\0', '\0']), ('\u{2d22}', ['\u{10c2}', '\0', - '\0']), ('\u{2d23}', ['\u{10c3}', '\0', '\0']), ('\u{2d24}', ['\u{10c4}', '\0', '\0']), - ('\u{2d25}', ['\u{10c5}', '\0', '\0']), ('\u{2d27}', ['\u{10c7}', '\0', '\0']), ('\u{2d2d}', - ['\u{10cd}', '\0', '\0']), ('\u{a641}', ['\u{a640}', '\0', '\0']), ('\u{a643}', ['\u{a642}', - '\0', '\0']), ('\u{a645}', ['\u{a644}', '\0', '\0']), ('\u{a647}', ['\u{a646}', '\0', - '\0']), ('\u{a649}', ['\u{a648}', '\0', '\0']), ('\u{a64b}', ['\u{a64a}', '\0', '\0']), - ('\u{a64d}', ['\u{a64c}', '\0', '\0']), ('\u{a64f}', ['\u{a64e}', '\0', '\0']), ('\u{a651}', - ['\u{a650}', '\0', '\0']), ('\u{a653}', ['\u{a652}', '\0', '\0']), ('\u{a655}', ['\u{a654}', - '\0', '\0']), ('\u{a657}', ['\u{a656}', '\0', '\0']), ('\u{a659}', ['\u{a658}', '\0', - '\0']), ('\u{a65b}', ['\u{a65a}', '\0', '\0']), ('\u{a65d}', ['\u{a65c}', '\0', '\0']), - ('\u{a65f}', ['\u{a65e}', '\0', '\0']), ('\u{a661}', ['\u{a660}', '\0', '\0']), ('\u{a663}', - ['\u{a662}', '\0', '\0']), ('\u{a665}', ['\u{a664}', '\0', '\0']), ('\u{a667}', ['\u{a666}', - '\0', '\0']), ('\u{a669}', ['\u{a668}', '\0', '\0']), ('\u{a66b}', ['\u{a66a}', '\0', - '\0']), ('\u{a66d}', ['\u{a66c}', '\0', '\0']), ('\u{a681}', ['\u{a680}', '\0', '\0']), - ('\u{a683}', ['\u{a682}', '\0', '\0']), ('\u{a685}', ['\u{a684}', '\0', '\0']), ('\u{a687}', - ['\u{a686}', '\0', '\0']), ('\u{a689}', ['\u{a688}', '\0', '\0']), ('\u{a68b}', ['\u{a68a}', - '\0', '\0']), ('\u{a68d}', ['\u{a68c}', '\0', '\0']), ('\u{a68f}', ['\u{a68e}', '\0', - '\0']), ('\u{a691}', ['\u{a690}', '\0', '\0']), ('\u{a693}', ['\u{a692}', '\0', '\0']), - ('\u{a695}', ['\u{a694}', '\0', '\0']), ('\u{a697}', ['\u{a696}', '\0', '\0']), ('\u{a699}', - ['\u{a698}', '\0', '\0']), ('\u{a69b}', ['\u{a69a}', '\0', '\0']), ('\u{a723}', ['\u{a722}', - '\0', '\0']), ('\u{a725}', ['\u{a724}', '\0', '\0']), ('\u{a727}', ['\u{a726}', '\0', - '\0']), ('\u{a729}', ['\u{a728}', '\0', '\0']), ('\u{a72b}', ['\u{a72a}', '\0', '\0']), - ('\u{a72d}', ['\u{a72c}', '\0', '\0']), ('\u{a72f}', ['\u{a72e}', '\0', '\0']), ('\u{a733}', - ['\u{a732}', '\0', '\0']), ('\u{a735}', ['\u{a734}', '\0', '\0']), ('\u{a737}', ['\u{a736}', - '\0', '\0']), ('\u{a739}', ['\u{a738}', '\0', '\0']), ('\u{a73b}', ['\u{a73a}', '\0', - '\0']), ('\u{a73d}', ['\u{a73c}', '\0', '\0']), ('\u{a73f}', ['\u{a73e}', '\0', '\0']), - ('\u{a741}', ['\u{a740}', '\0', '\0']), ('\u{a743}', ['\u{a742}', '\0', '\0']), ('\u{a745}', - ['\u{a744}', '\0', '\0']), ('\u{a747}', ['\u{a746}', '\0', '\0']), ('\u{a749}', ['\u{a748}', - '\0', '\0']), ('\u{a74b}', ['\u{a74a}', '\0', '\0']), ('\u{a74d}', ['\u{a74c}', '\0', - '\0']), ('\u{a74f}', ['\u{a74e}', '\0', '\0']), ('\u{a751}', ['\u{a750}', '\0', '\0']), - ('\u{a753}', ['\u{a752}', '\0', '\0']), ('\u{a755}', ['\u{a754}', '\0', '\0']), ('\u{a757}', - ['\u{a756}', '\0', '\0']), ('\u{a759}', ['\u{a758}', '\0', '\0']), ('\u{a75b}', ['\u{a75a}', - '\0', '\0']), ('\u{a75d}', ['\u{a75c}', '\0', '\0']), ('\u{a75f}', ['\u{a75e}', '\0', - '\0']), ('\u{a761}', ['\u{a760}', '\0', '\0']), ('\u{a763}', ['\u{a762}', '\0', '\0']), - ('\u{a765}', ['\u{a764}', '\0', '\0']), ('\u{a767}', ['\u{a766}', '\0', '\0']), ('\u{a769}', - ['\u{a768}', '\0', '\0']), ('\u{a76b}', ['\u{a76a}', '\0', '\0']), ('\u{a76d}', ['\u{a76c}', - '\0', '\0']), ('\u{a76f}', ['\u{a76e}', '\0', '\0']), ('\u{a77a}', ['\u{a779}', '\0', - '\0']), ('\u{a77c}', ['\u{a77b}', '\0', '\0']), ('\u{a77f}', ['\u{a77e}', '\0', '\0']), - ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}', - ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}', - '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0', - '\0']), ('\u{a794}', ['\u{a7c4}', '\0', '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), - ('\u{a799}', ['\u{a798}', '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', - ['\u{a79c}', '\0', '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', - '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', - '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), - ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', - ['\u{a7b8}', '\0', '\0']), ('\u{a7bb}', ['\u{a7ba}', '\0', '\0']), ('\u{a7bd}', ['\u{a7bc}', - '\0', '\0']), ('\u{a7bf}', ['\u{a7be}', '\0', '\0']), ('\u{a7c3}', ['\u{a7c2}', '\0', - '\0']), ('\u{ab53}', ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), - ('\u{ab71}', ['\u{13a1}', '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', - ['\u{13a3}', '\0', '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', - '\0', '\0']), ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', - '\0']), ('\u{ab78}', ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), - ('\u{ab7a}', ['\u{13aa}', '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', - ['\u{13ac}', '\0', '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', - '\0', '\0']), ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', - '\0']), ('\u{ab81}', ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), - ('\u{ab83}', ['\u{13b3}', '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', - ['\u{13b5}', '\0', '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', - '\0', '\0']), ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', - '\0']), ('\u{ab8a}', ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), - ('\u{ab8c}', ['\u{13bc}', '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', - ['\u{13be}', '\0', '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', - '\0', '\0']), ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', - '\0']), ('\u{ab93}', ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), - ('\u{ab95}', ['\u{13c5}', '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', - ['\u{13c7}', '\0', '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', - '\0', '\0']), ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', - '\0']), ('\u{ab9c}', ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), - ('\u{ab9e}', ['\u{13ce}', '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', - ['\u{13d0}', '\0', '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', - '\0', '\0']), ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', - '\0']), ('\u{aba5}', ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), - ('\u{aba7}', ['\u{13d7}', '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', - ['\u{13d9}', '\0', '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', - '\0', '\0']), ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', - '\0']), ('\u{abae}', ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), - ('\u{abb0}', ['\u{13e0}', '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', - ['\u{13e2}', '\0', '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', - '\0', '\0']), ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', - '\0']), ('\u{abb7}', ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), - ('\u{abb9}', ['\u{13e9}', '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', - ['\u{13eb}', '\0', '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', - '\0', '\0']), ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', - '\0']), ('\u{fb00}', ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), - ('\u{fb02}', ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), - ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), - ('\u{fb06}', ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), - ('\u{fb14}', ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), - ('\u{fb16}', ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), - ('\u{ff41}', ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', - ['\u{ff23}', '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', - '\0', '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', - '\0']), ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), - ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', - ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', - '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', - '\0']), ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), - ('\u{ff53}', ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', - ['\u{ff35}', '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', - '\0', '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', - '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), - ('\u{10429}', ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']), - ('\u{1042b}', ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']), - ('\u{1042d}', ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']), - ('\u{1042f}', ['\u{10407}', '\0', '\0']), ('\u{10430}', ['\u{10408}', '\0', '\0']), - ('\u{10431}', ['\u{10409}', '\0', '\0']), ('\u{10432}', ['\u{1040a}', '\0', '\0']), - ('\u{10433}', ['\u{1040b}', '\0', '\0']), ('\u{10434}', ['\u{1040c}', '\0', '\0']), - ('\u{10435}', ['\u{1040d}', '\0', '\0']), ('\u{10436}', ['\u{1040e}', '\0', '\0']), - ('\u{10437}', ['\u{1040f}', '\0', '\0']), ('\u{10438}', ['\u{10410}', '\0', '\0']), - ('\u{10439}', ['\u{10411}', '\0', '\0']), ('\u{1043a}', ['\u{10412}', '\0', '\0']), - ('\u{1043b}', ['\u{10413}', '\0', '\0']), ('\u{1043c}', ['\u{10414}', '\0', '\0']), - ('\u{1043d}', ['\u{10415}', '\0', '\0']), ('\u{1043e}', ['\u{10416}', '\0', '\0']), - ('\u{1043f}', ['\u{10417}', '\0', '\0']), ('\u{10440}', ['\u{10418}', '\0', '\0']), - ('\u{10441}', ['\u{10419}', '\0', '\0']), ('\u{10442}', ['\u{1041a}', '\0', '\0']), - ('\u{10443}', ['\u{1041b}', '\0', '\0']), ('\u{10444}', ['\u{1041c}', '\0', '\0']), - ('\u{10445}', ['\u{1041d}', '\0', '\0']), ('\u{10446}', ['\u{1041e}', '\0', '\0']), - ('\u{10447}', ['\u{1041f}', '\0', '\0']), ('\u{10448}', ['\u{10420}', '\0', '\0']), - ('\u{10449}', ['\u{10421}', '\0', '\0']), ('\u{1044a}', ['\u{10422}', '\0', '\0']), - ('\u{1044b}', ['\u{10423}', '\0', '\0']), ('\u{1044c}', ['\u{10424}', '\0', '\0']), - ('\u{1044d}', ['\u{10425}', '\0', '\0']), ('\u{1044e}', ['\u{10426}', '\0', '\0']), - ('\u{1044f}', ['\u{10427}', '\0', '\0']), ('\u{104d8}', ['\u{104b0}', '\0', '\0']), - ('\u{104d9}', ['\u{104b1}', '\0', '\0']), ('\u{104da}', ['\u{104b2}', '\0', '\0']), - ('\u{104db}', ['\u{104b3}', '\0', '\0']), ('\u{104dc}', ['\u{104b4}', '\0', '\0']), - ('\u{104dd}', ['\u{104b5}', '\0', '\0']), ('\u{104de}', ['\u{104b6}', '\0', '\0']), - ('\u{104df}', ['\u{104b7}', '\0', '\0']), ('\u{104e0}', ['\u{104b8}', '\0', '\0']), - ('\u{104e1}', ['\u{104b9}', '\0', '\0']), ('\u{104e2}', ['\u{104ba}', '\0', '\0']), - ('\u{104e3}', ['\u{104bb}', '\0', '\0']), ('\u{104e4}', ['\u{104bc}', '\0', '\0']), - ('\u{104e5}', ['\u{104bd}', '\0', '\0']), ('\u{104e6}', ['\u{104be}', '\0', '\0']), - ('\u{104e7}', ['\u{104bf}', '\0', '\0']), ('\u{104e8}', ['\u{104c0}', '\0', '\0']), - ('\u{104e9}', ['\u{104c1}', '\0', '\0']), ('\u{104ea}', ['\u{104c2}', '\0', '\0']), - ('\u{104eb}', ['\u{104c3}', '\0', '\0']), ('\u{104ec}', ['\u{104c4}', '\0', '\0']), - ('\u{104ed}', ['\u{104c5}', '\0', '\0']), ('\u{104ee}', ['\u{104c6}', '\0', '\0']), - ('\u{104ef}', ['\u{104c7}', '\0', '\0']), ('\u{104f0}', ['\u{104c8}', '\0', '\0']), - ('\u{104f1}', ['\u{104c9}', '\0', '\0']), ('\u{104f2}', ['\u{104ca}', '\0', '\0']), - ('\u{104f3}', ['\u{104cb}', '\0', '\0']), ('\u{104f4}', ['\u{104cc}', '\0', '\0']), - ('\u{104f5}', ['\u{104cd}', '\0', '\0']), ('\u{104f6}', ['\u{104ce}', '\0', '\0']), - ('\u{104f7}', ['\u{104cf}', '\0', '\0']), ('\u{104f8}', ['\u{104d0}', '\0', '\0']), - ('\u{104f9}', ['\u{104d1}', '\0', '\0']), ('\u{104fa}', ['\u{104d2}', '\0', '\0']), - ('\u{104fb}', ['\u{104d3}', '\0', '\0']), ('\u{10cc0}', ['\u{10c80}', '\0', '\0']), - ('\u{10cc1}', ['\u{10c81}', '\0', '\0']), ('\u{10cc2}', ['\u{10c82}', '\0', '\0']), - ('\u{10cc3}', ['\u{10c83}', '\0', '\0']), ('\u{10cc4}', ['\u{10c84}', '\0', '\0']), - ('\u{10cc5}', ['\u{10c85}', '\0', '\0']), ('\u{10cc6}', ['\u{10c86}', '\0', '\0']), - ('\u{10cc7}', ['\u{10c87}', '\0', '\0']), ('\u{10cc8}', ['\u{10c88}', '\0', '\0']), - ('\u{10cc9}', ['\u{10c89}', '\0', '\0']), ('\u{10cca}', ['\u{10c8a}', '\0', '\0']), - ('\u{10ccb}', ['\u{10c8b}', '\0', '\0']), ('\u{10ccc}', ['\u{10c8c}', '\0', '\0']), - ('\u{10ccd}', ['\u{10c8d}', '\0', '\0']), ('\u{10cce}', ['\u{10c8e}', '\0', '\0']), - ('\u{10ccf}', ['\u{10c8f}', '\0', '\0']), ('\u{10cd0}', ['\u{10c90}', '\0', '\0']), - ('\u{10cd1}', ['\u{10c91}', '\0', '\0']), ('\u{10cd2}', ['\u{10c92}', '\0', '\0']), - ('\u{10cd3}', ['\u{10c93}', '\0', '\0']), ('\u{10cd4}', ['\u{10c94}', '\0', '\0']), - ('\u{10cd5}', ['\u{10c95}', '\0', '\0']), ('\u{10cd6}', ['\u{10c96}', '\0', '\0']), - ('\u{10cd7}', ['\u{10c97}', '\0', '\0']), ('\u{10cd8}', ['\u{10c98}', '\0', '\0']), - ('\u{10cd9}', ['\u{10c99}', '\0', '\0']), ('\u{10cda}', ['\u{10c9a}', '\0', '\0']), - ('\u{10cdb}', ['\u{10c9b}', '\0', '\0']), ('\u{10cdc}', ['\u{10c9c}', '\0', '\0']), - ('\u{10cdd}', ['\u{10c9d}', '\0', '\0']), ('\u{10cde}', ['\u{10c9e}', '\0', '\0']), - ('\u{10cdf}', ['\u{10c9f}', '\0', '\0']), ('\u{10ce0}', ['\u{10ca0}', '\0', '\0']), - ('\u{10ce1}', ['\u{10ca1}', '\0', '\0']), ('\u{10ce2}', ['\u{10ca2}', '\0', '\0']), - ('\u{10ce3}', ['\u{10ca3}', '\0', '\0']), ('\u{10ce4}', ['\u{10ca4}', '\0', '\0']), - ('\u{10ce5}', ['\u{10ca5}', '\0', '\0']), ('\u{10ce6}', ['\u{10ca6}', '\0', '\0']), - ('\u{10ce7}', ['\u{10ca7}', '\0', '\0']), ('\u{10ce8}', ['\u{10ca8}', '\0', '\0']), - ('\u{10ce9}', ['\u{10ca9}', '\0', '\0']), ('\u{10cea}', ['\u{10caa}', '\0', '\0']), - ('\u{10ceb}', ['\u{10cab}', '\0', '\0']), ('\u{10cec}', ['\u{10cac}', '\0', '\0']), - ('\u{10ced}', ['\u{10cad}', '\0', '\0']), ('\u{10cee}', ['\u{10cae}', '\0', '\0']), - ('\u{10cef}', ['\u{10caf}', '\0', '\0']), ('\u{10cf0}', ['\u{10cb0}', '\0', '\0']), - ('\u{10cf1}', ['\u{10cb1}', '\0', '\0']), ('\u{10cf2}', ['\u{10cb2}', '\0', '\0']), - ('\u{118c0}', ['\u{118a0}', '\0', '\0']), ('\u{118c1}', ['\u{118a1}', '\0', '\0']), - ('\u{118c2}', ['\u{118a2}', '\0', '\0']), ('\u{118c3}', ['\u{118a3}', '\0', '\0']), - ('\u{118c4}', ['\u{118a4}', '\0', '\0']), ('\u{118c5}', ['\u{118a5}', '\0', '\0']), - ('\u{118c6}', ['\u{118a6}', '\0', '\0']), ('\u{118c7}', ['\u{118a7}', '\0', '\0']), - ('\u{118c8}', ['\u{118a8}', '\0', '\0']), ('\u{118c9}', ['\u{118a9}', '\0', '\0']), - ('\u{118ca}', ['\u{118aa}', '\0', '\0']), ('\u{118cb}', ['\u{118ab}', '\0', '\0']), - ('\u{118cc}', ['\u{118ac}', '\0', '\0']), ('\u{118cd}', ['\u{118ad}', '\0', '\0']), - ('\u{118ce}', ['\u{118ae}', '\0', '\0']), ('\u{118cf}', ['\u{118af}', '\0', '\0']), - ('\u{118d0}', ['\u{118b0}', '\0', '\0']), ('\u{118d1}', ['\u{118b1}', '\0', '\0']), - ('\u{118d2}', ['\u{118b2}', '\0', '\0']), ('\u{118d3}', ['\u{118b3}', '\0', '\0']), - ('\u{118d4}', ['\u{118b4}', '\0', '\0']), ('\u{118d5}', ['\u{118b5}', '\0', '\0']), - ('\u{118d6}', ['\u{118b6}', '\0', '\0']), ('\u{118d7}', ['\u{118b7}', '\0', '\0']), - ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}', ['\u{118b9}', '\0', '\0']), - ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']), - ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']), - ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0']), - ('\u{16e60}', ['\u{16e40}', '\0', '\0']), ('\u{16e61}', ['\u{16e41}', '\0', '\0']), - ('\u{16e62}', ['\u{16e42}', '\0', '\0']), ('\u{16e63}', ['\u{16e43}', '\0', '\0']), - ('\u{16e64}', ['\u{16e44}', '\0', '\0']), ('\u{16e65}', ['\u{16e45}', '\0', '\0']), - ('\u{16e66}', ['\u{16e46}', '\0', '\0']), ('\u{16e67}', ['\u{16e47}', '\0', '\0']), - ('\u{16e68}', ['\u{16e48}', '\0', '\0']), ('\u{16e69}', ['\u{16e49}', '\0', '\0']), - ('\u{16e6a}', ['\u{16e4a}', '\0', '\0']), ('\u{16e6b}', ['\u{16e4b}', '\0', '\0']), - ('\u{16e6c}', ['\u{16e4c}', '\0', '\0']), ('\u{16e6d}', ['\u{16e4d}', '\0', '\0']), - ('\u{16e6e}', ['\u{16e4e}', '\0', '\0']), ('\u{16e6f}', ['\u{16e4f}', '\0', '\0']), - ('\u{16e70}', ['\u{16e50}', '\0', '\0']), ('\u{16e71}', ['\u{16e51}', '\0', '\0']), - ('\u{16e72}', ['\u{16e52}', '\0', '\0']), ('\u{16e73}', ['\u{16e53}', '\0', '\0']), - ('\u{16e74}', ['\u{16e54}', '\0', '\0']), ('\u{16e75}', ['\u{16e55}', '\0', '\0']), - ('\u{16e76}', ['\u{16e56}', '\0', '\0']), ('\u{16e77}', ['\u{16e57}', '\0', '\0']), - ('\u{16e78}', ['\u{16e58}', '\0', '\0']), ('\u{16e79}', ['\u{16e59}', '\0', '\0']), - ('\u{16e7a}', ['\u{16e5a}', '\0', '\0']), ('\u{16e7b}', ['\u{16e5b}', '\0', '\0']), - ('\u{16e7c}', ['\u{16e5c}', '\0', '\0']), ('\u{16e7d}', ['\u{16e5d}', '\0', '\0']), - ('\u{16e7e}', ['\u{16e5e}', '\0', '\0']), ('\u{16e7f}', ['\u{16e5f}', '\0', '\0']), - ('\u{1e922}', ['\u{1e900}', '\0', '\0']), ('\u{1e923}', ['\u{1e901}', '\0', '\0']), - ('\u{1e924}', ['\u{1e902}', '\0', '\0']), ('\u{1e925}', ['\u{1e903}', '\0', '\0']), - ('\u{1e926}', ['\u{1e904}', '\0', '\0']), ('\u{1e927}', ['\u{1e905}', '\0', '\0']), - ('\u{1e928}', ['\u{1e906}', '\0', '\0']), ('\u{1e929}', ['\u{1e907}', '\0', '\0']), - ('\u{1e92a}', ['\u{1e908}', '\0', '\0']), ('\u{1e92b}', ['\u{1e909}', '\0', '\0']), - ('\u{1e92c}', ['\u{1e90a}', '\0', '\0']), ('\u{1e92d}', ['\u{1e90b}', '\0', '\0']), - ('\u{1e92e}', ['\u{1e90c}', '\0', '\0']), ('\u{1e92f}', ['\u{1e90d}', '\0', '\0']), - ('\u{1e930}', ['\u{1e90e}', '\0', '\0']), ('\u{1e931}', ['\u{1e90f}', '\0', '\0']), - ('\u{1e932}', ['\u{1e910}', '\0', '\0']), ('\u{1e933}', ['\u{1e911}', '\0', '\0']), - ('\u{1e934}', ['\u{1e912}', '\0', '\0']), ('\u{1e935}', ['\u{1e913}', '\0', '\0']), - ('\u{1e936}', ['\u{1e914}', '\0', '\0']), ('\u{1e937}', ['\u{1e915}', '\0', '\0']), - ('\u{1e938}', ['\u{1e916}', '\0', '\0']), ('\u{1e939}', ['\u{1e917}', '\0', '\0']), - ('\u{1e93a}', ['\u{1e918}', '\0', '\0']), ('\u{1e93b}', ['\u{1e919}', '\0', '\0']), - ('\u{1e93c}', ['\u{1e91a}', '\0', '\0']), ('\u{1e93d}', ['\u{1e91b}', '\0', '\0']), - ('\u{1e93e}', ['\u{1e91c}', '\0', '\0']), ('\u{1e93f}', ['\u{1e91d}', '\0', '\0']), - ('\u{1e940}', ['\u{1e91e}', '\0', '\0']), ('\u{1e941}', ['\u{1e91f}', '\0', '\0']), - ('\u{1e942}', ['\u{1e920}', '\0', '\0']), ('\u{1e943}', ['\u{1e921}', '\0', '\0']) - ]; -} diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py deleted file mode 100755 index 97df92a56da66..0000000000000 --- a/src/libcore/unicode/unicode.py +++ /dev/null @@ -1,878 +0,0 @@ -#!/usr/bin/env python - -""" -Regenerate Unicode tables (tables.rs). -""" - -# This script uses the Unicode tables as defined -# in the UnicodeFiles class. - -# Since this should not require frequent updates, we just store this -# out-of-line and check the tables.rs file into git. - -# Note that the "curl" program is required for operation. -# This script is compatible with Python 2.7 and 3.x. - -import argparse -import datetime -import fileinput -import itertools -import os -import re -import textwrap -import subprocess - -from collections import defaultdict, namedtuple - -try: - # Python 3 - from itertools import zip_longest - from io import StringIO -except ImportError: - # Python 2 compatibility - zip_longest = itertools.izip_longest - from StringIO import StringIO - -try: - # Completely optional type hinting - # (Python 2 compatible using comments, - # see: https://mypy.readthedocs.io/en/latest/python2.html) - # This is very helpful in typing-aware IDE like PyCharm. - from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple -except ImportError: - pass - - -# We don't use enum.Enum because of Python 2.7 compatibility. -class UnicodeFiles(object): - # ReadMe does not contain any Unicode data, we - # only use it to extract versions. - README = "ReadMe.txt" - - DERIVED_CORE_PROPERTIES = "DerivedCoreProperties.txt" - DERIVED_NORMALIZATION_PROPS = "DerivedNormalizationProps.txt" - PROPS = "PropList.txt" - SCRIPTS = "Scripts.txt" - SPECIAL_CASING = "SpecialCasing.txt" - UNICODE_DATA = "UnicodeData.txt" - - -# The order doesn't really matter (Python < 3.6 won't preserve it), -# we only want to aggregate all the file names. -ALL_UNICODE_FILES = tuple( - value for name, value in UnicodeFiles.__dict__.items() - if not name.startswith("_") -) - -assert len(ALL_UNICODE_FILES) == 7, "Unexpected number of unicode files" - -# The directory this file is located in. -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) - -# Where to download the Unicode data. The downloaded files -# will be placed in sub-directories named after Unicode version. -FETCH_DIR = os.path.join(THIS_DIR, "downloaded") - -FETCH_URL_LATEST = "ftp://ftp.unicode.org/Public/UNIDATA/{filename}" -FETCH_URL_VERSION = "ftp://ftp.unicode.org/Public/{version}/ucd/{filename}" - -PREAMBLE = """\ -// NOTE: The following code was generated by "./unicode.py", do not edit directly - -#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] - -use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; -use crate::unicode::version::UnicodeVersion; -""".format(year=datetime.datetime.now().year) - -# Mapping taken from Table 12 from: -# http://www.unicode.org/reports/tr44/#General_Category_Values -EXPANDED_CATEGORIES = { - "Lu": ["LC", "L"], "Ll": ["LC", "L"], "Lt": ["LC", "L"], - "Lm": ["L"], "Lo": ["L"], - "Mn": ["M"], "Mc": ["M"], "Me": ["M"], - "Nd": ["N"], "Nl": ["N"], "No": ["N"], - "Pc": ["P"], "Pd": ["P"], "Ps": ["P"], "Pe": ["P"], - "Pi": ["P"], "Pf": ["P"], "Po": ["P"], - "Sm": ["S"], "Sc": ["S"], "Sk": ["S"], "So": ["S"], - "Zs": ["Z"], "Zl": ["Z"], "Zp": ["Z"], - "Cc": ["C"], "Cf": ["C"], "Cs": ["C"], "Co": ["C"], "Cn": ["C"], -} - -# This is the (inclusive) range of surrogate codepoints. -# These are not valid Rust characters. -SURROGATE_CODEPOINTS_RANGE = (0xd800, 0xdfff) - -UnicodeData = namedtuple( - "UnicodeData", ( - # Conversions: - "to_upper", "to_lower", "to_title", - - # Decompositions: canonical decompositions, compatibility decomp - "canon_decomp", "compat_decomp", - - # Grouped: general categories and combining characters - "general_categories", "combines", - ) -) - -UnicodeVersion = namedtuple( - "UnicodeVersion", ("major", "minor", "micro", "as_str") -) - - -def fetch_files(version=None): - # type: (str) -> UnicodeVersion - """ - Fetch all the Unicode files from unicode.org. - - This will use cached files (stored in `FETCH_DIR`) if they exist, - creating them if they don't. In any case, the Unicode version - is always returned. - - :param version: The desired Unicode version, as string. - (If None, defaults to latest final release available, - querying the unicode.org service). - """ - have_version = check_stored_version(version) - if have_version: - return have_version - - if version: - # Check if the desired version exists on the server. - get_fetch_url = lambda name: FETCH_URL_VERSION.format(version=version, filename=name) - else: - # Extract the latest version. - get_fetch_url = lambda name: FETCH_URL_LATEST.format(filename=name) - - readme_url = get_fetch_url(UnicodeFiles.README) - - print("Fetching: {}".format(readme_url)) - readme_content = subprocess.check_output(("curl", readme_url)) - - unicode_version = parse_readme_unicode_version( - readme_content.decode("utf8") - ) - - download_dir = get_unicode_dir(unicode_version) - if not os.path.exists(download_dir): - # For 2.7 compat, we don't use `exist_ok=True`. - os.makedirs(download_dir) - - for filename in ALL_UNICODE_FILES: - file_path = get_unicode_file_path(unicode_version, filename) - - if os.path.exists(file_path): - # Assume file on the server didn't change if it's been saved before. - continue - - if filename == UnicodeFiles.README: - with open(file_path, "wb") as fd: - fd.write(readme_content) - else: - url = get_fetch_url(filename) - print("Fetching: {}".format(url)) - subprocess.check_call(("curl", "-o", file_path, url)) - - return unicode_version - - -def check_stored_version(version): - # type: (Optional[str]) -> Optional[UnicodeVersion] - """ - Given desired Unicode version, return the version - if stored files are all present, and `None` otherwise. - """ - if not version: - # If no desired version specified, we should check what's the latest - # version, skipping stored version checks. - return None - - fetch_dir = os.path.join(FETCH_DIR, version) - - for filename in ALL_UNICODE_FILES: - file_path = os.path.join(fetch_dir, filename) - - if not os.path.exists(file_path): - return None - - with open(os.path.join(fetch_dir, UnicodeFiles.README)) as fd: - return parse_readme_unicode_version(fd.read()) - - -def parse_readme_unicode_version(readme_content): - # type: (str) -> UnicodeVersion - """ - Parse the Unicode version contained in their `ReadMe.txt` file. - """ - # "Raw string" is necessary for \d not being treated as escape char - # (for the sake of compat with future Python versions). - # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior - pattern = r"for Version (\d+)\.(\d+)\.(\d+) of the Unicode" - groups = re.search(pattern, readme_content).groups() - - return UnicodeVersion(*map(int, groups), as_str=".".join(groups)) - - -def get_unicode_dir(unicode_version): - # type: (UnicodeVersion) -> str - """ - Indicate in which parent dir the Unicode data files should be stored. - - This returns a full, absolute path. - """ - return os.path.join(FETCH_DIR, unicode_version.as_str) - - -def get_unicode_file_path(unicode_version, filename): - # type: (UnicodeVersion, str) -> str - """ - Indicate where the Unicode data file should be stored. - """ - return os.path.join(get_unicode_dir(unicode_version), filename) - - -def is_surrogate(n): - # type: (int) -> bool - """ - Tell if given codepoint is a surrogate (not a valid Rust character). - """ - return SURROGATE_CODEPOINTS_RANGE[0] <= n <= SURROGATE_CODEPOINTS_RANGE[1] - - -def load_unicode_data(file_path): - # type: (str) -> UnicodeData - """ - Load main Unicode data. - """ - # Conversions - to_lower = {} # type: Dict[int, Tuple[int, int, int]] - to_upper = {} # type: Dict[int, Tuple[int, int, int]] - to_title = {} # type: Dict[int, Tuple[int, int, int]] - - # Decompositions - compat_decomp = {} # type: Dict[int, List[int]] - canon_decomp = {} # type: Dict[int, List[int]] - - # Combining characters - # FIXME: combines are not used - combines = defaultdict(set) # type: Dict[str, Set[int]] - - # Categories - general_categories = defaultdict(set) # type: Dict[str, Set[int]] - category_assigned_codepoints = set() # type: Set[int] - - all_codepoints = {} - - range_start = -1 - - for line in fileinput.input(file_path): - data = line.split(";") - if len(data) != 15: - continue - codepoint = int(data[0], 16) - if is_surrogate(codepoint): - continue - if range_start >= 0: - for i in range(range_start, codepoint): - all_codepoints[i] = data - range_start = -1 - if data[1].endswith(", First>"): - range_start = codepoint - continue - all_codepoints[codepoint] = data - - for code, data in all_codepoints.items(): - (code_org, name, gencat, combine, bidi, - decomp, deci, digit, num, mirror, - old, iso, upcase, lowcase, titlecase) = data - - # Generate char to char direct common and simple conversions: - - # Uppercase to lowercase - if lowcase != "" and code_org != lowcase: - to_lower[code] = (int(lowcase, 16), 0, 0) - - # Lowercase to uppercase - if upcase != "" and code_org != upcase: - to_upper[code] = (int(upcase, 16), 0, 0) - - # Title case - if titlecase.strip() != "" and code_org != titlecase: - to_title[code] = (int(titlecase, 16), 0, 0) - - # Store decomposition, if given - if decomp: - decompositions = decomp.split()[1:] - decomp_code_points = [int(i, 16) for i in decompositions] - - if decomp.startswith("<"): - # Compatibility decomposition - compat_decomp[code] = decomp_code_points - else: - # Canonical decomposition - canon_decomp[code] = decomp_code_points - - # Place letter in categories as appropriate. - for cat in itertools.chain((gencat, ), EXPANDED_CATEGORIES.get(gencat, [])): - general_categories[cat].add(code) - category_assigned_codepoints.add(code) - - # Record combining class, if any. - if combine != "0": - combines[combine].add(code) - - # Generate Not_Assigned from Assigned. - general_categories["Cn"] = get_unassigned_codepoints(category_assigned_codepoints) - - # Other contains Not_Assigned - general_categories["C"].update(general_categories["Cn"]) - - grouped_categories = group_categories(general_categories) - - # FIXME: combines are not used - return UnicodeData( - to_lower=to_lower, to_upper=to_upper, to_title=to_title, - compat_decomp=compat_decomp, canon_decomp=canon_decomp, - general_categories=grouped_categories, combines=combines, - ) - - -def load_special_casing(file_path, unicode_data): - # type: (str, UnicodeData) -> None - """ - Load special casing data and enrich given Unicode data. - """ - for line in fileinput.input(file_path): - data = line.split("#")[0].split(";") - if len(data) == 5: - code, lower, title, upper, _comment = data - elif len(data) == 6: - code, lower, title, upper, condition, _comment = data - if condition.strip(): # Only keep unconditional mappins - continue - else: - continue - code = code.strip() - lower = lower.strip() - title = title.strip() - upper = upper.strip() - key = int(code, 16) - for (map_, values) in ((unicode_data.to_lower, lower), - (unicode_data.to_upper, upper), - (unicode_data.to_title, title)): - if values != code: - split = values.split() - - codepoints = list(itertools.chain( - (int(i, 16) for i in split), - (0 for _ in range(len(split), 3)) - )) - - assert len(codepoints) == 3 - map_[key] = codepoints - - -def group_categories(mapping): - # type: (Dict[Any, Iterable[int]]) -> Dict[str, List[Tuple[int, int]]] - """ - Group codepoints mapped in "categories". - """ - return {category: group_codepoints(codepoints) - for category, codepoints in mapping.items()} - - -def group_codepoints(codepoints): - # type: (Iterable[int]) -> List[Tuple[int, int]] - """ - Group integral values into continuous, disjoint value ranges. - - Performs value deduplication. - - :return: sorted list of pairs denoting start and end of codepoint - group values, both ends inclusive. - - >>> group_codepoints([1, 2, 10, 11, 12, 3, 4]) - [(1, 4), (10, 12)] - >>> group_codepoints([1]) - [(1, 1)] - >>> group_codepoints([1, 5, 6]) - [(1, 1), (5, 6)] - >>> group_codepoints([]) - [] - """ - sorted_codes = sorted(set(codepoints)) - result = [] # type: List[Tuple[int, int]] - - if not sorted_codes: - return result - - next_codes = sorted_codes[1:] - start_code = sorted_codes[0] - - for code, next_code in zip_longest(sorted_codes, next_codes, fillvalue=None): - if next_code is None or next_code - code != 1: - result.append((start_code, code)) - start_code = next_code - - return result - - -def ungroup_codepoints(codepoint_pairs): - # type: (Iterable[Tuple[int, int]]) -> List[int] - """ - The inverse of group_codepoints -- produce a flat list of values - from value range pairs. - - >>> ungroup_codepoints([(1, 4), (10, 12)]) - [1, 2, 3, 4, 10, 11, 12] - >>> ungroup_codepoints([(1, 1), (5, 6)]) - [1, 5, 6] - >>> ungroup_codepoints(group_codepoints([1, 2, 7, 8])) - [1, 2, 7, 8] - >>> ungroup_codepoints([]) - [] - """ - return list(itertools.chain.from_iterable( - range(lo, hi + 1) for lo, hi in codepoint_pairs - )) - - -def get_unassigned_codepoints(assigned_codepoints): - # type: (Set[int]) -> Set[int] - """ - Given a set of "assigned" codepoints, return a set - of these that are not in assigned and not surrogate. - """ - return {i for i in range(0, 0x110000) - if i not in assigned_codepoints and not is_surrogate(i)} - - -def generate_table_lines(items, indent, wrap=98): - # type: (Iterable[str], int, int) -> Iterator[str] - """ - Given table items, generate wrapped lines of text with comma-separated items. - - This is a generator function. - - :param wrap: soft wrap limit (characters per line), integer. - """ - line = " " * indent - first = True - for item in items: - if len(line) + len(item) < wrap: - if first: - line += item - else: - line += ", " + item - first = False - else: - yield line + ",\n" - line = " " * indent + item - - yield line - - -def load_properties(file_path, interesting_props): - # type: (str, Iterable[str]) -> Dict[str, List[Tuple[int, int]]] - """ - Load properties data and return in grouped form. - """ - props = defaultdict(list) # type: Dict[str, List[Tuple[int, int]]] - # "Raw string" is necessary for `\.` and `\w` not to be treated as escape chars - # (for the sake of compat with future Python versions). - # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior - re1 = re.compile(r"^ *([0-9A-F]+) *; *(\w+)") - re2 = re.compile(r"^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)") - - for line in fileinput.input(file_path): - match = re1.match(line) or re2.match(line) - if match: - groups = match.groups() - - if len(groups) == 2: - # `re1` matched (2 groups). - d_lo, prop = groups - d_hi = d_lo - else: - d_lo, d_hi, prop = groups - else: - continue - - if interesting_props and prop not in interesting_props: - continue - - lo_value = int(d_lo, 16) - hi_value = int(d_hi, 16) - - props[prop].append((lo_value, hi_value)) - - # Optimize if possible. - for prop in props: - props[prop] = group_codepoints(ungroup_codepoints(props[prop])) - - return props - - -def escape_char(c): - # type: (int) -> str - r""" - Escape a codepoint for use as Rust char literal. - - Outputs are OK to use as Rust source code as char literals - and they also include necessary quotes. - - >>> escape_char(97) - "'\\u{61}'" - >>> escape_char(0) - "'\\0'" - """ - return r"'\u{%x}'" % c if c != 0 else r"'\0'" - - -def format_char_pair(pair): - # type: (Tuple[int, int]) -> str - """ - Format a pair of two Rust chars. - """ - return "(%s,%s)" % (escape_char(pair[0]), escape_char(pair[1])) - - -def generate_table( - name, # type: str - items, # type: List[Tuple[int, int]] - decl_type="&[(char, char)]", # type: str - is_pub=True, # type: bool - format_item=format_char_pair, # type: Callable[[Tuple[int, int]], str] -): - # type: (...) -> Iterator[str] - """ - Generate a nicely formatted Rust constant "table" array. - - This generates actual Rust code. - """ - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield " %sconst %s: %s = &[\n" % (pub_string, name, decl_type) - - data = [] - first = True - for item in items: - if not first: - data.append(",") - first = False - data.extend(format_item(item)) - - for table_line in generate_table_lines("".join(data).split(","), 8): - yield table_line - - yield "\n ];\n" - - -def compute_trie(raw_data, chunk_size): - # type: (List[int], int) -> Tuple[List[int], List[int]] - """ - Compute postfix-compressed trie. - - See: bool_trie.rs for more details. - - >>> compute_trie([1, 2, 3, 1, 2, 3, 4, 5, 6], 3) - ([0, 0, 1], [1, 2, 3, 4, 5, 6]) - >>> compute_trie([1, 2, 3, 1, 2, 4, 4, 5, 6], 3) - ([0, 1, 2], [1, 2, 3, 1, 2, 4, 4, 5, 6]) - """ - root = [] - childmap = {} # type: Dict[Tuple[int, ...], int] - child_data = [] - - assert len(raw_data) % chunk_size == 0, "Chunks must be equally sized" - - for i in range(len(raw_data) // chunk_size): - data = raw_data[i * chunk_size : (i + 1) * chunk_size] - - # Postfix compression of child nodes (data chunks) - # (identical child nodes are shared). - - # Make a tuple out of the list so it's hashable. - child = tuple(data) - if child not in childmap: - childmap[child] = len(childmap) - child_data.extend(data) - - root.append(childmap[child]) - - return root, child_data - - -def generate_bool_trie(name, codepoint_ranges, is_pub=False): - # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] - """ - Generate Rust code for BoolTrie struct. - - This yields string fragments that should be joined to produce - the final string. - - See: `bool_trie.rs`. - """ - chunk_size = 64 - rawdata = [False] * 0x110000 - for (lo, hi) in codepoint_ranges: - for cp in range(lo, hi + 1): - rawdata[cp] = True - - # Convert to bitmap chunks of `chunk_size` bits each. - chunks = [] - for i in range(0x110000 // chunk_size): - chunk = 0 - for j in range(chunk_size): - if rawdata[i * chunk_size + j]: - chunk |= 1 << j - chunks.append(chunk) - - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield " %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name) - yield " r1: [\n" - data = ("0x%016x" % chunk for chunk in chunks[:0x800 // chunk_size]) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - # 0x800..0x10000 trie - (r2, r3) = compute_trie(chunks[0x800 // chunk_size : 0x10000 // chunk_size], 64 // chunk_size) - yield " r2: [\n" - data = map(str, r2) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r3: &[\n" - data = ("0x%016x" % node for node in r3) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - # 0x10000..0x110000 trie - (mid, r6) = compute_trie(chunks[0x10000 // chunk_size : 0x110000 // chunk_size], - 64 // chunk_size) - (r4, r5) = compute_trie(mid, 64) - - yield " r4: [\n" - data = map(str, r4) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r5: &[\n" - data = map(str, r5) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r6: &[\n" - data = ("0x%016x" % node for node in r6) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " };\n" - - -def generate_small_bool_trie(name, codepoint_ranges, is_pub=False): - # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] - """ - Generate Rust code for `SmallBoolTrie` struct. - - See: `bool_trie.rs`. - """ - last_chunk = max(hi // 64 for (lo, hi) in codepoint_ranges) - n_chunks = last_chunk + 1 - chunks = [0] * n_chunks - for (lo, hi) in codepoint_ranges: - for cp in range(lo, hi + 1): - assert cp // 64 < len(chunks) - chunks[cp // 64] |= 1 << (cp & 63) - - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield (" %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n" - % (pub_string, name)) - - (r1, r2) = compute_trie(chunks, 1) - - yield " r1: &[\n" - data = (str(node) for node in r1) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r2: &[\n" - data = ("0x%016x" % node for node in r2) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " };\n" - - -def generate_property_module(mod, grouped_categories, category_subset): - # type: (str, Dict[str, List[Tuple[int, int]]], Iterable[str]) -> Iterator[str] - """ - Generate Rust code for module defining properties. - """ - - yield "pub(crate) mod %s {" % mod - for cat in sorted(category_subset): - if cat in ("Cc", "White_Space"): - generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat]) - else: - generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat]) - - for fragment in generator: - yield fragment - - yield "\n" - yield " pub fn %s(c: char) -> bool {\n" % cat - yield " %s_table.lookup(c)\n" % cat - yield " }\n" - - yield "}\n\n" - - -def generate_conversions_module(unicode_data): - # type: (UnicodeData) -> Iterator[str] - """ - Generate Rust code for module defining conversions. - """ - - yield "pub(crate) mod conversions {" - yield """ - pub fn to_lower(c: char) -> [char; 3] { - match bsearch_case_table(c, to_lowercase_table) { - None => [c, '\\0', '\\0'], - Some(index) => to_lowercase_table[index].1, - } - } - - pub fn to_upper(c: char) -> [char; 3] { - match bsearch_case_table(c, to_uppercase_table) { - None => [c, '\\0', '\\0'], - Some(index) => to_uppercase_table[index].1, - } - } - - fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { - table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() - }\n""" - - decl_type = "&[(char, [char; 3])]" - format_conversion = lambda x: "({},[{},{},{}])".format(*( - escape_char(c) for c in (x[0], x[1][0], x[1][1], x[1][2]) - )) - - for fragment in generate_table( - name="to_lowercase_table", - items=sorted(unicode_data.to_lower.items(), key=lambda x: x[0]), - decl_type=decl_type, - is_pub=False, - format_item=format_conversion - ): - yield fragment - - for fragment in generate_table( - name="to_uppercase_table", - items=sorted(unicode_data.to_upper.items(), key=lambda x: x[0]), - decl_type=decl_type, - is_pub=False, - format_item=format_conversion - ): - yield fragment - - yield "}\n" - - -def parse_args(): - # type: () -> argparse.Namespace - """ - Parse command line arguments. - """ - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("-v", "--version", default=None, type=str, - help="Unicode version to use (if not specified," - " defaults to latest release).") - - return parser.parse_args() - - -def main(): - # type: () -> None - """ - Script entry point. - """ - args = parse_args() - - unicode_version = fetch_files(args.version) - print("Using Unicode version: {}".format(unicode_version.as_str)) - - # All the writing happens entirely in memory, we only write to file - # once we have generated the file content (it's not very large, <1 MB). - buf = StringIO() - buf.write(PREAMBLE) - - unicode_version_notice = textwrap.dedent(""" - /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of - /// `char` and `str` methods are based on. - #[unstable(feature = "unicode_version", issue = "49726")] - pub const UNICODE_VERSION: UnicodeVersion = - UnicodeVersion {{ major: {v.major}, minor: {v.minor}, micro: {v.micro}, _priv: () }}; - """).format(v=unicode_version) - buf.write(unicode_version_notice) - - get_path = lambda f: get_unicode_file_path(unicode_version, f) - - unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA)) - load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data) - - want_derived = {"Alphabetic", "Lowercase", "Uppercase", - "Cased", "Case_Ignorable", "Grapheme_Extend"} - derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived) - - props = load_properties(get_path(UnicodeFiles.PROPS), - {"White_Space", "Join_Control", "Noncharacter_Code_Point"}) - - # Category tables - for (name, categories, category_subset) in ( - ("general_category", unicode_data.general_categories, ["N", "Cc"]), - ("derived_property", derived, want_derived), - ("property", props, ["White_Space"]) - ): - for fragment in generate_property_module(name, categories, category_subset): - buf.write(fragment) - - for fragment in generate_conversions_module(unicode_data): - buf.write(fragment) - - tables_rs_path = os.path.join(THIS_DIR, "tables.rs") - - # Actually write out the file content. - # Will overwrite the file if it exists. - with open(tables_rs_path, "w") as fd: - fd.write(buf.getvalue()) - - print("Regenerated tables.rs.") - - -if __name__ == "__main__": - main() diff --git a/src/libcore/unicode/unicode_data.rs b/src/libcore/unicode/unicode_data.rs new file mode 100644 index 0000000000000..da4cd4e9b1da1 --- /dev/null +++ b/src/libcore/unicode/unicode_data.rs @@ -0,0 +1,2343 @@ +///! This file is generated by src/tools/unicode-table-generator; do not edit manually! +use super::range_search; + +pub const UNICODE_VERSION: (u32, u32, u32) = (12, 1, 0); + +#[rustfmt::skip] +pub mod alphabetic { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (190, 37); + static BITSET_CHUNKS_MAP: [u8; 187] = [ + 6, 32, 10, 18, 19, 23, 21, 12, 7, 5, 0, 20, 14, 49, 49, 49, 49, 49, 49, 36, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 47, 49, 30, 8, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 45, 0, 0, 0, 0, 0, 0, 0, 0, 4, 35, 17, 31, 16, 25, 24, 26, 13, 15, + 44, 27, 0, 0, 49, 11, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 49, 49, 49, 49, 49, 48, + 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 28, 0, 0, 0, 0, 0, 29, 0, 0, 9, 0, 33, 2, 3, 0, 0, + 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 41, 49, 49, 49, + 43, 22, 49, 49, 49, 49, 40, 49, 49, 49, 49, 49, 49, 46, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 50] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 248, 241, 38, 40], + [0, 0, 0, 0, 0, 0, 0, 0, 108, 133, 110, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 190, 200, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 248, 248, 248, 248, 248, 205, 248, 23, 134, 245, 68, 237], + [0, 0, 179, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 103, 99, 176, 248, 248, 248, 248, 248, 248, 248, 61, 0, 151, 217, 178], + [0, 145, 28, 0, 168, 221, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [48, 77, 248, 165, 201, 120, 184, 137, 91, 175, 143, 83, 206, 196, 248, 56], + [53, 0, 0, 0, 126, 15, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0], + [59, 54, 127, 199, 167, 186, 157, 114, 154, 84, 160, 115, 158, 66, 155, 21], + [62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [91, 129, 164, 101, 248, 248, 248, 79, 248, 248, 248, 248, 230, 128, 135, 117], + [97, 0, 220, 144, 0, 0, 212, 44, 142, 240, 30, 97, 0, 0, 0, 0], + [116, 247, 219, 171, 188, 248, 104, 190, 0, 0, 0, 0, 0, 0, 0, 0], + [141, 185, 88, 0, 149, 213, 22, 0, 0, 0, 0, 89, 0, 0, 0, 0], + [147, 90, 35, 82, 98, 0, 153, 0, 85, 119, 29, 45, 86, 71, 18, 0], + [150, 32, 248, 107, 0, 81, 0, 0, 0, 0, 227, 17, 211, 105, 231, 19], + [162, 41, 161, 69, 163, 173, 123, 73, 106, 14, 124, 37, 1, 187, 121, 0], + [172, 240, 228, 170, 248, 248, 248, 248, 248, 229, 138, 235, 234, 24, 222, 125], + [208, 233, 248, 74, 204, 64, 140, 232, 63, 0, 0, 0, 0, 0, 0, 0], + [220, 97, 202, 86, 94, 78, 203, 9, 226, 80, 46, 0, 183, 11, 174, 67], + [231, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248], + [247, 248, 248, 248, 248, 248, 248, 248, 248, 209, 225, 95, 76, 75, 180, 25], + [248, 5, 96, 50, 72, 87, 248, 26, 132, 0, 198, 51, 159, 42, 0, 0], + [248, 8, 72, 72, 49, 0, 0, 0, 0, 0, 0, 0, 194, 5, 0, 89], + [248, 36, 248, 7, 0, 0, 139, 31, 143, 3, 93, 0, 55, 0, 0, 0], + [248, 62, 248, 248, 248, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 118, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 236, 166, 246, 136, 239, 248, 248, 248, 248, 215, 169, 182, 207, 214, 12], + [248, 248, 13, 130, 248, 248, 248, 248, 57, 146, 248, 65, 218, 248, 243, 177], + [248, 248, 191, 111, 197, 43, 0, 0, 248, 248, 248, 248, 91, 47, 0, 0], + [248, 248, 244, 248, 189, 223, 152, 70, 224, 210, 248, 148, 240, 242, 68, 100], + [248, 248, 248, 4, 248, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 35, 195, 248, 248, 248, 248, 248, 113, 0, 0, 0, 0], + [248, 248, 248, 248, 131, 240, 238, 109, 0, 181, 248, 122, 102, 216, 143, 27], + [248, 248, 248, 248, 248, 248, 86, 0, 248, 248, 248, 248, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 33, 0, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 97, 35, 0, 60, 65, 156, 16, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 6, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 192, 248, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 20, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 72, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 81, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 23, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 193, 112], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 39], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 65], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 92], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248], + ]; + static BITSET: [u64; 249] = [ + 0, 1, 15, 17, 31, 63, 127, 179, 511, 1023, 2191, 4079, 4087, 8191, 8319, 16384, 65535, + 131071, 262143, 4128527, 8388607, 8461767, 24870911, 67108863, 134217727, 276824575, + 335544350, 486341884, 536805376, 536870911, 553648127, 1056964608, 1073692671, 1073741823, + 1140785663, 2147483647, 2147485627, 4026540127, 4294934783, 8589934591, 47244640256, + 64548249055, 68191066527, 68719476735, 115913785343, 137438953215, 549755813888, + 1095220854783, 1099511627711, 1099511627775, 2199023190016, 2199023255551, 4398046511103, + 8641373536127, 8791831609343, 8795690369023, 8796093022207, 13198434443263, 17592186044415, + 35184321757183, 70368744112128, 88094074470339, 140737488355327, 140737488355328, + 141836999983103, 281474976710655, 563017343310239, 1125625028935679, 1125899906842623, + 1688915364814303, 2119858418286774, 2251795522912255, 2251799813685247, 3377704004976767, + 3509778554814463, 3905461007941631, 4503595333443583, 4503599627370495, 8796093022142464, + 9006649498927104, 9007192812290047, 9007199254740991, 15762594400829440, 17169970223906821, + 17732925109967239, 18014398491652207, 18014398509481983, 20266198323101808, + 36027697507139583, 36028792723996672, 36028792728190975, 36028797018963967, + 72057594037927935, 90071992547409919, 143851303137705983, 144053615424700415, + 144115188075855868, 144115188075855871, 288230371860938751, 297241973452963840, + 301749971126844416, 319718190147960832, 576460743713488896, 576460743847706622, + 576460748008488959, 576460752303359999, 576460752303423486, 576460752303423487, + 790380184120328175, 1152640029630136575, 1152917029519358975, 1152921504591118335, + 1152921504606845055, 1152921504606846975, 1153765996922689951, 2161727885562420159, + 2251241253188403424, 2295745090394464220, 2305570330330005503, 2305843004918726656, + 2305843004919250943, 2305843009196916483, 2305843009213693951, 3457638613854978028, + 4323455298678290390, 4557642822898941951, 4575692405780512767, 4602678814877679616, + 4611686017001275199, 4611686018360336384, 4611686018427322368, 4611686018427387903, + 4656722014700830719, 6843210385291930244, 6881498031078244479, 6908521828386340863, + 8935141660164089791, 8935423131384840192, 9168765891372858879, 9169328841326329855, + 9187201948305063935, 9187343239835811327, 9216616637413720063, 9223372036854775807, + 9223372041149743103, 9223934986808197120, 10371930679322607615, 10502394331027995967, + 11241233151490523135, 13006395723845991295, 13258596753222922239, 13609596598936928288, + 13834776580305453567, 13907115649320091647, 14082190885810440174, 14123225865944680428, + 16212958624174047247, 16412803692974677999, 16424062692043104238, 16424062692043104239, + 16424062692043243502, 16424625641996804079, 16429129241624174575, 16717361816799141871, + 16717361816799216127, 16788293510930366511, 17005555242810474495, 17293822569102704639, + 17581979622616071300, 17870283321271910397, 17870283321406070975, 17870283321406128127, + 17978369712463020031, 18158513764145585631, 18158781978395017215, 18194542490281852927, + 18410715276682199039, 18410715276690587772, 18428729675200069631, 18428729675200069632, + 18433233274827440127, 18437455399478099968, 18437736874452713471, 18442240474082181119, + 18444492273895866367, 18445618173802708993, 18446181192473632767, 18446216308128218879, + 18446462598732840928, 18446462598732840959, 18446462598732840960, 18446462599806582783, + 18446462615912710143, 18446462667452317695, 18446463149025525759, 18446463629525450752, + 18446463698110251007, 18446463698244468735, 18446464796682337663, 18446466966713532416, + 18446466996779287551, 18446471394825862144, 18446471394825863167, 18446480190918885375, + 18446498607738650623, 18446532967477018623, 18446602782178705022, 18446603336221163519, + 18446603336221196287, 18446638520593285119, 18446673709243564031, 18446708893632430079, + 18446740770879700992, 18446741595513422027, 18446741874686295551, 18446743249075830783, + 18446743798965862398, 18446744056529672000, 18446744060816261120, 18446744068886102015, + 18446744069414584320, 18446744069414601696, 18446744069414649855, 18446744069456527359, + 18446744069548736512, 18446744069548802046, 18446744069683019775, 18446744069951455231, + 18446744070421282815, 18446744070446333439, 18446744070475743231, 18446744070488326143, + 18446744071553646463, 18446744071562067967, 18446744073696837631, 18446744073701162813, + 18446744073707454463, 18446744073709027328, 18446744073709355007, 18446744073709419615, + 18446744073709486080, 18446744073709520895, 18446744073709543424, 18446744073709550079, + 18446744073709550595, 18446744073709551579, 18446744073709551599, 18446744073709551614, + 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod case_ignorable { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (896, 33); + static BITSET_CHUNKS_MAP: [u8; 125] = [ + 25, 14, 21, 30, 28, 4, 17, 23, 22, 0, 0, 16, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 6, 9, 0, 7, 11, 32, 31, 26, 29, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, + 10, 0, 8, 0, 20, 0, 12, 0, 1, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 34] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 47, 52], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 171, 2], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 88, 134, 38], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 102, 6, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 76, 26, 0, 146, 136, 79, 43, 117], + [0, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 58, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 165, 97, 75, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 48, 0, 114, 0, 0], + [0, 0, 0, 0, 0, 170, 68, 0, 0, 7, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0], + [0, 0, 0, 28, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 133, 0, 0, 0, 0, 15, 160, 45, 84, 51, 78, 12, 109], + [0, 0, 11, 0, 0, 30, 161, 90, 35, 80, 0, 69, 173, 13, 81, 129], + [0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 131, 0, 85, 0, 148, 0, 175, 73, 0, 0, 0, 0, 0, 0, 0], + [20, 4, 62, 0, 118, 0, 0, 0, 32, 154, 145, 0, 124, 89, 67, 86], + [25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [59, 0, 0, 150, 70, 24, 132, 60, 100, 122, 163, 99, 0, 46, 0, 66], + [63, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0], + [71, 33, 0, 178, 123, 83, 120, 137, 121, 98, 121, 167, 153, 55, 3, 18], + [72, 149, 36, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [104, 133, 0, 110, 174, 105, 177, 166, 0, 0, 0, 0, 0, 0, 155, 139], + [107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [111, 50, 106, 0, 0, 0, 0, 0, 0, 0, 172, 179, 179, 112, 9, 0], + [113, 0, 0, 0, 0, 0, 0, 49, 142, 34, 31, 0, 0, 0, 0, 0], + [116, 0, 42, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140, 93, 37, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0], + [159, 0, 101, 0, 158, 10, 29, 0, 0, 0, 0, 91, 0, 0, 0, 0], + [162, 56, 153, 54, 125, 53, 0, 27, 115, 21, 126, 19, 108, 144, 127, 8], + [168, 41, 151, 5, 0, 0, 157, 39, 156, 1, 103, 0, 65, 0, 0, 0], + [169, 147, 130, 17, 96, 87, 143, 16, 138, 0, 0, 64, 125, 95, 0, 0], + [176, 179, 0, 0, 179, 179, 179, 77, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 180] = [ + 0, 1, 3, 4, 8, 13, 15, 28, 64, 176, 191, 1016, 1792, 2047, 4080, 4096, 7680, 8192, 8193, + 16192, 30720, 32704, 32768, 131008, 262016, 2097152, 2359296, 6030336, 8323072, 10682368, + 33554432, 58719232, 159383552, 234881024, 243138688, 402587711, 536805376, 536879204, + 546307648, 805306369, 1073741824, 1073741916, 2113929216, 3221225472, 3758096384, + 4026531840, 4160749568, 4294934528, 4294967296, 4512022528, 5368709120, 17179869183, + 47244640256, 51539615774, 51539619904, 51543810078, 51545914817, 66035122176, 412316860416, + 412316862532, 412316893184, 1030792151040, 2199023255648, 8641373536127, 8763880767488, + 17303886364672, 36421322670080, 65128884076547, 65970697670631, 68168642985984, + 70093866270720, 70368739983360, 136957967529984, 140737488355328, 263882790666240, + 281470547525648, 281470682333183, 281474976710655, 281474976710656, 281474976710657, + 281479271675905, 562675075514368, 562949953355776, 563001509683710, 844424930131968, + 985162418487296, 1023920203366400, 2251799813685248, 3377699721314304, 4494803534348292, + 4503599627370678, 6755399441055744, 7881299349733376, 8444256867844096, 8725724278030336, + 8760633772212225, 8989057312882695, 9042383626829823, 9851624185018758, 24822575045541890, + 28848986089586688, 30958948903026688, 35747322042253312, 53805701016846336, + 58529202969772032, 72066390130950143, 112767012056334336, 143833713099145216, + 189151184399892480, 216172782113783808, 220713756545974272, 288301294651703296, + 302022650010533887, 504262420777140224, 558446353793941504, 572520102629474304, + 593978171557150752, 1008806350890729472, 1009933895770046464, 1152921504606846976, + 1152921504606846978, 1152921504606846982, 1153202979583561736, 1441151880758558727, + 1715871458028158991, 1729382256910270467, 2301902359539744768, 2305843009196908767, + 2305843009213693952, 2612078987781865472, 2771965570646540291, 3458764513820540928, + 3731232291276455943, 4539628424389459968, 4589168020290535424, 4611404543450677248, + 4611686018494513280, 4611686069967003678, 4671217976001691648, 6917775322003857411, + 7421334051581067264, 8070450532247928832, 8788774672813524990, 9205357638345293827, + 9222809086901354496, 9223091111633879040, 9223372036854775808, 9223372036854775935, + 9223512774343131136, 9224216320050987008, 9224497932466651184, 9653465801268658176, + 9727775195120332910, 10376293541461622786, 11526998316797657088, 11529215046068469760, + 12103423998558208000, 12699025049277956096, 13005832773892571136, 13798747783286489088, + 13832665517980123136, 13835058055282032640, 13835058055282163729, 13951307220663664640, + 17870283321406128128, 17906312118425092095, 18158513697557839871, 18158513749097456062, + 18374686479671623680, 18374686479671623682, 18444496122186563584, 18445618173802708992, + 18446462598732840960, 18446462598733004800, 18446726481523507200, 18446744069414584320, + 18446744069414584322, 18446744073575333888, 18446744073709027328, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod cased { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 6); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 13, 18, 0, 0, 12, 0, 0, 9, 14, 10, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 0, 16, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, + 0, 0, 0, 7, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 8, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 62, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 10, 0, 50, 62, 58, 20], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 42, 44, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 31, 0, 62, 62, 62, 0, 62, 62, 62, 62, 54, 26, 27, 24], + [0, 0, 39, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 51, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 25], + [0, 22, 19, 37, 62, 62, 36, 61, 62, 62, 18, 12, 0, 30, 49, 38], + [0, 29, 9, 0, 34, 52, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [46, 55, 62, 17, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [62, 6, 42, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [62, 56, 33, 60, 28, 57, 62, 62, 62, 62, 48, 35, 40, 45, 47, 5], + [62, 62, 59, 62, 41, 53, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 63] = [ + 0, 15, 24, 511, 1023, 4087, 65535, 16253055, 134217726, 536805376, 1073741823, 4294967295, + 133143986179, 4398046511103, 36009005809663, 70368744177663, 2251799813685247, + 3509778554814463, 144115188074807295, 297241973452963840, 504403158265495676, + 576460743713488896, 576460743847706622, 1152921504591118335, 2295745090394464220, + 4557642822898941951, 4611686017001275199, 6908521828386340863, 8935141660164089791, + 9223934986808197120, 13605092999309557792, 16717361816799216127, 16717361816799223999, + 17005555242810474495, 17446871633794956420, 17870283321271910397, 17870283321406128127, + 18410715276682199039, 18428729675200069631, 18428729675200069632, 18437736874452713471, + 18446462598732840959, 18446462598732840960, 18446463698110251007, 18446466996779287551, + 18446603336221163519, 18446603336221196287, 18446741874686295551, 18446743249075830783, + 18446744056529672000, 18446744056529682432, 18446744069414584320, 18446744069414601696, + 18446744069422972927, 18446744070475743231, 18446744071562067967, 18446744073707454463, + 18446744073709419615, 18446744073709517055, 18446744073709550595, 18446744073709551599, + 18446744073709551600, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod cc { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (0, 0); + static BITSET_CHUNKS_MAP: [u8; 0] = [ + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 1] = [ + [1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 3] = [ + 0, 4294967295, 9223372036854775808, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod grapheme_extend { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (896, 30); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 4, 15, 21, 27, 25, 3, 18, 23, 17, 0, 0, 14, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 7, 10, 0, 8, 12, 29, 28, 24, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 11, 0, 9, 0, 20, 0, 13, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 31] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 18, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 70, 102, 29], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 62, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 83, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 35, 66, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 35, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 45, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 130, 78, 60, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 37, 0, 90, 0, 0], + [0, 0, 0, 0, 0, 129, 54, 0, 0, 3, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0], + [0, 0, 0, 19, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 67, 0, 114, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 7, 0, 0, 0, 125, 5, 24, 63, 0, 55, 135, 9, 64, 100], + [0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [10, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [12, 0, 48, 0, 92, 0, 0, 0, 25, 119, 113, 0, 96, 71, 53, 68], + [46, 0, 0, 116, 57, 17, 101, 44, 81, 94, 127, 80, 0, 0, 0, 52], + [49, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0], + [56, 26, 0, 136, 95, 43, 107, 105, 93, 79, 93, 132, 128, 42, 104, 20], + [59, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [85, 0, 0, 87, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0], + [89, 0, 0, 0, 0, 0, 0, 38, 110, 27, 22, 0, 0, 0, 0, 0], + [109, 74, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0], + [124, 0, 82, 0, 123, 6, 21, 0, 0, 0, 0, 72, 0, 0, 0, 0], + [126, 40, 118, 39, 108, 41, 0, 34, 91, 14, 97, 13, 86, 112, 98, 4], + [133, 32, 120, 2, 0, 0, 122, 30, 121, 1, 84, 0, 51, 0, 0, 0], + [134, 115, 88, 0, 77, 69, 111, 11, 106, 0, 0, 50, 108, 76, 0, 0], + [137, 138, 0, 0, 138, 138, 138, 62, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 139] = [ + 0, 1, 13, 28, 64, 182, 191, 1016, 2032, 2047, 4096, 7680, 14336, 16128, 32640, 32768, + 131008, 262016, 491520, 8323072, 8396801, 10682368, 58719232, 100663296, 134152192, + 159383552, 234881024, 243138688, 536879204, 537919040, 805306369, 1073741824, 1073741916, + 1610612736, 2153546752, 3221225472, 3758096384, 4294967296, 4512022528, 51545911364, + 51545914817, 51548004382, 51552198686, 51556262398, 137438953472, 412316860416, + 412316862532, 1030792151040, 2199023255648, 8641373536127, 8763880767488, 17303886364672, + 36421322670080, 65128884076547, 65970697670631, 67755789254656, 69200441769984, + 70093866270720, 263882790666240, 277076930199552, 281470547525648, 281470681808895, + 281474976710655, 281479271675904, 562675075514368, 562949953355776, 844424930131968, + 985162418487296, 1023920203366400, 2251799813685248, 3377699721314304, 4494803534348292, + 6755399441055744, 7881299349733376, 8444256867844096, 8725724278030336, 8760633780600833, + 8989057312882695, 9042383626829823, 9851624185018758, 18067175067615234, 28848986089586688, + 30958948903026688, 35747322042253312, 53805701016846336, 58529202969772032, + 189151184399892480, 220713756545974272, 466122561432846339, 504262420777140224, + 558446353793941504, 572520102629474304, 1009933895770046464, 1152921504606846982, + 1152921504606851080, 1441151880758558727, 1724878657282899983, 2301902359539744768, + 2305843009196908767, 2305843009213693952, 2310337812748042240, 3731232291276455943, + 4589168020290535424, 4609293481125347328, 4611686018427387908, 4611686069975392286, + 4671217976001691648, 5764607523034234882, 6341068275337658371, 7421334051581067264, + 8788774672813524990, 9205357638345293827, 9222809086901354496, 9223090561878065152, + 9223372036854775808, 9223372036854775935, 9224497932466651184, 9727775195120332910, + 10376293541461622786, 11526998316797657088, 11959590285459062784, 12103423998558208000, + 12699165786766311424, 13005832773892571136, 13798747783286489088, 13835058055282032640, + 13835058055282163729, 13951307220663664640, 14987979559889010690, 17872468738205286400, + 17906312118425092095, 18158513697557839871, 18158513749097456062, 18374686479671623680, + 18374686479671623682, 18446462598732972032, 18446744056529158144, 18446744069414584320, + 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod lowercase { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (122, 6); + static BITSET_CHUNKS_MAP: [u8; 118] = [ + 12, 16, 0, 0, 10, 0, 0, 11, 13, 8, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 0, 17, 0, 9, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 18] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 62, 71, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 9, 0, 50, 42, 44, 28], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35], + [0, 0, 3, 0, 71, 71, 71, 0, 46, 46, 48, 46, 24, 37, 38, 23], + [0, 29, 27, 57, 39, 51, 52, 43, 41, 70, 26, 11, 0, 34, 64, 32], + [0, 40, 8, 0, 33, 60, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [22, 13, 54, 66, 25, 15, 56, 63, 30, 19, 12, 55, 58, 61, 65, 4], + [59, 36, 46, 21, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [59, 49, 45, 47, 18, 69, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [67, 5, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 72] = [ + 0, 15, 16, 511, 3063, 65535, 16253055, 134217726, 536805376, 984263338, 4294967295, + 133143986179, 274877905920, 1099509514240, 4398046445568, 17592185782272, 36009005809663, + 46912496118442, 187649984473770, 281474972516352, 2251799813685247, 2339875276368554, + 4503599560261632, 61925590106570972, 71777214282006783, 72057592964186127, + 144115188074807295, 297241973452963840, 504403158265495560, 576460743713488896, + 1152921487426978047, 1152921504590069760, 1814856824841797631, 3607524039012697088, + 4362299189061746720, 4539628424389459968, 4601013482110844927, 4611405638684049471, + 4674456033467236607, 6172933889249159850, 9223934986808197120, 10663022717737544362, + 10808545280696953514, 12261519110656315968, 12294970652241842346, 12297829382473033730, + 12297829382473034410, 12297829382473045332, 12297829382829550250, 12297829383904690175, + 12298110845996498944, 15324248332066007893, 16596095761559859497, 16717361816799215616, + 16987577794709946364, 17293822586148356092, 18158513701852807104, 18410715274543104000, + 18428729675466407935, 18446462598732840960, 18446462598732858304, 18446462598737002495, + 18446463698110251007, 18446673704966422527, 18446726481523572736, 18446739675663105535, + 18446739675663106031, 18446742974197923840, 18446744056529682432, 18446744069414584320, + 18446744073709529733, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod n { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 11); + static BITSET_CHUNKS_MAP: [u8; 124] = [ + 30, 7, 10, 24, 18, 3, 28, 20, 23, 27, 0, 15, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 12, 17, 25, 16, 22, 19, 14, 21, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 1, 0, 0, 9, 0, 13, 26, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 33] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 48], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 42, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 21, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 46, 0, 0, 0, 2], + [0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 30, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 30, 0, 44, 0, 30, 0, 30, 0, 40, 0, 33], + [0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 36, 43, 4, 0, 0, 0, 0, 51, 22, 3, 0, 12], + [0, 0, 0, 6, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 61, 46, 0, 0, 0, 0, 59, 0, 0, 23, 9, 0, 0], + [0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0], + [0, 14, 0, 14, 0, 0, 0, 0, 0, 14, 0, 2, 50, 0, 0, 0], + [0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 25, 0, 0, 0, 14, 24, 0, 0, 0, 0, 0, 0, 0, 0, 10], + [0, 31, 0, 46, 64, 0, 0, 38, 0, 0, 0, 46, 0, 0, 0, 0], + [0, 45, 2, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 58, 0, 30, 0, 41, 0, 30, 0, 14, 0, 14, 35, 0, 0, 0], + [0, 62, 29, 60, 17, 0, 54, 69, 0, 56, 19, 27, 0, 63, 28, 0], + [0, 65, 37, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 68, 18, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 8, 0], + [14, 0, 0, 0, 0, 7, 0, 16, 0, 0, 15, 0, 0, 14, 46, 0], + [39, 0, 0, 14, 2, 0, 0, 47, 0, 14, 0, 0, 0, 0, 0, 46], + [46, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [49, 0, 0, 0, 0, 0, 11, 0, 24, 20, 66, 0, 0, 0, 0, 0], + [72, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 73] = [ + 0, 999, 1023, 1026, 3072, 8191, 65408, 65472, 1048575, 1966080, 2097151, 3932160, 4063232, + 8388607, 67043328, 67044351, 134152192, 264241152, 268435455, 3758096384, 4294901504, + 17112694784, 64424509440, 549218942976, 4393751543808, 35184372023296, 140737488355327, + 272678883688448, 279275953455104, 280925220896768, 281200098803712, 281474976448512, + 492581209243648, 2251524935778304, 2251795518717952, 4503595332403200, 4503599627370368, + 8708132091985919, 9007190731849728, 17732923532771328, 71212894229889024, + 144114915328655360, 144115183780888576, 144115188075855871, 284007976623144960, + 284008251501051904, 287948901175001088, 287948901242044416, 287953294926544896, + 504407547722072192, 1152640029630136320, 1152921496016912384, 2305840810190438400, + 2305843009213693952, 3458764513820540928, 4611615649683210238, 6917529027641082367, + 8217943420044312576, 9151595642915651584, 9223372032559808512, 17870283321406128128, + 18158513697557839872, 18302628889911885824, 18374686483949813760, 18428729675200069632, + 18446181123756130304, 18446181123756131327, 18446739675663040512, 18446744069414584320, + 18446744073709355007, 18446744073709486080, 18446744073709535232, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod uppercase { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 6); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 12, 15, 0, 0, 11, 0, 0, 8, 5, 9, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 13, 0, 7, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 4, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 10, 0, 38, 46, 44, 2], + [0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 51, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 60, 62, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 54, 0, 0, 0, 0, 0, 43, 43, 40, 43, 56, 23, 34, 35], + [0, 0, 57, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 66, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 30], + [0, 11, 0, 12, 50, 37, 36, 45, 47, 6, 0, 0, 0, 49, 18, 53], + [15, 0, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [22, 52, 43, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [25, 39, 42, 41, 59, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [58, 65, 29, 17, 48, 63, 31, 20, 55, 61, 64, 32, 28, 21, 16, 4], + ]; + static BITSET: [u64; 67] = [ + 0, 8, 116, 1023, 1024, 8383, 21882, 65535, 1048575, 8388607, 89478485, 134217726, + 2139095039, 4294967295, 17179869183, 1099511627775, 2199023190016, 4398046445568, + 17575006099264, 23456248059221, 70368743129088, 140737484161024, 140737488355327, + 280378317225728, 281470681743392, 281474976710655, 1169903278445909, 2251799813685247, + 9007198986305536, 17977448100528131, 18014398509481983, 288230371856744511, + 576460735123554305, 576460743713488896, 1080863910568919040, 1080897995681042176, + 1274187559846268630, 3122495741643543722, 6148633210533183488, 6148914689804861440, + 6148914690880001365, 6148914691236506283, 6148914691236516865, 6148914691236517205, + 6151773421467674709, 6184099063146390672, 7638198793012598101, 7783721355972007253, + 8863084067199903664, 9242793810247811072, 12273810184460391765, 13839347594782259332, + 13845730589451223040, 16613872850358272000, 16717361816799215616, 17293822586282573568, + 18374966856193736448, 18428729675200069632, 18442240474149289983, 18446274948748367189, + 18446462598732840960, 18446462598737035263, 18446466996779287551, 18446726481523637343, + 18446742974197924863, 18446742974197940223, 18446744069414584320, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod white_space { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (12, 2); + static BITSET_CHUNKS_MAP: [u8; 9] = [ + 3, 0, 0, 0, 0, 1, 0, 0, 4, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 5] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 6] = [ + 0, 1, 2147483648, 4294967328, 4294983168, 144036023240703, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod conversions { + pub fn to_lower(c: char) -> [char; 3] { + match bsearch_case_table(c, LOWERCASE_TABLE) { + None => [c, '\0', '\0'], + Some(index) => LOWERCASE_TABLE[index].1, + } + } + + pub fn to_upper(c: char) -> [char; 3] { + match bsearch_case_table(c, UPPERCASE_TABLE) { + None => [c, '\0', '\0'], + Some(index) => UPPERCASE_TABLE[index].1, + } + } + + fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { + table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() + } + static LOWERCASE_TABLE: &[(char, [char; 3])] = &[ + ('A', ['a', '\u{0}', '\u{0}']), ('B', ['b', '\u{0}', '\u{0}']), + ('C', ['c', '\u{0}', '\u{0}']), ('D', ['d', '\u{0}', '\u{0}']), + ('E', ['e', '\u{0}', '\u{0}']), ('F', ['f', '\u{0}', '\u{0}']), + ('G', ['g', '\u{0}', '\u{0}']), ('H', ['h', '\u{0}', '\u{0}']), + ('I', ['i', '\u{0}', '\u{0}']), ('J', ['j', '\u{0}', '\u{0}']), + ('K', ['k', '\u{0}', '\u{0}']), ('L', ['l', '\u{0}', '\u{0}']), + ('M', ['m', '\u{0}', '\u{0}']), ('N', ['n', '\u{0}', '\u{0}']), + ('O', ['o', '\u{0}', '\u{0}']), ('P', ['p', '\u{0}', '\u{0}']), + ('Q', ['q', '\u{0}', '\u{0}']), ('R', ['r', '\u{0}', '\u{0}']), + ('S', ['s', '\u{0}', '\u{0}']), ('T', ['t', '\u{0}', '\u{0}']), + ('U', ['u', '\u{0}', '\u{0}']), ('V', ['v', '\u{0}', '\u{0}']), + ('W', ['w', '\u{0}', '\u{0}']), ('X', ['x', '\u{0}', '\u{0}']), + ('Y', ['y', '\u{0}', '\u{0}']), ('Z', ['z', '\u{0}', '\u{0}']), + ('\u{c0}', ['\u{e0}', '\u{0}', '\u{0}']), ('\u{c1}', ['\u{e1}', '\u{0}', '\u{0}']), + ('\u{c2}', ['\u{e2}', '\u{0}', '\u{0}']), ('\u{c3}', ['\u{e3}', '\u{0}', '\u{0}']), + ('\u{c4}', ['\u{e4}', '\u{0}', '\u{0}']), ('\u{c5}', ['\u{e5}', '\u{0}', '\u{0}']), + ('\u{c6}', ['\u{e6}', '\u{0}', '\u{0}']), ('\u{c7}', ['\u{e7}', '\u{0}', '\u{0}']), + ('\u{c8}', ['\u{e8}', '\u{0}', '\u{0}']), ('\u{c9}', ['\u{e9}', '\u{0}', '\u{0}']), + ('\u{ca}', ['\u{ea}', '\u{0}', '\u{0}']), ('\u{cb}', ['\u{eb}', '\u{0}', '\u{0}']), + ('\u{cc}', ['\u{ec}', '\u{0}', '\u{0}']), ('\u{cd}', ['\u{ed}', '\u{0}', '\u{0}']), + ('\u{ce}', ['\u{ee}', '\u{0}', '\u{0}']), ('\u{cf}', ['\u{ef}', '\u{0}', '\u{0}']), + ('\u{d0}', ['\u{f0}', '\u{0}', '\u{0}']), ('\u{d1}', ['\u{f1}', '\u{0}', '\u{0}']), + ('\u{d2}', ['\u{f2}', '\u{0}', '\u{0}']), ('\u{d3}', ['\u{f3}', '\u{0}', '\u{0}']), + ('\u{d4}', ['\u{f4}', '\u{0}', '\u{0}']), ('\u{d5}', ['\u{f5}', '\u{0}', '\u{0}']), + ('\u{d6}', ['\u{f6}', '\u{0}', '\u{0}']), ('\u{d8}', ['\u{f8}', '\u{0}', '\u{0}']), + ('\u{d9}', ['\u{f9}', '\u{0}', '\u{0}']), ('\u{da}', ['\u{fa}', '\u{0}', '\u{0}']), + ('\u{db}', ['\u{fb}', '\u{0}', '\u{0}']), ('\u{dc}', ['\u{fc}', '\u{0}', '\u{0}']), + ('\u{dd}', ['\u{fd}', '\u{0}', '\u{0}']), ('\u{de}', ['\u{fe}', '\u{0}', '\u{0}']), + ('\u{100}', ['\u{101}', '\u{0}', '\u{0}']), ('\u{102}', ['\u{103}', '\u{0}', '\u{0}']), + ('\u{104}', ['\u{105}', '\u{0}', '\u{0}']), ('\u{106}', ['\u{107}', '\u{0}', '\u{0}']), + ('\u{108}', ['\u{109}', '\u{0}', '\u{0}']), ('\u{10a}', ['\u{10b}', '\u{0}', '\u{0}']), + ('\u{10c}', ['\u{10d}', '\u{0}', '\u{0}']), ('\u{10e}', ['\u{10f}', '\u{0}', '\u{0}']), + ('\u{110}', ['\u{111}', '\u{0}', '\u{0}']), ('\u{112}', ['\u{113}', '\u{0}', '\u{0}']), + ('\u{114}', ['\u{115}', '\u{0}', '\u{0}']), ('\u{116}', ['\u{117}', '\u{0}', '\u{0}']), + ('\u{118}', ['\u{119}', '\u{0}', '\u{0}']), ('\u{11a}', ['\u{11b}', '\u{0}', '\u{0}']), + ('\u{11c}', ['\u{11d}', '\u{0}', '\u{0}']), ('\u{11e}', ['\u{11f}', '\u{0}', '\u{0}']), + ('\u{120}', ['\u{121}', '\u{0}', '\u{0}']), ('\u{122}', ['\u{123}', '\u{0}', '\u{0}']), + ('\u{124}', ['\u{125}', '\u{0}', '\u{0}']), ('\u{126}', ['\u{127}', '\u{0}', '\u{0}']), + ('\u{128}', ['\u{129}', '\u{0}', '\u{0}']), ('\u{12a}', ['\u{12b}', '\u{0}', '\u{0}']), + ('\u{12c}', ['\u{12d}', '\u{0}', '\u{0}']), ('\u{12e}', ['\u{12f}', '\u{0}', '\u{0}']), + ('\u{130}', ['i', '\u{307}', '\u{0}']), ('\u{132}', ['\u{133}', '\u{0}', '\u{0}']), + ('\u{134}', ['\u{135}', '\u{0}', '\u{0}']), ('\u{136}', ['\u{137}', '\u{0}', '\u{0}']), + ('\u{139}', ['\u{13a}', '\u{0}', '\u{0}']), ('\u{13b}', ['\u{13c}', '\u{0}', '\u{0}']), + ('\u{13d}', ['\u{13e}', '\u{0}', '\u{0}']), ('\u{13f}', ['\u{140}', '\u{0}', '\u{0}']), + ('\u{141}', ['\u{142}', '\u{0}', '\u{0}']), ('\u{143}', ['\u{144}', '\u{0}', '\u{0}']), + ('\u{145}', ['\u{146}', '\u{0}', '\u{0}']), ('\u{147}', ['\u{148}', '\u{0}', '\u{0}']), + ('\u{14a}', ['\u{14b}', '\u{0}', '\u{0}']), ('\u{14c}', ['\u{14d}', '\u{0}', '\u{0}']), + ('\u{14e}', ['\u{14f}', '\u{0}', '\u{0}']), ('\u{150}', ['\u{151}', '\u{0}', '\u{0}']), + ('\u{152}', ['\u{153}', '\u{0}', '\u{0}']), ('\u{154}', ['\u{155}', '\u{0}', '\u{0}']), + ('\u{156}', ['\u{157}', '\u{0}', '\u{0}']), ('\u{158}', ['\u{159}', '\u{0}', '\u{0}']), + ('\u{15a}', ['\u{15b}', '\u{0}', '\u{0}']), ('\u{15c}', ['\u{15d}', '\u{0}', '\u{0}']), + ('\u{15e}', ['\u{15f}', '\u{0}', '\u{0}']), ('\u{160}', ['\u{161}', '\u{0}', '\u{0}']), + ('\u{162}', ['\u{163}', '\u{0}', '\u{0}']), ('\u{164}', ['\u{165}', '\u{0}', '\u{0}']), + ('\u{166}', ['\u{167}', '\u{0}', '\u{0}']), ('\u{168}', ['\u{169}', '\u{0}', '\u{0}']), + ('\u{16a}', ['\u{16b}', '\u{0}', '\u{0}']), ('\u{16c}', ['\u{16d}', '\u{0}', '\u{0}']), + ('\u{16e}', ['\u{16f}', '\u{0}', '\u{0}']), ('\u{170}', ['\u{171}', '\u{0}', '\u{0}']), + ('\u{172}', ['\u{173}', '\u{0}', '\u{0}']), ('\u{174}', ['\u{175}', '\u{0}', '\u{0}']), + ('\u{176}', ['\u{177}', '\u{0}', '\u{0}']), ('\u{178}', ['\u{ff}', '\u{0}', '\u{0}']), + ('\u{179}', ['\u{17a}', '\u{0}', '\u{0}']), ('\u{17b}', ['\u{17c}', '\u{0}', '\u{0}']), + ('\u{17d}', ['\u{17e}', '\u{0}', '\u{0}']), ('\u{181}', ['\u{253}', '\u{0}', '\u{0}']), + ('\u{182}', ['\u{183}', '\u{0}', '\u{0}']), ('\u{184}', ['\u{185}', '\u{0}', '\u{0}']), + ('\u{186}', ['\u{254}', '\u{0}', '\u{0}']), ('\u{187}', ['\u{188}', '\u{0}', '\u{0}']), + ('\u{189}', ['\u{256}', '\u{0}', '\u{0}']), ('\u{18a}', ['\u{257}', '\u{0}', '\u{0}']), + ('\u{18b}', ['\u{18c}', '\u{0}', '\u{0}']), ('\u{18e}', ['\u{1dd}', '\u{0}', '\u{0}']), + ('\u{18f}', ['\u{259}', '\u{0}', '\u{0}']), ('\u{190}', ['\u{25b}', '\u{0}', '\u{0}']), + ('\u{191}', ['\u{192}', '\u{0}', '\u{0}']), ('\u{193}', ['\u{260}', '\u{0}', '\u{0}']), + ('\u{194}', ['\u{263}', '\u{0}', '\u{0}']), ('\u{196}', ['\u{269}', '\u{0}', '\u{0}']), + ('\u{197}', ['\u{268}', '\u{0}', '\u{0}']), ('\u{198}', ['\u{199}', '\u{0}', '\u{0}']), + ('\u{19c}', ['\u{26f}', '\u{0}', '\u{0}']), ('\u{19d}', ['\u{272}', '\u{0}', '\u{0}']), + ('\u{19f}', ['\u{275}', '\u{0}', '\u{0}']), ('\u{1a0}', ['\u{1a1}', '\u{0}', '\u{0}']), + ('\u{1a2}', ['\u{1a3}', '\u{0}', '\u{0}']), ('\u{1a4}', ['\u{1a5}', '\u{0}', '\u{0}']), + ('\u{1a6}', ['\u{280}', '\u{0}', '\u{0}']), ('\u{1a7}', ['\u{1a8}', '\u{0}', '\u{0}']), + ('\u{1a9}', ['\u{283}', '\u{0}', '\u{0}']), ('\u{1ac}', ['\u{1ad}', '\u{0}', '\u{0}']), + ('\u{1ae}', ['\u{288}', '\u{0}', '\u{0}']), ('\u{1af}', ['\u{1b0}', '\u{0}', '\u{0}']), + ('\u{1b1}', ['\u{28a}', '\u{0}', '\u{0}']), ('\u{1b2}', ['\u{28b}', '\u{0}', '\u{0}']), + ('\u{1b3}', ['\u{1b4}', '\u{0}', '\u{0}']), ('\u{1b5}', ['\u{1b6}', '\u{0}', '\u{0}']), + ('\u{1b7}', ['\u{292}', '\u{0}', '\u{0}']), ('\u{1b8}', ['\u{1b9}', '\u{0}', '\u{0}']), + ('\u{1bc}', ['\u{1bd}', '\u{0}', '\u{0}']), ('\u{1c4}', ['\u{1c6}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c6}', '\u{0}', '\u{0}']), ('\u{1c7}', ['\u{1c9}', '\u{0}', '\u{0}']), + ('\u{1c8}', ['\u{1c9}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cc}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1cc}', '\u{0}', '\u{0}']), ('\u{1cd}', ['\u{1ce}', '\u{0}', '\u{0}']), + ('\u{1cf}', ['\u{1d0}', '\u{0}', '\u{0}']), ('\u{1d1}', ['\u{1d2}', '\u{0}', '\u{0}']), + ('\u{1d3}', ['\u{1d4}', '\u{0}', '\u{0}']), ('\u{1d5}', ['\u{1d6}', '\u{0}', '\u{0}']), + ('\u{1d7}', ['\u{1d8}', '\u{0}', '\u{0}']), ('\u{1d9}', ['\u{1da}', '\u{0}', '\u{0}']), + ('\u{1db}', ['\u{1dc}', '\u{0}', '\u{0}']), ('\u{1de}', ['\u{1df}', '\u{0}', '\u{0}']), + ('\u{1e0}', ['\u{1e1}', '\u{0}', '\u{0}']), ('\u{1e2}', ['\u{1e3}', '\u{0}', '\u{0}']), + ('\u{1e4}', ['\u{1e5}', '\u{0}', '\u{0}']), ('\u{1e6}', ['\u{1e7}', '\u{0}', '\u{0}']), + ('\u{1e8}', ['\u{1e9}', '\u{0}', '\u{0}']), ('\u{1ea}', ['\u{1eb}', '\u{0}', '\u{0}']), + ('\u{1ec}', ['\u{1ed}', '\u{0}', '\u{0}']), ('\u{1ee}', ['\u{1ef}', '\u{0}', '\u{0}']), + ('\u{1f1}', ['\u{1f3}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f3}', '\u{0}', '\u{0}']), + ('\u{1f4}', ['\u{1f5}', '\u{0}', '\u{0}']), ('\u{1f6}', ['\u{195}', '\u{0}', '\u{0}']), + ('\u{1f7}', ['\u{1bf}', '\u{0}', '\u{0}']), ('\u{1f8}', ['\u{1f9}', '\u{0}', '\u{0}']), + ('\u{1fa}', ['\u{1fb}', '\u{0}', '\u{0}']), ('\u{1fc}', ['\u{1fd}', '\u{0}', '\u{0}']), + ('\u{1fe}', ['\u{1ff}', '\u{0}', '\u{0}']), ('\u{200}', ['\u{201}', '\u{0}', '\u{0}']), + ('\u{202}', ['\u{203}', '\u{0}', '\u{0}']), ('\u{204}', ['\u{205}', '\u{0}', '\u{0}']), + ('\u{206}', ['\u{207}', '\u{0}', '\u{0}']), ('\u{208}', ['\u{209}', '\u{0}', '\u{0}']), + ('\u{20a}', ['\u{20b}', '\u{0}', '\u{0}']), ('\u{20c}', ['\u{20d}', '\u{0}', '\u{0}']), + ('\u{20e}', ['\u{20f}', '\u{0}', '\u{0}']), ('\u{210}', ['\u{211}', '\u{0}', '\u{0}']), + ('\u{212}', ['\u{213}', '\u{0}', '\u{0}']), ('\u{214}', ['\u{215}', '\u{0}', '\u{0}']), + ('\u{216}', ['\u{217}', '\u{0}', '\u{0}']), ('\u{218}', ['\u{219}', '\u{0}', '\u{0}']), + ('\u{21a}', ['\u{21b}', '\u{0}', '\u{0}']), ('\u{21c}', ['\u{21d}', '\u{0}', '\u{0}']), + ('\u{21e}', ['\u{21f}', '\u{0}', '\u{0}']), ('\u{220}', ['\u{19e}', '\u{0}', '\u{0}']), + ('\u{222}', ['\u{223}', '\u{0}', '\u{0}']), ('\u{224}', ['\u{225}', '\u{0}', '\u{0}']), + ('\u{226}', ['\u{227}', '\u{0}', '\u{0}']), ('\u{228}', ['\u{229}', '\u{0}', '\u{0}']), + ('\u{22a}', ['\u{22b}', '\u{0}', '\u{0}']), ('\u{22c}', ['\u{22d}', '\u{0}', '\u{0}']), + ('\u{22e}', ['\u{22f}', '\u{0}', '\u{0}']), ('\u{230}', ['\u{231}', '\u{0}', '\u{0}']), + ('\u{232}', ['\u{233}', '\u{0}', '\u{0}']), ('\u{23a}', ['\u{2c65}', '\u{0}', '\u{0}']), + ('\u{23b}', ['\u{23c}', '\u{0}', '\u{0}']), ('\u{23d}', ['\u{19a}', '\u{0}', '\u{0}']), + ('\u{23e}', ['\u{2c66}', '\u{0}', '\u{0}']), ('\u{241}', ['\u{242}', '\u{0}', '\u{0}']), + ('\u{243}', ['\u{180}', '\u{0}', '\u{0}']), ('\u{244}', ['\u{289}', '\u{0}', '\u{0}']), + ('\u{245}', ['\u{28c}', '\u{0}', '\u{0}']), ('\u{246}', ['\u{247}', '\u{0}', '\u{0}']), + ('\u{248}', ['\u{249}', '\u{0}', '\u{0}']), ('\u{24a}', ['\u{24b}', '\u{0}', '\u{0}']), + ('\u{24c}', ['\u{24d}', '\u{0}', '\u{0}']), ('\u{24e}', ['\u{24f}', '\u{0}', '\u{0}']), + ('\u{370}', ['\u{371}', '\u{0}', '\u{0}']), ('\u{372}', ['\u{373}', '\u{0}', '\u{0}']), + ('\u{376}', ['\u{377}', '\u{0}', '\u{0}']), ('\u{37f}', ['\u{3f3}', '\u{0}', '\u{0}']), + ('\u{386}', ['\u{3ac}', '\u{0}', '\u{0}']), ('\u{388}', ['\u{3ad}', '\u{0}', '\u{0}']), + ('\u{389}', ['\u{3ae}', '\u{0}', '\u{0}']), ('\u{38a}', ['\u{3af}', '\u{0}', '\u{0}']), + ('\u{38c}', ['\u{3cc}', '\u{0}', '\u{0}']), ('\u{38e}', ['\u{3cd}', '\u{0}', '\u{0}']), + ('\u{38f}', ['\u{3ce}', '\u{0}', '\u{0}']), ('\u{391}', ['\u{3b1}', '\u{0}', '\u{0}']), + ('\u{392}', ['\u{3b2}', '\u{0}', '\u{0}']), ('\u{393}', ['\u{3b3}', '\u{0}', '\u{0}']), + ('\u{394}', ['\u{3b4}', '\u{0}', '\u{0}']), ('\u{395}', ['\u{3b5}', '\u{0}', '\u{0}']), + ('\u{396}', ['\u{3b6}', '\u{0}', '\u{0}']), ('\u{397}', ['\u{3b7}', '\u{0}', '\u{0}']), + ('\u{398}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{399}', ['\u{3b9}', '\u{0}', '\u{0}']), + ('\u{39a}', ['\u{3ba}', '\u{0}', '\u{0}']), ('\u{39b}', ['\u{3bb}', '\u{0}', '\u{0}']), + ('\u{39c}', ['\u{3bc}', '\u{0}', '\u{0}']), ('\u{39d}', ['\u{3bd}', '\u{0}', '\u{0}']), + ('\u{39e}', ['\u{3be}', '\u{0}', '\u{0}']), ('\u{39f}', ['\u{3bf}', '\u{0}', '\u{0}']), + ('\u{3a0}', ['\u{3c0}', '\u{0}', '\u{0}']), ('\u{3a1}', ['\u{3c1}', '\u{0}', '\u{0}']), + ('\u{3a3}', ['\u{3c3}', '\u{0}', '\u{0}']), ('\u{3a4}', ['\u{3c4}', '\u{0}', '\u{0}']), + ('\u{3a5}', ['\u{3c5}', '\u{0}', '\u{0}']), ('\u{3a6}', ['\u{3c6}', '\u{0}', '\u{0}']), + ('\u{3a7}', ['\u{3c7}', '\u{0}', '\u{0}']), ('\u{3a8}', ['\u{3c8}', '\u{0}', '\u{0}']), + ('\u{3a9}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{3aa}', ['\u{3ca}', '\u{0}', '\u{0}']), + ('\u{3ab}', ['\u{3cb}', '\u{0}', '\u{0}']), ('\u{3cf}', ['\u{3d7}', '\u{0}', '\u{0}']), + ('\u{3d8}', ['\u{3d9}', '\u{0}', '\u{0}']), ('\u{3da}', ['\u{3db}', '\u{0}', '\u{0}']), + ('\u{3dc}', ['\u{3dd}', '\u{0}', '\u{0}']), ('\u{3de}', ['\u{3df}', '\u{0}', '\u{0}']), + ('\u{3e0}', ['\u{3e1}', '\u{0}', '\u{0}']), ('\u{3e2}', ['\u{3e3}', '\u{0}', '\u{0}']), + ('\u{3e4}', ['\u{3e5}', '\u{0}', '\u{0}']), ('\u{3e6}', ['\u{3e7}', '\u{0}', '\u{0}']), + ('\u{3e8}', ['\u{3e9}', '\u{0}', '\u{0}']), ('\u{3ea}', ['\u{3eb}', '\u{0}', '\u{0}']), + ('\u{3ec}', ['\u{3ed}', '\u{0}', '\u{0}']), ('\u{3ee}', ['\u{3ef}', '\u{0}', '\u{0}']), + ('\u{3f4}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{3f7}', ['\u{3f8}', '\u{0}', '\u{0}']), + ('\u{3f9}', ['\u{3f2}', '\u{0}', '\u{0}']), ('\u{3fa}', ['\u{3fb}', '\u{0}', '\u{0}']), + ('\u{3fd}', ['\u{37b}', '\u{0}', '\u{0}']), ('\u{3fe}', ['\u{37c}', '\u{0}', '\u{0}']), + ('\u{3ff}', ['\u{37d}', '\u{0}', '\u{0}']), ('\u{400}', ['\u{450}', '\u{0}', '\u{0}']), + ('\u{401}', ['\u{451}', '\u{0}', '\u{0}']), ('\u{402}', ['\u{452}', '\u{0}', '\u{0}']), + ('\u{403}', ['\u{453}', '\u{0}', '\u{0}']), ('\u{404}', ['\u{454}', '\u{0}', '\u{0}']), + ('\u{405}', ['\u{455}', '\u{0}', '\u{0}']), ('\u{406}', ['\u{456}', '\u{0}', '\u{0}']), + ('\u{407}', ['\u{457}', '\u{0}', '\u{0}']), ('\u{408}', ['\u{458}', '\u{0}', '\u{0}']), + ('\u{409}', ['\u{459}', '\u{0}', '\u{0}']), ('\u{40a}', ['\u{45a}', '\u{0}', '\u{0}']), + ('\u{40b}', ['\u{45b}', '\u{0}', '\u{0}']), ('\u{40c}', ['\u{45c}', '\u{0}', '\u{0}']), + ('\u{40d}', ['\u{45d}', '\u{0}', '\u{0}']), ('\u{40e}', ['\u{45e}', '\u{0}', '\u{0}']), + ('\u{40f}', ['\u{45f}', '\u{0}', '\u{0}']), ('\u{410}', ['\u{430}', '\u{0}', '\u{0}']), + ('\u{411}', ['\u{431}', '\u{0}', '\u{0}']), ('\u{412}', ['\u{432}', '\u{0}', '\u{0}']), + ('\u{413}', ['\u{433}', '\u{0}', '\u{0}']), ('\u{414}', ['\u{434}', '\u{0}', '\u{0}']), + ('\u{415}', ['\u{435}', '\u{0}', '\u{0}']), ('\u{416}', ['\u{436}', '\u{0}', '\u{0}']), + ('\u{417}', ['\u{437}', '\u{0}', '\u{0}']), ('\u{418}', ['\u{438}', '\u{0}', '\u{0}']), + ('\u{419}', ['\u{439}', '\u{0}', '\u{0}']), ('\u{41a}', ['\u{43a}', '\u{0}', '\u{0}']), + ('\u{41b}', ['\u{43b}', '\u{0}', '\u{0}']), ('\u{41c}', ['\u{43c}', '\u{0}', '\u{0}']), + ('\u{41d}', ['\u{43d}', '\u{0}', '\u{0}']), ('\u{41e}', ['\u{43e}', '\u{0}', '\u{0}']), + ('\u{41f}', ['\u{43f}', '\u{0}', '\u{0}']), ('\u{420}', ['\u{440}', '\u{0}', '\u{0}']), + ('\u{421}', ['\u{441}', '\u{0}', '\u{0}']), ('\u{422}', ['\u{442}', '\u{0}', '\u{0}']), + ('\u{423}', ['\u{443}', '\u{0}', '\u{0}']), ('\u{424}', ['\u{444}', '\u{0}', '\u{0}']), + ('\u{425}', ['\u{445}', '\u{0}', '\u{0}']), ('\u{426}', ['\u{446}', '\u{0}', '\u{0}']), + ('\u{427}', ['\u{447}', '\u{0}', '\u{0}']), ('\u{428}', ['\u{448}', '\u{0}', '\u{0}']), + ('\u{429}', ['\u{449}', '\u{0}', '\u{0}']), ('\u{42a}', ['\u{44a}', '\u{0}', '\u{0}']), + ('\u{42b}', ['\u{44b}', '\u{0}', '\u{0}']), ('\u{42c}', ['\u{44c}', '\u{0}', '\u{0}']), + ('\u{42d}', ['\u{44d}', '\u{0}', '\u{0}']), ('\u{42e}', ['\u{44e}', '\u{0}', '\u{0}']), + ('\u{42f}', ['\u{44f}', '\u{0}', '\u{0}']), ('\u{460}', ['\u{461}', '\u{0}', '\u{0}']), + ('\u{462}', ['\u{463}', '\u{0}', '\u{0}']), ('\u{464}', ['\u{465}', '\u{0}', '\u{0}']), + ('\u{466}', ['\u{467}', '\u{0}', '\u{0}']), ('\u{468}', ['\u{469}', '\u{0}', '\u{0}']), + ('\u{46a}', ['\u{46b}', '\u{0}', '\u{0}']), ('\u{46c}', ['\u{46d}', '\u{0}', '\u{0}']), + ('\u{46e}', ['\u{46f}', '\u{0}', '\u{0}']), ('\u{470}', ['\u{471}', '\u{0}', '\u{0}']), + ('\u{472}', ['\u{473}', '\u{0}', '\u{0}']), ('\u{474}', ['\u{475}', '\u{0}', '\u{0}']), + ('\u{476}', ['\u{477}', '\u{0}', '\u{0}']), ('\u{478}', ['\u{479}', '\u{0}', '\u{0}']), + ('\u{47a}', ['\u{47b}', '\u{0}', '\u{0}']), ('\u{47c}', ['\u{47d}', '\u{0}', '\u{0}']), + ('\u{47e}', ['\u{47f}', '\u{0}', '\u{0}']), ('\u{480}', ['\u{481}', '\u{0}', '\u{0}']), + ('\u{48a}', ['\u{48b}', '\u{0}', '\u{0}']), ('\u{48c}', ['\u{48d}', '\u{0}', '\u{0}']), + ('\u{48e}', ['\u{48f}', '\u{0}', '\u{0}']), ('\u{490}', ['\u{491}', '\u{0}', '\u{0}']), + ('\u{492}', ['\u{493}', '\u{0}', '\u{0}']), ('\u{494}', ['\u{495}', '\u{0}', '\u{0}']), + ('\u{496}', ['\u{497}', '\u{0}', '\u{0}']), ('\u{498}', ['\u{499}', '\u{0}', '\u{0}']), + ('\u{49a}', ['\u{49b}', '\u{0}', '\u{0}']), ('\u{49c}', ['\u{49d}', '\u{0}', '\u{0}']), + ('\u{49e}', ['\u{49f}', '\u{0}', '\u{0}']), ('\u{4a0}', ['\u{4a1}', '\u{0}', '\u{0}']), + ('\u{4a2}', ['\u{4a3}', '\u{0}', '\u{0}']), ('\u{4a4}', ['\u{4a5}', '\u{0}', '\u{0}']), + ('\u{4a6}', ['\u{4a7}', '\u{0}', '\u{0}']), ('\u{4a8}', ['\u{4a9}', '\u{0}', '\u{0}']), + ('\u{4aa}', ['\u{4ab}', '\u{0}', '\u{0}']), ('\u{4ac}', ['\u{4ad}', '\u{0}', '\u{0}']), + ('\u{4ae}', ['\u{4af}', '\u{0}', '\u{0}']), ('\u{4b0}', ['\u{4b1}', '\u{0}', '\u{0}']), + ('\u{4b2}', ['\u{4b3}', '\u{0}', '\u{0}']), ('\u{4b4}', ['\u{4b5}', '\u{0}', '\u{0}']), + ('\u{4b6}', ['\u{4b7}', '\u{0}', '\u{0}']), ('\u{4b8}', ['\u{4b9}', '\u{0}', '\u{0}']), + ('\u{4ba}', ['\u{4bb}', '\u{0}', '\u{0}']), ('\u{4bc}', ['\u{4bd}', '\u{0}', '\u{0}']), + ('\u{4be}', ['\u{4bf}', '\u{0}', '\u{0}']), ('\u{4c0}', ['\u{4cf}', '\u{0}', '\u{0}']), + ('\u{4c1}', ['\u{4c2}', '\u{0}', '\u{0}']), ('\u{4c3}', ['\u{4c4}', '\u{0}', '\u{0}']), + ('\u{4c5}', ['\u{4c6}', '\u{0}', '\u{0}']), ('\u{4c7}', ['\u{4c8}', '\u{0}', '\u{0}']), + ('\u{4c9}', ['\u{4ca}', '\u{0}', '\u{0}']), ('\u{4cb}', ['\u{4cc}', '\u{0}', '\u{0}']), + ('\u{4cd}', ['\u{4ce}', '\u{0}', '\u{0}']), ('\u{4d0}', ['\u{4d1}', '\u{0}', '\u{0}']), + ('\u{4d2}', ['\u{4d3}', '\u{0}', '\u{0}']), ('\u{4d4}', ['\u{4d5}', '\u{0}', '\u{0}']), + ('\u{4d6}', ['\u{4d7}', '\u{0}', '\u{0}']), ('\u{4d8}', ['\u{4d9}', '\u{0}', '\u{0}']), + ('\u{4da}', ['\u{4db}', '\u{0}', '\u{0}']), ('\u{4dc}', ['\u{4dd}', '\u{0}', '\u{0}']), + ('\u{4de}', ['\u{4df}', '\u{0}', '\u{0}']), ('\u{4e0}', ['\u{4e1}', '\u{0}', '\u{0}']), + ('\u{4e2}', ['\u{4e3}', '\u{0}', '\u{0}']), ('\u{4e4}', ['\u{4e5}', '\u{0}', '\u{0}']), + ('\u{4e6}', ['\u{4e7}', '\u{0}', '\u{0}']), ('\u{4e8}', ['\u{4e9}', '\u{0}', '\u{0}']), + ('\u{4ea}', ['\u{4eb}', '\u{0}', '\u{0}']), ('\u{4ec}', ['\u{4ed}', '\u{0}', '\u{0}']), + ('\u{4ee}', ['\u{4ef}', '\u{0}', '\u{0}']), ('\u{4f0}', ['\u{4f1}', '\u{0}', '\u{0}']), + ('\u{4f2}', ['\u{4f3}', '\u{0}', '\u{0}']), ('\u{4f4}', ['\u{4f5}', '\u{0}', '\u{0}']), + ('\u{4f6}', ['\u{4f7}', '\u{0}', '\u{0}']), ('\u{4f8}', ['\u{4f9}', '\u{0}', '\u{0}']), + ('\u{4fa}', ['\u{4fb}', '\u{0}', '\u{0}']), ('\u{4fc}', ['\u{4fd}', '\u{0}', '\u{0}']), + ('\u{4fe}', ['\u{4ff}', '\u{0}', '\u{0}']), ('\u{500}', ['\u{501}', '\u{0}', '\u{0}']), + ('\u{502}', ['\u{503}', '\u{0}', '\u{0}']), ('\u{504}', ['\u{505}', '\u{0}', '\u{0}']), + ('\u{506}', ['\u{507}', '\u{0}', '\u{0}']), ('\u{508}', ['\u{509}', '\u{0}', '\u{0}']), + ('\u{50a}', ['\u{50b}', '\u{0}', '\u{0}']), ('\u{50c}', ['\u{50d}', '\u{0}', '\u{0}']), + ('\u{50e}', ['\u{50f}', '\u{0}', '\u{0}']), ('\u{510}', ['\u{511}', '\u{0}', '\u{0}']), + ('\u{512}', ['\u{513}', '\u{0}', '\u{0}']), ('\u{514}', ['\u{515}', '\u{0}', '\u{0}']), + ('\u{516}', ['\u{517}', '\u{0}', '\u{0}']), ('\u{518}', ['\u{519}', '\u{0}', '\u{0}']), + ('\u{51a}', ['\u{51b}', '\u{0}', '\u{0}']), ('\u{51c}', ['\u{51d}', '\u{0}', '\u{0}']), + ('\u{51e}', ['\u{51f}', '\u{0}', '\u{0}']), ('\u{520}', ['\u{521}', '\u{0}', '\u{0}']), + ('\u{522}', ['\u{523}', '\u{0}', '\u{0}']), ('\u{524}', ['\u{525}', '\u{0}', '\u{0}']), + ('\u{526}', ['\u{527}', '\u{0}', '\u{0}']), ('\u{528}', ['\u{529}', '\u{0}', '\u{0}']), + ('\u{52a}', ['\u{52b}', '\u{0}', '\u{0}']), ('\u{52c}', ['\u{52d}', '\u{0}', '\u{0}']), + ('\u{52e}', ['\u{52f}', '\u{0}', '\u{0}']), ('\u{531}', ['\u{561}', '\u{0}', '\u{0}']), + ('\u{532}', ['\u{562}', '\u{0}', '\u{0}']), ('\u{533}', ['\u{563}', '\u{0}', '\u{0}']), + ('\u{534}', ['\u{564}', '\u{0}', '\u{0}']), ('\u{535}', ['\u{565}', '\u{0}', '\u{0}']), + ('\u{536}', ['\u{566}', '\u{0}', '\u{0}']), ('\u{537}', ['\u{567}', '\u{0}', '\u{0}']), + ('\u{538}', ['\u{568}', '\u{0}', '\u{0}']), ('\u{539}', ['\u{569}', '\u{0}', '\u{0}']), + ('\u{53a}', ['\u{56a}', '\u{0}', '\u{0}']), ('\u{53b}', ['\u{56b}', '\u{0}', '\u{0}']), + ('\u{53c}', ['\u{56c}', '\u{0}', '\u{0}']), ('\u{53d}', ['\u{56d}', '\u{0}', '\u{0}']), + ('\u{53e}', ['\u{56e}', '\u{0}', '\u{0}']), ('\u{53f}', ['\u{56f}', '\u{0}', '\u{0}']), + ('\u{540}', ['\u{570}', '\u{0}', '\u{0}']), ('\u{541}', ['\u{571}', '\u{0}', '\u{0}']), + ('\u{542}', ['\u{572}', '\u{0}', '\u{0}']), ('\u{543}', ['\u{573}', '\u{0}', '\u{0}']), + ('\u{544}', ['\u{574}', '\u{0}', '\u{0}']), ('\u{545}', ['\u{575}', '\u{0}', '\u{0}']), + ('\u{546}', ['\u{576}', '\u{0}', '\u{0}']), ('\u{547}', ['\u{577}', '\u{0}', '\u{0}']), + ('\u{548}', ['\u{578}', '\u{0}', '\u{0}']), ('\u{549}', ['\u{579}', '\u{0}', '\u{0}']), + ('\u{54a}', ['\u{57a}', '\u{0}', '\u{0}']), ('\u{54b}', ['\u{57b}', '\u{0}', '\u{0}']), + ('\u{54c}', ['\u{57c}', '\u{0}', '\u{0}']), ('\u{54d}', ['\u{57d}', '\u{0}', '\u{0}']), + ('\u{54e}', ['\u{57e}', '\u{0}', '\u{0}']), ('\u{54f}', ['\u{57f}', '\u{0}', '\u{0}']), + ('\u{550}', ['\u{580}', '\u{0}', '\u{0}']), ('\u{551}', ['\u{581}', '\u{0}', '\u{0}']), + ('\u{552}', ['\u{582}', '\u{0}', '\u{0}']), ('\u{553}', ['\u{583}', '\u{0}', '\u{0}']), + ('\u{554}', ['\u{584}', '\u{0}', '\u{0}']), ('\u{555}', ['\u{585}', '\u{0}', '\u{0}']), + ('\u{556}', ['\u{586}', '\u{0}', '\u{0}']), ('\u{10a0}', ['\u{2d00}', '\u{0}', '\u{0}']), + ('\u{10a1}', ['\u{2d01}', '\u{0}', '\u{0}']), ('\u{10a2}', ['\u{2d02}', '\u{0}', '\u{0}']), + ('\u{10a3}', ['\u{2d03}', '\u{0}', '\u{0}']), ('\u{10a4}', ['\u{2d04}', '\u{0}', '\u{0}']), + ('\u{10a5}', ['\u{2d05}', '\u{0}', '\u{0}']), ('\u{10a6}', ['\u{2d06}', '\u{0}', '\u{0}']), + ('\u{10a7}', ['\u{2d07}', '\u{0}', '\u{0}']), ('\u{10a8}', ['\u{2d08}', '\u{0}', '\u{0}']), + ('\u{10a9}', ['\u{2d09}', '\u{0}', '\u{0}']), ('\u{10aa}', ['\u{2d0a}', '\u{0}', '\u{0}']), + ('\u{10ab}', ['\u{2d0b}', '\u{0}', '\u{0}']), ('\u{10ac}', ['\u{2d0c}', '\u{0}', '\u{0}']), + ('\u{10ad}', ['\u{2d0d}', '\u{0}', '\u{0}']), ('\u{10ae}', ['\u{2d0e}', '\u{0}', '\u{0}']), + ('\u{10af}', ['\u{2d0f}', '\u{0}', '\u{0}']), ('\u{10b0}', ['\u{2d10}', '\u{0}', '\u{0}']), + ('\u{10b1}', ['\u{2d11}', '\u{0}', '\u{0}']), ('\u{10b2}', ['\u{2d12}', '\u{0}', '\u{0}']), + ('\u{10b3}', ['\u{2d13}', '\u{0}', '\u{0}']), ('\u{10b4}', ['\u{2d14}', '\u{0}', '\u{0}']), + ('\u{10b5}', ['\u{2d15}', '\u{0}', '\u{0}']), ('\u{10b6}', ['\u{2d16}', '\u{0}', '\u{0}']), + ('\u{10b7}', ['\u{2d17}', '\u{0}', '\u{0}']), ('\u{10b8}', ['\u{2d18}', '\u{0}', '\u{0}']), + ('\u{10b9}', ['\u{2d19}', '\u{0}', '\u{0}']), ('\u{10ba}', ['\u{2d1a}', '\u{0}', '\u{0}']), + ('\u{10bb}', ['\u{2d1b}', '\u{0}', '\u{0}']), ('\u{10bc}', ['\u{2d1c}', '\u{0}', '\u{0}']), + ('\u{10bd}', ['\u{2d1d}', '\u{0}', '\u{0}']), ('\u{10be}', ['\u{2d1e}', '\u{0}', '\u{0}']), + ('\u{10bf}', ['\u{2d1f}', '\u{0}', '\u{0}']), ('\u{10c0}', ['\u{2d20}', '\u{0}', '\u{0}']), + ('\u{10c1}', ['\u{2d21}', '\u{0}', '\u{0}']), ('\u{10c2}', ['\u{2d22}', '\u{0}', '\u{0}']), + ('\u{10c3}', ['\u{2d23}', '\u{0}', '\u{0}']), ('\u{10c4}', ['\u{2d24}', '\u{0}', '\u{0}']), + ('\u{10c5}', ['\u{2d25}', '\u{0}', '\u{0}']), ('\u{10c7}', ['\u{2d27}', '\u{0}', '\u{0}']), + ('\u{10cd}', ['\u{2d2d}', '\u{0}', '\u{0}']), ('\u{13a0}', ['\u{ab70}', '\u{0}', '\u{0}']), + ('\u{13a1}', ['\u{ab71}', '\u{0}', '\u{0}']), ('\u{13a2}', ['\u{ab72}', '\u{0}', '\u{0}']), + ('\u{13a3}', ['\u{ab73}', '\u{0}', '\u{0}']), ('\u{13a4}', ['\u{ab74}', '\u{0}', '\u{0}']), + ('\u{13a5}', ['\u{ab75}', '\u{0}', '\u{0}']), ('\u{13a6}', ['\u{ab76}', '\u{0}', '\u{0}']), + ('\u{13a7}', ['\u{ab77}', '\u{0}', '\u{0}']), ('\u{13a8}', ['\u{ab78}', '\u{0}', '\u{0}']), + ('\u{13a9}', ['\u{ab79}', '\u{0}', '\u{0}']), ('\u{13aa}', ['\u{ab7a}', '\u{0}', '\u{0}']), + ('\u{13ab}', ['\u{ab7b}', '\u{0}', '\u{0}']), ('\u{13ac}', ['\u{ab7c}', '\u{0}', '\u{0}']), + ('\u{13ad}', ['\u{ab7d}', '\u{0}', '\u{0}']), ('\u{13ae}', ['\u{ab7e}', '\u{0}', '\u{0}']), + ('\u{13af}', ['\u{ab7f}', '\u{0}', '\u{0}']), ('\u{13b0}', ['\u{ab80}', '\u{0}', '\u{0}']), + ('\u{13b1}', ['\u{ab81}', '\u{0}', '\u{0}']), ('\u{13b2}', ['\u{ab82}', '\u{0}', '\u{0}']), + ('\u{13b3}', ['\u{ab83}', '\u{0}', '\u{0}']), ('\u{13b4}', ['\u{ab84}', '\u{0}', '\u{0}']), + ('\u{13b5}', ['\u{ab85}', '\u{0}', '\u{0}']), ('\u{13b6}', ['\u{ab86}', '\u{0}', '\u{0}']), + ('\u{13b7}', ['\u{ab87}', '\u{0}', '\u{0}']), ('\u{13b8}', ['\u{ab88}', '\u{0}', '\u{0}']), + ('\u{13b9}', ['\u{ab89}', '\u{0}', '\u{0}']), ('\u{13ba}', ['\u{ab8a}', '\u{0}', '\u{0}']), + ('\u{13bb}', ['\u{ab8b}', '\u{0}', '\u{0}']), ('\u{13bc}', ['\u{ab8c}', '\u{0}', '\u{0}']), + ('\u{13bd}', ['\u{ab8d}', '\u{0}', '\u{0}']), ('\u{13be}', ['\u{ab8e}', '\u{0}', '\u{0}']), + ('\u{13bf}', ['\u{ab8f}', '\u{0}', '\u{0}']), ('\u{13c0}', ['\u{ab90}', '\u{0}', '\u{0}']), + ('\u{13c1}', ['\u{ab91}', '\u{0}', '\u{0}']), ('\u{13c2}', ['\u{ab92}', '\u{0}', '\u{0}']), + ('\u{13c3}', ['\u{ab93}', '\u{0}', '\u{0}']), ('\u{13c4}', ['\u{ab94}', '\u{0}', '\u{0}']), + ('\u{13c5}', ['\u{ab95}', '\u{0}', '\u{0}']), ('\u{13c6}', ['\u{ab96}', '\u{0}', '\u{0}']), + ('\u{13c7}', ['\u{ab97}', '\u{0}', '\u{0}']), ('\u{13c8}', ['\u{ab98}', '\u{0}', '\u{0}']), + ('\u{13c9}', ['\u{ab99}', '\u{0}', '\u{0}']), ('\u{13ca}', ['\u{ab9a}', '\u{0}', '\u{0}']), + ('\u{13cb}', ['\u{ab9b}', '\u{0}', '\u{0}']), ('\u{13cc}', ['\u{ab9c}', '\u{0}', '\u{0}']), + ('\u{13cd}', ['\u{ab9d}', '\u{0}', '\u{0}']), ('\u{13ce}', ['\u{ab9e}', '\u{0}', '\u{0}']), + ('\u{13cf}', ['\u{ab9f}', '\u{0}', '\u{0}']), ('\u{13d0}', ['\u{aba0}', '\u{0}', '\u{0}']), + ('\u{13d1}', ['\u{aba1}', '\u{0}', '\u{0}']), ('\u{13d2}', ['\u{aba2}', '\u{0}', '\u{0}']), + ('\u{13d3}', ['\u{aba3}', '\u{0}', '\u{0}']), ('\u{13d4}', ['\u{aba4}', '\u{0}', '\u{0}']), + ('\u{13d5}', ['\u{aba5}', '\u{0}', '\u{0}']), ('\u{13d6}', ['\u{aba6}', '\u{0}', '\u{0}']), + ('\u{13d7}', ['\u{aba7}', '\u{0}', '\u{0}']), ('\u{13d8}', ['\u{aba8}', '\u{0}', '\u{0}']), + ('\u{13d9}', ['\u{aba9}', '\u{0}', '\u{0}']), ('\u{13da}', ['\u{abaa}', '\u{0}', '\u{0}']), + ('\u{13db}', ['\u{abab}', '\u{0}', '\u{0}']), ('\u{13dc}', ['\u{abac}', '\u{0}', '\u{0}']), + ('\u{13dd}', ['\u{abad}', '\u{0}', '\u{0}']), ('\u{13de}', ['\u{abae}', '\u{0}', '\u{0}']), + ('\u{13df}', ['\u{abaf}', '\u{0}', '\u{0}']), ('\u{13e0}', ['\u{abb0}', '\u{0}', '\u{0}']), + ('\u{13e1}', ['\u{abb1}', '\u{0}', '\u{0}']), ('\u{13e2}', ['\u{abb2}', '\u{0}', '\u{0}']), + ('\u{13e3}', ['\u{abb3}', '\u{0}', '\u{0}']), ('\u{13e4}', ['\u{abb4}', '\u{0}', '\u{0}']), + ('\u{13e5}', ['\u{abb5}', '\u{0}', '\u{0}']), ('\u{13e6}', ['\u{abb6}', '\u{0}', '\u{0}']), + ('\u{13e7}', ['\u{abb7}', '\u{0}', '\u{0}']), ('\u{13e8}', ['\u{abb8}', '\u{0}', '\u{0}']), + ('\u{13e9}', ['\u{abb9}', '\u{0}', '\u{0}']), ('\u{13ea}', ['\u{abba}', '\u{0}', '\u{0}']), + ('\u{13eb}', ['\u{abbb}', '\u{0}', '\u{0}']), ('\u{13ec}', ['\u{abbc}', '\u{0}', '\u{0}']), + ('\u{13ed}', ['\u{abbd}', '\u{0}', '\u{0}']), ('\u{13ee}', ['\u{abbe}', '\u{0}', '\u{0}']), + ('\u{13ef}', ['\u{abbf}', '\u{0}', '\u{0}']), ('\u{13f0}', ['\u{13f8}', '\u{0}', '\u{0}']), + ('\u{13f1}', ['\u{13f9}', '\u{0}', '\u{0}']), ('\u{13f2}', ['\u{13fa}', '\u{0}', '\u{0}']), + ('\u{13f3}', ['\u{13fb}', '\u{0}', '\u{0}']), ('\u{13f4}', ['\u{13fc}', '\u{0}', '\u{0}']), + ('\u{13f5}', ['\u{13fd}', '\u{0}', '\u{0}']), ('\u{1c90}', ['\u{10d0}', '\u{0}', '\u{0}']), + ('\u{1c91}', ['\u{10d1}', '\u{0}', '\u{0}']), ('\u{1c92}', ['\u{10d2}', '\u{0}', '\u{0}']), + ('\u{1c93}', ['\u{10d3}', '\u{0}', '\u{0}']), ('\u{1c94}', ['\u{10d4}', '\u{0}', '\u{0}']), + ('\u{1c95}', ['\u{10d5}', '\u{0}', '\u{0}']), ('\u{1c96}', ['\u{10d6}', '\u{0}', '\u{0}']), + ('\u{1c97}', ['\u{10d7}', '\u{0}', '\u{0}']), ('\u{1c98}', ['\u{10d8}', '\u{0}', '\u{0}']), + ('\u{1c99}', ['\u{10d9}', '\u{0}', '\u{0}']), ('\u{1c9a}', ['\u{10da}', '\u{0}', '\u{0}']), + ('\u{1c9b}', ['\u{10db}', '\u{0}', '\u{0}']), ('\u{1c9c}', ['\u{10dc}', '\u{0}', '\u{0}']), + ('\u{1c9d}', ['\u{10dd}', '\u{0}', '\u{0}']), ('\u{1c9e}', ['\u{10de}', '\u{0}', '\u{0}']), + ('\u{1c9f}', ['\u{10df}', '\u{0}', '\u{0}']), ('\u{1ca0}', ['\u{10e0}', '\u{0}', '\u{0}']), + ('\u{1ca1}', ['\u{10e1}', '\u{0}', '\u{0}']), ('\u{1ca2}', ['\u{10e2}', '\u{0}', '\u{0}']), + ('\u{1ca3}', ['\u{10e3}', '\u{0}', '\u{0}']), ('\u{1ca4}', ['\u{10e4}', '\u{0}', '\u{0}']), + ('\u{1ca5}', ['\u{10e5}', '\u{0}', '\u{0}']), ('\u{1ca6}', ['\u{10e6}', '\u{0}', '\u{0}']), + ('\u{1ca7}', ['\u{10e7}', '\u{0}', '\u{0}']), ('\u{1ca8}', ['\u{10e8}', '\u{0}', '\u{0}']), + ('\u{1ca9}', ['\u{10e9}', '\u{0}', '\u{0}']), ('\u{1caa}', ['\u{10ea}', '\u{0}', '\u{0}']), + ('\u{1cab}', ['\u{10eb}', '\u{0}', '\u{0}']), ('\u{1cac}', ['\u{10ec}', '\u{0}', '\u{0}']), + ('\u{1cad}', ['\u{10ed}', '\u{0}', '\u{0}']), ('\u{1cae}', ['\u{10ee}', '\u{0}', '\u{0}']), + ('\u{1caf}', ['\u{10ef}', '\u{0}', '\u{0}']), ('\u{1cb0}', ['\u{10f0}', '\u{0}', '\u{0}']), + ('\u{1cb1}', ['\u{10f1}', '\u{0}', '\u{0}']), ('\u{1cb2}', ['\u{10f2}', '\u{0}', '\u{0}']), + ('\u{1cb3}', ['\u{10f3}', '\u{0}', '\u{0}']), ('\u{1cb4}', ['\u{10f4}', '\u{0}', '\u{0}']), + ('\u{1cb5}', ['\u{10f5}', '\u{0}', '\u{0}']), ('\u{1cb6}', ['\u{10f6}', '\u{0}', '\u{0}']), + ('\u{1cb7}', ['\u{10f7}', '\u{0}', '\u{0}']), ('\u{1cb8}', ['\u{10f8}', '\u{0}', '\u{0}']), + ('\u{1cb9}', ['\u{10f9}', '\u{0}', '\u{0}']), ('\u{1cba}', ['\u{10fa}', '\u{0}', '\u{0}']), + ('\u{1cbd}', ['\u{10fd}', '\u{0}', '\u{0}']), ('\u{1cbe}', ['\u{10fe}', '\u{0}', '\u{0}']), + ('\u{1cbf}', ['\u{10ff}', '\u{0}', '\u{0}']), ('\u{1e00}', ['\u{1e01}', '\u{0}', '\u{0}']), + ('\u{1e02}', ['\u{1e03}', '\u{0}', '\u{0}']), ('\u{1e04}', ['\u{1e05}', '\u{0}', '\u{0}']), + ('\u{1e06}', ['\u{1e07}', '\u{0}', '\u{0}']), ('\u{1e08}', ['\u{1e09}', '\u{0}', '\u{0}']), + ('\u{1e0a}', ['\u{1e0b}', '\u{0}', '\u{0}']), ('\u{1e0c}', ['\u{1e0d}', '\u{0}', '\u{0}']), + ('\u{1e0e}', ['\u{1e0f}', '\u{0}', '\u{0}']), ('\u{1e10}', ['\u{1e11}', '\u{0}', '\u{0}']), + ('\u{1e12}', ['\u{1e13}', '\u{0}', '\u{0}']), ('\u{1e14}', ['\u{1e15}', '\u{0}', '\u{0}']), + ('\u{1e16}', ['\u{1e17}', '\u{0}', '\u{0}']), ('\u{1e18}', ['\u{1e19}', '\u{0}', '\u{0}']), + ('\u{1e1a}', ['\u{1e1b}', '\u{0}', '\u{0}']), ('\u{1e1c}', ['\u{1e1d}', '\u{0}', '\u{0}']), + ('\u{1e1e}', ['\u{1e1f}', '\u{0}', '\u{0}']), ('\u{1e20}', ['\u{1e21}', '\u{0}', '\u{0}']), + ('\u{1e22}', ['\u{1e23}', '\u{0}', '\u{0}']), ('\u{1e24}', ['\u{1e25}', '\u{0}', '\u{0}']), + ('\u{1e26}', ['\u{1e27}', '\u{0}', '\u{0}']), ('\u{1e28}', ['\u{1e29}', '\u{0}', '\u{0}']), + ('\u{1e2a}', ['\u{1e2b}', '\u{0}', '\u{0}']), ('\u{1e2c}', ['\u{1e2d}', '\u{0}', '\u{0}']), + ('\u{1e2e}', ['\u{1e2f}', '\u{0}', '\u{0}']), ('\u{1e30}', ['\u{1e31}', '\u{0}', '\u{0}']), + ('\u{1e32}', ['\u{1e33}', '\u{0}', '\u{0}']), ('\u{1e34}', ['\u{1e35}', '\u{0}', '\u{0}']), + ('\u{1e36}', ['\u{1e37}', '\u{0}', '\u{0}']), ('\u{1e38}', ['\u{1e39}', '\u{0}', '\u{0}']), + ('\u{1e3a}', ['\u{1e3b}', '\u{0}', '\u{0}']), ('\u{1e3c}', ['\u{1e3d}', '\u{0}', '\u{0}']), + ('\u{1e3e}', ['\u{1e3f}', '\u{0}', '\u{0}']), ('\u{1e40}', ['\u{1e41}', '\u{0}', '\u{0}']), + ('\u{1e42}', ['\u{1e43}', '\u{0}', '\u{0}']), ('\u{1e44}', ['\u{1e45}', '\u{0}', '\u{0}']), + ('\u{1e46}', ['\u{1e47}', '\u{0}', '\u{0}']), ('\u{1e48}', ['\u{1e49}', '\u{0}', '\u{0}']), + ('\u{1e4a}', ['\u{1e4b}', '\u{0}', '\u{0}']), ('\u{1e4c}', ['\u{1e4d}', '\u{0}', '\u{0}']), + ('\u{1e4e}', ['\u{1e4f}', '\u{0}', '\u{0}']), ('\u{1e50}', ['\u{1e51}', '\u{0}', '\u{0}']), + ('\u{1e52}', ['\u{1e53}', '\u{0}', '\u{0}']), ('\u{1e54}', ['\u{1e55}', '\u{0}', '\u{0}']), + ('\u{1e56}', ['\u{1e57}', '\u{0}', '\u{0}']), ('\u{1e58}', ['\u{1e59}', '\u{0}', '\u{0}']), + ('\u{1e5a}', ['\u{1e5b}', '\u{0}', '\u{0}']), ('\u{1e5c}', ['\u{1e5d}', '\u{0}', '\u{0}']), + ('\u{1e5e}', ['\u{1e5f}', '\u{0}', '\u{0}']), ('\u{1e60}', ['\u{1e61}', '\u{0}', '\u{0}']), + ('\u{1e62}', ['\u{1e63}', '\u{0}', '\u{0}']), ('\u{1e64}', ['\u{1e65}', '\u{0}', '\u{0}']), + ('\u{1e66}', ['\u{1e67}', '\u{0}', '\u{0}']), ('\u{1e68}', ['\u{1e69}', '\u{0}', '\u{0}']), + ('\u{1e6a}', ['\u{1e6b}', '\u{0}', '\u{0}']), ('\u{1e6c}', ['\u{1e6d}', '\u{0}', '\u{0}']), + ('\u{1e6e}', ['\u{1e6f}', '\u{0}', '\u{0}']), ('\u{1e70}', ['\u{1e71}', '\u{0}', '\u{0}']), + ('\u{1e72}', ['\u{1e73}', '\u{0}', '\u{0}']), ('\u{1e74}', ['\u{1e75}', '\u{0}', '\u{0}']), + ('\u{1e76}', ['\u{1e77}', '\u{0}', '\u{0}']), ('\u{1e78}', ['\u{1e79}', '\u{0}', '\u{0}']), + ('\u{1e7a}', ['\u{1e7b}', '\u{0}', '\u{0}']), ('\u{1e7c}', ['\u{1e7d}', '\u{0}', '\u{0}']), + ('\u{1e7e}', ['\u{1e7f}', '\u{0}', '\u{0}']), ('\u{1e80}', ['\u{1e81}', '\u{0}', '\u{0}']), + ('\u{1e82}', ['\u{1e83}', '\u{0}', '\u{0}']), ('\u{1e84}', ['\u{1e85}', '\u{0}', '\u{0}']), + ('\u{1e86}', ['\u{1e87}', '\u{0}', '\u{0}']), ('\u{1e88}', ['\u{1e89}', '\u{0}', '\u{0}']), + ('\u{1e8a}', ['\u{1e8b}', '\u{0}', '\u{0}']), ('\u{1e8c}', ['\u{1e8d}', '\u{0}', '\u{0}']), + ('\u{1e8e}', ['\u{1e8f}', '\u{0}', '\u{0}']), ('\u{1e90}', ['\u{1e91}', '\u{0}', '\u{0}']), + ('\u{1e92}', ['\u{1e93}', '\u{0}', '\u{0}']), ('\u{1e94}', ['\u{1e95}', '\u{0}', '\u{0}']), + ('\u{1e9e}', ['\u{df}', '\u{0}', '\u{0}']), ('\u{1ea0}', ['\u{1ea1}', '\u{0}', '\u{0}']), + ('\u{1ea2}', ['\u{1ea3}', '\u{0}', '\u{0}']), ('\u{1ea4}', ['\u{1ea5}', '\u{0}', '\u{0}']), + ('\u{1ea6}', ['\u{1ea7}', '\u{0}', '\u{0}']), ('\u{1ea8}', ['\u{1ea9}', '\u{0}', '\u{0}']), + ('\u{1eaa}', ['\u{1eab}', '\u{0}', '\u{0}']), ('\u{1eac}', ['\u{1ead}', '\u{0}', '\u{0}']), + ('\u{1eae}', ['\u{1eaf}', '\u{0}', '\u{0}']), ('\u{1eb0}', ['\u{1eb1}', '\u{0}', '\u{0}']), + ('\u{1eb2}', ['\u{1eb3}', '\u{0}', '\u{0}']), ('\u{1eb4}', ['\u{1eb5}', '\u{0}', '\u{0}']), + ('\u{1eb6}', ['\u{1eb7}', '\u{0}', '\u{0}']), ('\u{1eb8}', ['\u{1eb9}', '\u{0}', '\u{0}']), + ('\u{1eba}', ['\u{1ebb}', '\u{0}', '\u{0}']), ('\u{1ebc}', ['\u{1ebd}', '\u{0}', '\u{0}']), + ('\u{1ebe}', ['\u{1ebf}', '\u{0}', '\u{0}']), ('\u{1ec0}', ['\u{1ec1}', '\u{0}', '\u{0}']), + ('\u{1ec2}', ['\u{1ec3}', '\u{0}', '\u{0}']), ('\u{1ec4}', ['\u{1ec5}', '\u{0}', '\u{0}']), + ('\u{1ec6}', ['\u{1ec7}', '\u{0}', '\u{0}']), ('\u{1ec8}', ['\u{1ec9}', '\u{0}', '\u{0}']), + ('\u{1eca}', ['\u{1ecb}', '\u{0}', '\u{0}']), ('\u{1ecc}', ['\u{1ecd}', '\u{0}', '\u{0}']), + ('\u{1ece}', ['\u{1ecf}', '\u{0}', '\u{0}']), ('\u{1ed0}', ['\u{1ed1}', '\u{0}', '\u{0}']), + ('\u{1ed2}', ['\u{1ed3}', '\u{0}', '\u{0}']), ('\u{1ed4}', ['\u{1ed5}', '\u{0}', '\u{0}']), + ('\u{1ed6}', ['\u{1ed7}', '\u{0}', '\u{0}']), ('\u{1ed8}', ['\u{1ed9}', '\u{0}', '\u{0}']), + ('\u{1eda}', ['\u{1edb}', '\u{0}', '\u{0}']), ('\u{1edc}', ['\u{1edd}', '\u{0}', '\u{0}']), + ('\u{1ede}', ['\u{1edf}', '\u{0}', '\u{0}']), ('\u{1ee0}', ['\u{1ee1}', '\u{0}', '\u{0}']), + ('\u{1ee2}', ['\u{1ee3}', '\u{0}', '\u{0}']), ('\u{1ee4}', ['\u{1ee5}', '\u{0}', '\u{0}']), + ('\u{1ee6}', ['\u{1ee7}', '\u{0}', '\u{0}']), ('\u{1ee8}', ['\u{1ee9}', '\u{0}', '\u{0}']), + ('\u{1eea}', ['\u{1eeb}', '\u{0}', '\u{0}']), ('\u{1eec}', ['\u{1eed}', '\u{0}', '\u{0}']), + ('\u{1eee}', ['\u{1eef}', '\u{0}', '\u{0}']), ('\u{1ef0}', ['\u{1ef1}', '\u{0}', '\u{0}']), + ('\u{1ef2}', ['\u{1ef3}', '\u{0}', '\u{0}']), ('\u{1ef4}', ['\u{1ef5}', '\u{0}', '\u{0}']), + ('\u{1ef6}', ['\u{1ef7}', '\u{0}', '\u{0}']), ('\u{1ef8}', ['\u{1ef9}', '\u{0}', '\u{0}']), + ('\u{1efa}', ['\u{1efb}', '\u{0}', '\u{0}']), ('\u{1efc}', ['\u{1efd}', '\u{0}', '\u{0}']), + ('\u{1efe}', ['\u{1eff}', '\u{0}', '\u{0}']), ('\u{1f08}', ['\u{1f00}', '\u{0}', '\u{0}']), + ('\u{1f09}', ['\u{1f01}', '\u{0}', '\u{0}']), ('\u{1f0a}', ['\u{1f02}', '\u{0}', '\u{0}']), + ('\u{1f0b}', ['\u{1f03}', '\u{0}', '\u{0}']), ('\u{1f0c}', ['\u{1f04}', '\u{0}', '\u{0}']), + ('\u{1f0d}', ['\u{1f05}', '\u{0}', '\u{0}']), ('\u{1f0e}', ['\u{1f06}', '\u{0}', '\u{0}']), + ('\u{1f0f}', ['\u{1f07}', '\u{0}', '\u{0}']), ('\u{1f18}', ['\u{1f10}', '\u{0}', '\u{0}']), + ('\u{1f19}', ['\u{1f11}', '\u{0}', '\u{0}']), ('\u{1f1a}', ['\u{1f12}', '\u{0}', '\u{0}']), + ('\u{1f1b}', ['\u{1f13}', '\u{0}', '\u{0}']), ('\u{1f1c}', ['\u{1f14}', '\u{0}', '\u{0}']), + ('\u{1f1d}', ['\u{1f15}', '\u{0}', '\u{0}']), ('\u{1f28}', ['\u{1f20}', '\u{0}', '\u{0}']), + ('\u{1f29}', ['\u{1f21}', '\u{0}', '\u{0}']), ('\u{1f2a}', ['\u{1f22}', '\u{0}', '\u{0}']), + ('\u{1f2b}', ['\u{1f23}', '\u{0}', '\u{0}']), ('\u{1f2c}', ['\u{1f24}', '\u{0}', '\u{0}']), + ('\u{1f2d}', ['\u{1f25}', '\u{0}', '\u{0}']), ('\u{1f2e}', ['\u{1f26}', '\u{0}', '\u{0}']), + ('\u{1f2f}', ['\u{1f27}', '\u{0}', '\u{0}']), ('\u{1f38}', ['\u{1f30}', '\u{0}', '\u{0}']), + ('\u{1f39}', ['\u{1f31}', '\u{0}', '\u{0}']), ('\u{1f3a}', ['\u{1f32}', '\u{0}', '\u{0}']), + ('\u{1f3b}', ['\u{1f33}', '\u{0}', '\u{0}']), ('\u{1f3c}', ['\u{1f34}', '\u{0}', '\u{0}']), + ('\u{1f3d}', ['\u{1f35}', '\u{0}', '\u{0}']), ('\u{1f3e}', ['\u{1f36}', '\u{0}', '\u{0}']), + ('\u{1f3f}', ['\u{1f37}', '\u{0}', '\u{0}']), ('\u{1f48}', ['\u{1f40}', '\u{0}', '\u{0}']), + ('\u{1f49}', ['\u{1f41}', '\u{0}', '\u{0}']), ('\u{1f4a}', ['\u{1f42}', '\u{0}', '\u{0}']), + ('\u{1f4b}', ['\u{1f43}', '\u{0}', '\u{0}']), ('\u{1f4c}', ['\u{1f44}', '\u{0}', '\u{0}']), + ('\u{1f4d}', ['\u{1f45}', '\u{0}', '\u{0}']), ('\u{1f59}', ['\u{1f51}', '\u{0}', '\u{0}']), + ('\u{1f5b}', ['\u{1f53}', '\u{0}', '\u{0}']), ('\u{1f5d}', ['\u{1f55}', '\u{0}', '\u{0}']), + ('\u{1f5f}', ['\u{1f57}', '\u{0}', '\u{0}']), ('\u{1f68}', ['\u{1f60}', '\u{0}', '\u{0}']), + ('\u{1f69}', ['\u{1f61}', '\u{0}', '\u{0}']), ('\u{1f6a}', ['\u{1f62}', '\u{0}', '\u{0}']), + ('\u{1f6b}', ['\u{1f63}', '\u{0}', '\u{0}']), ('\u{1f6c}', ['\u{1f64}', '\u{0}', '\u{0}']), + ('\u{1f6d}', ['\u{1f65}', '\u{0}', '\u{0}']), ('\u{1f6e}', ['\u{1f66}', '\u{0}', '\u{0}']), + ('\u{1f6f}', ['\u{1f67}', '\u{0}', '\u{0}']), ('\u{1f88}', ['\u{1f80}', '\u{0}', '\u{0}']), + ('\u{1f89}', ['\u{1f81}', '\u{0}', '\u{0}']), ('\u{1f8a}', ['\u{1f82}', '\u{0}', '\u{0}']), + ('\u{1f8b}', ['\u{1f83}', '\u{0}', '\u{0}']), ('\u{1f8c}', ['\u{1f84}', '\u{0}', '\u{0}']), + ('\u{1f8d}', ['\u{1f85}', '\u{0}', '\u{0}']), ('\u{1f8e}', ['\u{1f86}', '\u{0}', '\u{0}']), + ('\u{1f8f}', ['\u{1f87}', '\u{0}', '\u{0}']), ('\u{1f98}', ['\u{1f90}', '\u{0}', '\u{0}']), + ('\u{1f99}', ['\u{1f91}', '\u{0}', '\u{0}']), ('\u{1f9a}', ['\u{1f92}', '\u{0}', '\u{0}']), + ('\u{1f9b}', ['\u{1f93}', '\u{0}', '\u{0}']), ('\u{1f9c}', ['\u{1f94}', '\u{0}', '\u{0}']), + ('\u{1f9d}', ['\u{1f95}', '\u{0}', '\u{0}']), ('\u{1f9e}', ['\u{1f96}', '\u{0}', '\u{0}']), + ('\u{1f9f}', ['\u{1f97}', '\u{0}', '\u{0}']), ('\u{1fa8}', ['\u{1fa0}', '\u{0}', '\u{0}']), + ('\u{1fa9}', ['\u{1fa1}', '\u{0}', '\u{0}']), ('\u{1faa}', ['\u{1fa2}', '\u{0}', '\u{0}']), + ('\u{1fab}', ['\u{1fa3}', '\u{0}', '\u{0}']), ('\u{1fac}', ['\u{1fa4}', '\u{0}', '\u{0}']), + ('\u{1fad}', ['\u{1fa5}', '\u{0}', '\u{0}']), ('\u{1fae}', ['\u{1fa6}', '\u{0}', '\u{0}']), + ('\u{1faf}', ['\u{1fa7}', '\u{0}', '\u{0}']), ('\u{1fb8}', ['\u{1fb0}', '\u{0}', '\u{0}']), + ('\u{1fb9}', ['\u{1fb1}', '\u{0}', '\u{0}']), ('\u{1fba}', ['\u{1f70}', '\u{0}', '\u{0}']), + ('\u{1fbb}', ['\u{1f71}', '\u{0}', '\u{0}']), ('\u{1fbc}', ['\u{1fb3}', '\u{0}', '\u{0}']), + ('\u{1fc8}', ['\u{1f72}', '\u{0}', '\u{0}']), ('\u{1fc9}', ['\u{1f73}', '\u{0}', '\u{0}']), + ('\u{1fca}', ['\u{1f74}', '\u{0}', '\u{0}']), ('\u{1fcb}', ['\u{1f75}', '\u{0}', '\u{0}']), + ('\u{1fcc}', ['\u{1fc3}', '\u{0}', '\u{0}']), ('\u{1fd8}', ['\u{1fd0}', '\u{0}', '\u{0}']), + ('\u{1fd9}', ['\u{1fd1}', '\u{0}', '\u{0}']), ('\u{1fda}', ['\u{1f76}', '\u{0}', '\u{0}']), + ('\u{1fdb}', ['\u{1f77}', '\u{0}', '\u{0}']), ('\u{1fe8}', ['\u{1fe0}', '\u{0}', '\u{0}']), + ('\u{1fe9}', ['\u{1fe1}', '\u{0}', '\u{0}']), ('\u{1fea}', ['\u{1f7a}', '\u{0}', '\u{0}']), + ('\u{1feb}', ['\u{1f7b}', '\u{0}', '\u{0}']), ('\u{1fec}', ['\u{1fe5}', '\u{0}', '\u{0}']), + ('\u{1ff8}', ['\u{1f78}', '\u{0}', '\u{0}']), ('\u{1ff9}', ['\u{1f79}', '\u{0}', '\u{0}']), + ('\u{1ffa}', ['\u{1f7c}', '\u{0}', '\u{0}']), ('\u{1ffb}', ['\u{1f7d}', '\u{0}', '\u{0}']), + ('\u{1ffc}', ['\u{1ff3}', '\u{0}', '\u{0}']), ('\u{2126}', ['\u{3c9}', '\u{0}', '\u{0}']), + ('\u{212a}', ['k', '\u{0}', '\u{0}']), ('\u{212b}', ['\u{e5}', '\u{0}', '\u{0}']), + ('\u{2132}', ['\u{214e}', '\u{0}', '\u{0}']), ('\u{2160}', ['\u{2170}', '\u{0}', '\u{0}']), + ('\u{2161}', ['\u{2171}', '\u{0}', '\u{0}']), ('\u{2162}', ['\u{2172}', '\u{0}', '\u{0}']), + ('\u{2163}', ['\u{2173}', '\u{0}', '\u{0}']), ('\u{2164}', ['\u{2174}', '\u{0}', '\u{0}']), + ('\u{2165}', ['\u{2175}', '\u{0}', '\u{0}']), ('\u{2166}', ['\u{2176}', '\u{0}', '\u{0}']), + ('\u{2167}', ['\u{2177}', '\u{0}', '\u{0}']), ('\u{2168}', ['\u{2178}', '\u{0}', '\u{0}']), + ('\u{2169}', ['\u{2179}', '\u{0}', '\u{0}']), ('\u{216a}', ['\u{217a}', '\u{0}', '\u{0}']), + ('\u{216b}', ['\u{217b}', '\u{0}', '\u{0}']), ('\u{216c}', ['\u{217c}', '\u{0}', '\u{0}']), + ('\u{216d}', ['\u{217d}', '\u{0}', '\u{0}']), ('\u{216e}', ['\u{217e}', '\u{0}', '\u{0}']), + ('\u{216f}', ['\u{217f}', '\u{0}', '\u{0}']), ('\u{2183}', ['\u{2184}', '\u{0}', '\u{0}']), + ('\u{24b6}', ['\u{24d0}', '\u{0}', '\u{0}']), ('\u{24b7}', ['\u{24d1}', '\u{0}', '\u{0}']), + ('\u{24b8}', ['\u{24d2}', '\u{0}', '\u{0}']), ('\u{24b9}', ['\u{24d3}', '\u{0}', '\u{0}']), + ('\u{24ba}', ['\u{24d4}', '\u{0}', '\u{0}']), ('\u{24bb}', ['\u{24d5}', '\u{0}', '\u{0}']), + ('\u{24bc}', ['\u{24d6}', '\u{0}', '\u{0}']), ('\u{24bd}', ['\u{24d7}', '\u{0}', '\u{0}']), + ('\u{24be}', ['\u{24d8}', '\u{0}', '\u{0}']), ('\u{24bf}', ['\u{24d9}', '\u{0}', '\u{0}']), + ('\u{24c0}', ['\u{24da}', '\u{0}', '\u{0}']), ('\u{24c1}', ['\u{24db}', '\u{0}', '\u{0}']), + ('\u{24c2}', ['\u{24dc}', '\u{0}', '\u{0}']), ('\u{24c3}', ['\u{24dd}', '\u{0}', '\u{0}']), + ('\u{24c4}', ['\u{24de}', '\u{0}', '\u{0}']), ('\u{24c5}', ['\u{24df}', '\u{0}', '\u{0}']), + ('\u{24c6}', ['\u{24e0}', '\u{0}', '\u{0}']), ('\u{24c7}', ['\u{24e1}', '\u{0}', '\u{0}']), + ('\u{24c8}', ['\u{24e2}', '\u{0}', '\u{0}']), ('\u{24c9}', ['\u{24e3}', '\u{0}', '\u{0}']), + ('\u{24ca}', ['\u{24e4}', '\u{0}', '\u{0}']), ('\u{24cb}', ['\u{24e5}', '\u{0}', '\u{0}']), + ('\u{24cc}', ['\u{24e6}', '\u{0}', '\u{0}']), ('\u{24cd}', ['\u{24e7}', '\u{0}', '\u{0}']), + ('\u{24ce}', ['\u{24e8}', '\u{0}', '\u{0}']), ('\u{24cf}', ['\u{24e9}', '\u{0}', '\u{0}']), + ('\u{2c00}', ['\u{2c30}', '\u{0}', '\u{0}']), ('\u{2c01}', ['\u{2c31}', '\u{0}', '\u{0}']), + ('\u{2c02}', ['\u{2c32}', '\u{0}', '\u{0}']), ('\u{2c03}', ['\u{2c33}', '\u{0}', '\u{0}']), + ('\u{2c04}', ['\u{2c34}', '\u{0}', '\u{0}']), ('\u{2c05}', ['\u{2c35}', '\u{0}', '\u{0}']), + ('\u{2c06}', ['\u{2c36}', '\u{0}', '\u{0}']), ('\u{2c07}', ['\u{2c37}', '\u{0}', '\u{0}']), + ('\u{2c08}', ['\u{2c38}', '\u{0}', '\u{0}']), ('\u{2c09}', ['\u{2c39}', '\u{0}', '\u{0}']), + ('\u{2c0a}', ['\u{2c3a}', '\u{0}', '\u{0}']), ('\u{2c0b}', ['\u{2c3b}', '\u{0}', '\u{0}']), + ('\u{2c0c}', ['\u{2c3c}', '\u{0}', '\u{0}']), ('\u{2c0d}', ['\u{2c3d}', '\u{0}', '\u{0}']), + ('\u{2c0e}', ['\u{2c3e}', '\u{0}', '\u{0}']), ('\u{2c0f}', ['\u{2c3f}', '\u{0}', '\u{0}']), + ('\u{2c10}', ['\u{2c40}', '\u{0}', '\u{0}']), ('\u{2c11}', ['\u{2c41}', '\u{0}', '\u{0}']), + ('\u{2c12}', ['\u{2c42}', '\u{0}', '\u{0}']), ('\u{2c13}', ['\u{2c43}', '\u{0}', '\u{0}']), + ('\u{2c14}', ['\u{2c44}', '\u{0}', '\u{0}']), ('\u{2c15}', ['\u{2c45}', '\u{0}', '\u{0}']), + ('\u{2c16}', ['\u{2c46}', '\u{0}', '\u{0}']), ('\u{2c17}', ['\u{2c47}', '\u{0}', '\u{0}']), + ('\u{2c18}', ['\u{2c48}', '\u{0}', '\u{0}']), ('\u{2c19}', ['\u{2c49}', '\u{0}', '\u{0}']), + ('\u{2c1a}', ['\u{2c4a}', '\u{0}', '\u{0}']), ('\u{2c1b}', ['\u{2c4b}', '\u{0}', '\u{0}']), + ('\u{2c1c}', ['\u{2c4c}', '\u{0}', '\u{0}']), ('\u{2c1d}', ['\u{2c4d}', '\u{0}', '\u{0}']), + ('\u{2c1e}', ['\u{2c4e}', '\u{0}', '\u{0}']), ('\u{2c1f}', ['\u{2c4f}', '\u{0}', '\u{0}']), + ('\u{2c20}', ['\u{2c50}', '\u{0}', '\u{0}']), ('\u{2c21}', ['\u{2c51}', '\u{0}', '\u{0}']), + ('\u{2c22}', ['\u{2c52}', '\u{0}', '\u{0}']), ('\u{2c23}', ['\u{2c53}', '\u{0}', '\u{0}']), + ('\u{2c24}', ['\u{2c54}', '\u{0}', '\u{0}']), ('\u{2c25}', ['\u{2c55}', '\u{0}', '\u{0}']), + ('\u{2c26}', ['\u{2c56}', '\u{0}', '\u{0}']), ('\u{2c27}', ['\u{2c57}', '\u{0}', '\u{0}']), + ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']), + ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']), + ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']), + ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), + ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), + ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), + ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), + ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), + ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), + ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), + ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), + ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), + ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), + ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), + ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), + ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), + ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), + ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), + ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), + ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), + ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), + ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), + ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), + ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), + ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), + ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), + ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), + ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), + ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), + ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), + ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), + ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), + ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), + ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), + ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), + ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), + ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), + ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), + ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), + ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), + ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), + ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), + ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), + ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), + ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), + ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), + ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), + ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), + ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), + ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), + ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), + ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), + ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), + ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), + ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), + ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), + ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), + ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), + ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), + ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), + ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), + ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), + ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), + ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), + ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), + ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), + ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), + ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), + ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), + ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), + ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), + ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), + ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), + ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), + ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), + ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), + ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), + ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), + ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), + ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), + ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), + ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), + ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), + ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), + ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), + ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), + ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), + ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), + ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), + ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), + ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), + ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), + ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), + ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']), + ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']), + ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), + ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), + ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), + ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), + ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), + ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), + ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), + ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), + ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), + ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), + ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), + ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), + ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), + ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']), + ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']), + ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']), + ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']), + ('\u{10403}', ['\u{1042b}', '\u{0}', '\u{0}']), + ('\u{10404}', ['\u{1042c}', '\u{0}', '\u{0}']), + ('\u{10405}', ['\u{1042d}', '\u{0}', '\u{0}']), + ('\u{10406}', ['\u{1042e}', '\u{0}', '\u{0}']), + ('\u{10407}', ['\u{1042f}', '\u{0}', '\u{0}']), + ('\u{10408}', ['\u{10430}', '\u{0}', '\u{0}']), + ('\u{10409}', ['\u{10431}', '\u{0}', '\u{0}']), + ('\u{1040a}', ['\u{10432}', '\u{0}', '\u{0}']), + ('\u{1040b}', ['\u{10433}', '\u{0}', '\u{0}']), + ('\u{1040c}', ['\u{10434}', '\u{0}', '\u{0}']), + ('\u{1040d}', ['\u{10435}', '\u{0}', '\u{0}']), + ('\u{1040e}', ['\u{10436}', '\u{0}', '\u{0}']), + ('\u{1040f}', ['\u{10437}', '\u{0}', '\u{0}']), + ('\u{10410}', ['\u{10438}', '\u{0}', '\u{0}']), + ('\u{10411}', ['\u{10439}', '\u{0}', '\u{0}']), + ('\u{10412}', ['\u{1043a}', '\u{0}', '\u{0}']), + ('\u{10413}', ['\u{1043b}', '\u{0}', '\u{0}']), + ('\u{10414}', ['\u{1043c}', '\u{0}', '\u{0}']), + ('\u{10415}', ['\u{1043d}', '\u{0}', '\u{0}']), + ('\u{10416}', ['\u{1043e}', '\u{0}', '\u{0}']), + ('\u{10417}', ['\u{1043f}', '\u{0}', '\u{0}']), + ('\u{10418}', ['\u{10440}', '\u{0}', '\u{0}']), + ('\u{10419}', ['\u{10441}', '\u{0}', '\u{0}']), + ('\u{1041a}', ['\u{10442}', '\u{0}', '\u{0}']), + ('\u{1041b}', ['\u{10443}', '\u{0}', '\u{0}']), + ('\u{1041c}', ['\u{10444}', '\u{0}', '\u{0}']), + ('\u{1041d}', ['\u{10445}', '\u{0}', '\u{0}']), + ('\u{1041e}', ['\u{10446}', '\u{0}', '\u{0}']), + ('\u{1041f}', ['\u{10447}', '\u{0}', '\u{0}']), + ('\u{10420}', ['\u{10448}', '\u{0}', '\u{0}']), + ('\u{10421}', ['\u{10449}', '\u{0}', '\u{0}']), + ('\u{10422}', ['\u{1044a}', '\u{0}', '\u{0}']), + ('\u{10423}', ['\u{1044b}', '\u{0}', '\u{0}']), + ('\u{10424}', ['\u{1044c}', '\u{0}', '\u{0}']), + ('\u{10425}', ['\u{1044d}', '\u{0}', '\u{0}']), + ('\u{10426}', ['\u{1044e}', '\u{0}', '\u{0}']), + ('\u{10427}', ['\u{1044f}', '\u{0}', '\u{0}']), + ('\u{104b0}', ['\u{104d8}', '\u{0}', '\u{0}']), + ('\u{104b1}', ['\u{104d9}', '\u{0}', '\u{0}']), + ('\u{104b2}', ['\u{104da}', '\u{0}', '\u{0}']), + ('\u{104b3}', ['\u{104db}', '\u{0}', '\u{0}']), + ('\u{104b4}', ['\u{104dc}', '\u{0}', '\u{0}']), + ('\u{104b5}', ['\u{104dd}', '\u{0}', '\u{0}']), + ('\u{104b6}', ['\u{104de}', '\u{0}', '\u{0}']), + ('\u{104b7}', ['\u{104df}', '\u{0}', '\u{0}']), + ('\u{104b8}', ['\u{104e0}', '\u{0}', '\u{0}']), + ('\u{104b9}', ['\u{104e1}', '\u{0}', '\u{0}']), + ('\u{104ba}', ['\u{104e2}', '\u{0}', '\u{0}']), + ('\u{104bb}', ['\u{104e3}', '\u{0}', '\u{0}']), + ('\u{104bc}', ['\u{104e4}', '\u{0}', '\u{0}']), + ('\u{104bd}', ['\u{104e5}', '\u{0}', '\u{0}']), + ('\u{104be}', ['\u{104e6}', '\u{0}', '\u{0}']), + ('\u{104bf}', ['\u{104e7}', '\u{0}', '\u{0}']), + ('\u{104c0}', ['\u{104e8}', '\u{0}', '\u{0}']), + ('\u{104c1}', ['\u{104e9}', '\u{0}', '\u{0}']), + ('\u{104c2}', ['\u{104ea}', '\u{0}', '\u{0}']), + ('\u{104c3}', ['\u{104eb}', '\u{0}', '\u{0}']), + ('\u{104c4}', ['\u{104ec}', '\u{0}', '\u{0}']), + ('\u{104c5}', ['\u{104ed}', '\u{0}', '\u{0}']), + ('\u{104c6}', ['\u{104ee}', '\u{0}', '\u{0}']), + ('\u{104c7}', ['\u{104ef}', '\u{0}', '\u{0}']), + ('\u{104c8}', ['\u{104f0}', '\u{0}', '\u{0}']), + ('\u{104c9}', ['\u{104f1}', '\u{0}', '\u{0}']), + ('\u{104ca}', ['\u{104f2}', '\u{0}', '\u{0}']), + ('\u{104cb}', ['\u{104f3}', '\u{0}', '\u{0}']), + ('\u{104cc}', ['\u{104f4}', '\u{0}', '\u{0}']), + ('\u{104cd}', ['\u{104f5}', '\u{0}', '\u{0}']), + ('\u{104ce}', ['\u{104f6}', '\u{0}', '\u{0}']), + ('\u{104cf}', ['\u{104f7}', '\u{0}', '\u{0}']), + ('\u{104d0}', ['\u{104f8}', '\u{0}', '\u{0}']), + ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']), + ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']), + ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']), + ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']), + ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']), + ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']), + ('\u{10c83}', ['\u{10cc3}', '\u{0}', '\u{0}']), + ('\u{10c84}', ['\u{10cc4}', '\u{0}', '\u{0}']), + ('\u{10c85}', ['\u{10cc5}', '\u{0}', '\u{0}']), + ('\u{10c86}', ['\u{10cc6}', '\u{0}', '\u{0}']), + ('\u{10c87}', ['\u{10cc7}', '\u{0}', '\u{0}']), + ('\u{10c88}', ['\u{10cc8}', '\u{0}', '\u{0}']), + ('\u{10c89}', ['\u{10cc9}', '\u{0}', '\u{0}']), + ('\u{10c8a}', ['\u{10cca}', '\u{0}', '\u{0}']), + ('\u{10c8b}', ['\u{10ccb}', '\u{0}', '\u{0}']), + ('\u{10c8c}', ['\u{10ccc}', '\u{0}', '\u{0}']), + ('\u{10c8d}', ['\u{10ccd}', '\u{0}', '\u{0}']), + ('\u{10c8e}', ['\u{10cce}', '\u{0}', '\u{0}']), + ('\u{10c8f}', ['\u{10ccf}', '\u{0}', '\u{0}']), + ('\u{10c90}', ['\u{10cd0}', '\u{0}', '\u{0}']), + ('\u{10c91}', ['\u{10cd1}', '\u{0}', '\u{0}']), + ('\u{10c92}', ['\u{10cd2}', '\u{0}', '\u{0}']), + ('\u{10c93}', ['\u{10cd3}', '\u{0}', '\u{0}']), + ('\u{10c94}', ['\u{10cd4}', '\u{0}', '\u{0}']), + ('\u{10c95}', ['\u{10cd5}', '\u{0}', '\u{0}']), + ('\u{10c96}', ['\u{10cd6}', '\u{0}', '\u{0}']), + ('\u{10c97}', ['\u{10cd7}', '\u{0}', '\u{0}']), + ('\u{10c98}', ['\u{10cd8}', '\u{0}', '\u{0}']), + ('\u{10c99}', ['\u{10cd9}', '\u{0}', '\u{0}']), + ('\u{10c9a}', ['\u{10cda}', '\u{0}', '\u{0}']), + ('\u{10c9b}', ['\u{10cdb}', '\u{0}', '\u{0}']), + ('\u{10c9c}', ['\u{10cdc}', '\u{0}', '\u{0}']), + ('\u{10c9d}', ['\u{10cdd}', '\u{0}', '\u{0}']), + ('\u{10c9e}', ['\u{10cde}', '\u{0}', '\u{0}']), + ('\u{10c9f}', ['\u{10cdf}', '\u{0}', '\u{0}']), + ('\u{10ca0}', ['\u{10ce0}', '\u{0}', '\u{0}']), + ('\u{10ca1}', ['\u{10ce1}', '\u{0}', '\u{0}']), + ('\u{10ca2}', ['\u{10ce2}', '\u{0}', '\u{0}']), + ('\u{10ca3}', ['\u{10ce3}', '\u{0}', '\u{0}']), + ('\u{10ca4}', ['\u{10ce4}', '\u{0}', '\u{0}']), + ('\u{10ca5}', ['\u{10ce5}', '\u{0}', '\u{0}']), + ('\u{10ca6}', ['\u{10ce6}', '\u{0}', '\u{0}']), + ('\u{10ca7}', ['\u{10ce7}', '\u{0}', '\u{0}']), + ('\u{10ca8}', ['\u{10ce8}', '\u{0}', '\u{0}']), + ('\u{10ca9}', ['\u{10ce9}', '\u{0}', '\u{0}']), + ('\u{10caa}', ['\u{10cea}', '\u{0}', '\u{0}']), + ('\u{10cab}', ['\u{10ceb}', '\u{0}', '\u{0}']), + ('\u{10cac}', ['\u{10cec}', '\u{0}', '\u{0}']), + ('\u{10cad}', ['\u{10ced}', '\u{0}', '\u{0}']), + ('\u{10cae}', ['\u{10cee}', '\u{0}', '\u{0}']), + ('\u{10caf}', ['\u{10cef}', '\u{0}', '\u{0}']), + ('\u{10cb0}', ['\u{10cf0}', '\u{0}', '\u{0}']), + ('\u{10cb1}', ['\u{10cf1}', '\u{0}', '\u{0}']), + ('\u{10cb2}', ['\u{10cf2}', '\u{0}', '\u{0}']), + ('\u{118a0}', ['\u{118c0}', '\u{0}', '\u{0}']), + ('\u{118a1}', ['\u{118c1}', '\u{0}', '\u{0}']), + ('\u{118a2}', ['\u{118c2}', '\u{0}', '\u{0}']), + ('\u{118a3}', ['\u{118c3}', '\u{0}', '\u{0}']), + ('\u{118a4}', ['\u{118c4}', '\u{0}', '\u{0}']), + ('\u{118a5}', ['\u{118c5}', '\u{0}', '\u{0}']), + ('\u{118a6}', ['\u{118c6}', '\u{0}', '\u{0}']), + ('\u{118a7}', ['\u{118c7}', '\u{0}', '\u{0}']), + ('\u{118a8}', ['\u{118c8}', '\u{0}', '\u{0}']), + ('\u{118a9}', ['\u{118c9}', '\u{0}', '\u{0}']), + ('\u{118aa}', ['\u{118ca}', '\u{0}', '\u{0}']), + ('\u{118ab}', ['\u{118cb}', '\u{0}', '\u{0}']), + ('\u{118ac}', ['\u{118cc}', '\u{0}', '\u{0}']), + ('\u{118ad}', ['\u{118cd}', '\u{0}', '\u{0}']), + ('\u{118ae}', ['\u{118ce}', '\u{0}', '\u{0}']), + ('\u{118af}', ['\u{118cf}', '\u{0}', '\u{0}']), + ('\u{118b0}', ['\u{118d0}', '\u{0}', '\u{0}']), + ('\u{118b1}', ['\u{118d1}', '\u{0}', '\u{0}']), + ('\u{118b2}', ['\u{118d2}', '\u{0}', '\u{0}']), + ('\u{118b3}', ['\u{118d3}', '\u{0}', '\u{0}']), + ('\u{118b4}', ['\u{118d4}', '\u{0}', '\u{0}']), + ('\u{118b5}', ['\u{118d5}', '\u{0}', '\u{0}']), + ('\u{118b6}', ['\u{118d6}', '\u{0}', '\u{0}']), + ('\u{118b7}', ['\u{118d7}', '\u{0}', '\u{0}']), + ('\u{118b8}', ['\u{118d8}', '\u{0}', '\u{0}']), + ('\u{118b9}', ['\u{118d9}', '\u{0}', '\u{0}']), + ('\u{118ba}', ['\u{118da}', '\u{0}', '\u{0}']), + ('\u{118bb}', ['\u{118db}', '\u{0}', '\u{0}']), + ('\u{118bc}', ['\u{118dc}', '\u{0}', '\u{0}']), + ('\u{118bd}', ['\u{118dd}', '\u{0}', '\u{0}']), + ('\u{118be}', ['\u{118de}', '\u{0}', '\u{0}']), + ('\u{118bf}', ['\u{118df}', '\u{0}', '\u{0}']), + ('\u{16e40}', ['\u{16e60}', '\u{0}', '\u{0}']), + ('\u{16e41}', ['\u{16e61}', '\u{0}', '\u{0}']), + ('\u{16e42}', ['\u{16e62}', '\u{0}', '\u{0}']), + ('\u{16e43}', ['\u{16e63}', '\u{0}', '\u{0}']), + ('\u{16e44}', ['\u{16e64}', '\u{0}', '\u{0}']), + ('\u{16e45}', ['\u{16e65}', '\u{0}', '\u{0}']), + ('\u{16e46}', ['\u{16e66}', '\u{0}', '\u{0}']), + ('\u{16e47}', ['\u{16e67}', '\u{0}', '\u{0}']), + ('\u{16e48}', ['\u{16e68}', '\u{0}', '\u{0}']), + ('\u{16e49}', ['\u{16e69}', '\u{0}', '\u{0}']), + ('\u{16e4a}', ['\u{16e6a}', '\u{0}', '\u{0}']), + ('\u{16e4b}', ['\u{16e6b}', '\u{0}', '\u{0}']), + ('\u{16e4c}', ['\u{16e6c}', '\u{0}', '\u{0}']), + ('\u{16e4d}', ['\u{16e6d}', '\u{0}', '\u{0}']), + ('\u{16e4e}', ['\u{16e6e}', '\u{0}', '\u{0}']), + ('\u{16e4f}', ['\u{16e6f}', '\u{0}', '\u{0}']), + ('\u{16e50}', ['\u{16e70}', '\u{0}', '\u{0}']), + ('\u{16e51}', ['\u{16e71}', '\u{0}', '\u{0}']), + ('\u{16e52}', ['\u{16e72}', '\u{0}', '\u{0}']), + ('\u{16e53}', ['\u{16e73}', '\u{0}', '\u{0}']), + ('\u{16e54}', ['\u{16e74}', '\u{0}', '\u{0}']), + ('\u{16e55}', ['\u{16e75}', '\u{0}', '\u{0}']), + ('\u{16e56}', ['\u{16e76}', '\u{0}', '\u{0}']), + ('\u{16e57}', ['\u{16e77}', '\u{0}', '\u{0}']), + ('\u{16e58}', ['\u{16e78}', '\u{0}', '\u{0}']), + ('\u{16e59}', ['\u{16e79}', '\u{0}', '\u{0}']), + ('\u{16e5a}', ['\u{16e7a}', '\u{0}', '\u{0}']), + ('\u{16e5b}', ['\u{16e7b}', '\u{0}', '\u{0}']), + ('\u{16e5c}', ['\u{16e7c}', '\u{0}', '\u{0}']), + ('\u{16e5d}', ['\u{16e7d}', '\u{0}', '\u{0}']), + ('\u{16e5e}', ['\u{16e7e}', '\u{0}', '\u{0}']), + ('\u{16e5f}', ['\u{16e7f}', '\u{0}', '\u{0}']), + ('\u{1e900}', ['\u{1e922}', '\u{0}', '\u{0}']), + ('\u{1e901}', ['\u{1e923}', '\u{0}', '\u{0}']), + ('\u{1e902}', ['\u{1e924}', '\u{0}', '\u{0}']), + ('\u{1e903}', ['\u{1e925}', '\u{0}', '\u{0}']), + ('\u{1e904}', ['\u{1e926}', '\u{0}', '\u{0}']), + ('\u{1e905}', ['\u{1e927}', '\u{0}', '\u{0}']), + ('\u{1e906}', ['\u{1e928}', '\u{0}', '\u{0}']), + ('\u{1e907}', ['\u{1e929}', '\u{0}', '\u{0}']), + ('\u{1e908}', ['\u{1e92a}', '\u{0}', '\u{0}']), + ('\u{1e909}', ['\u{1e92b}', '\u{0}', '\u{0}']), + ('\u{1e90a}', ['\u{1e92c}', '\u{0}', '\u{0}']), + ('\u{1e90b}', ['\u{1e92d}', '\u{0}', '\u{0}']), + ('\u{1e90c}', ['\u{1e92e}', '\u{0}', '\u{0}']), + ('\u{1e90d}', ['\u{1e92f}', '\u{0}', '\u{0}']), + ('\u{1e90e}', ['\u{1e930}', '\u{0}', '\u{0}']), + ('\u{1e90f}', ['\u{1e931}', '\u{0}', '\u{0}']), + ('\u{1e910}', ['\u{1e932}', '\u{0}', '\u{0}']), + ('\u{1e911}', ['\u{1e933}', '\u{0}', '\u{0}']), + ('\u{1e912}', ['\u{1e934}', '\u{0}', '\u{0}']), + ('\u{1e913}', ['\u{1e935}', '\u{0}', '\u{0}']), + ('\u{1e914}', ['\u{1e936}', '\u{0}', '\u{0}']), + ('\u{1e915}', ['\u{1e937}', '\u{0}', '\u{0}']), + ('\u{1e916}', ['\u{1e938}', '\u{0}', '\u{0}']), + ('\u{1e917}', ['\u{1e939}', '\u{0}', '\u{0}']), + ('\u{1e918}', ['\u{1e93a}', '\u{0}', '\u{0}']), + ('\u{1e919}', ['\u{1e93b}', '\u{0}', '\u{0}']), + ('\u{1e91a}', ['\u{1e93c}', '\u{0}', '\u{0}']), + ('\u{1e91b}', ['\u{1e93d}', '\u{0}', '\u{0}']), + ('\u{1e91c}', ['\u{1e93e}', '\u{0}', '\u{0}']), + ('\u{1e91d}', ['\u{1e93f}', '\u{0}', '\u{0}']), + ('\u{1e91e}', ['\u{1e940}', '\u{0}', '\u{0}']), + ('\u{1e91f}', ['\u{1e941}', '\u{0}', '\u{0}']), + ('\u{1e920}', ['\u{1e942}', '\u{0}', '\u{0}']), + ('\u{1e921}', ['\u{1e943}', '\u{0}', '\u{0}']), + ]; + + static UPPERCASE_TABLE: &[(char, [char; 3])] = &[ + ('a', ['A', '\u{0}', '\u{0}']), ('b', ['B', '\u{0}', '\u{0}']), + ('c', ['C', '\u{0}', '\u{0}']), ('d', ['D', '\u{0}', '\u{0}']), + ('e', ['E', '\u{0}', '\u{0}']), ('f', ['F', '\u{0}', '\u{0}']), + ('g', ['G', '\u{0}', '\u{0}']), ('h', ['H', '\u{0}', '\u{0}']), + ('i', ['I', '\u{0}', '\u{0}']), ('j', ['J', '\u{0}', '\u{0}']), + ('k', ['K', '\u{0}', '\u{0}']), ('l', ['L', '\u{0}', '\u{0}']), + ('m', ['M', '\u{0}', '\u{0}']), ('n', ['N', '\u{0}', '\u{0}']), + ('o', ['O', '\u{0}', '\u{0}']), ('p', ['P', '\u{0}', '\u{0}']), + ('q', ['Q', '\u{0}', '\u{0}']), ('r', ['R', '\u{0}', '\u{0}']), + ('s', ['S', '\u{0}', '\u{0}']), ('t', ['T', '\u{0}', '\u{0}']), + ('u', ['U', '\u{0}', '\u{0}']), ('v', ['V', '\u{0}', '\u{0}']), + ('w', ['W', '\u{0}', '\u{0}']), ('x', ['X', '\u{0}', '\u{0}']), + ('y', ['Y', '\u{0}', '\u{0}']), ('z', ['Z', '\u{0}', '\u{0}']), + ('\u{b5}', ['\u{39c}', '\u{0}', '\u{0}']), ('\u{df}', ['S', 'S', '\u{0}']), + ('\u{e0}', ['\u{c0}', '\u{0}', '\u{0}']), ('\u{e1}', ['\u{c1}', '\u{0}', '\u{0}']), + ('\u{e2}', ['\u{c2}', '\u{0}', '\u{0}']), ('\u{e3}', ['\u{c3}', '\u{0}', '\u{0}']), + ('\u{e4}', ['\u{c4}', '\u{0}', '\u{0}']), ('\u{e5}', ['\u{c5}', '\u{0}', '\u{0}']), + ('\u{e6}', ['\u{c6}', '\u{0}', '\u{0}']), ('\u{e7}', ['\u{c7}', '\u{0}', '\u{0}']), + ('\u{e8}', ['\u{c8}', '\u{0}', '\u{0}']), ('\u{e9}', ['\u{c9}', '\u{0}', '\u{0}']), + ('\u{ea}', ['\u{ca}', '\u{0}', '\u{0}']), ('\u{eb}', ['\u{cb}', '\u{0}', '\u{0}']), + ('\u{ec}', ['\u{cc}', '\u{0}', '\u{0}']), ('\u{ed}', ['\u{cd}', '\u{0}', '\u{0}']), + ('\u{ee}', ['\u{ce}', '\u{0}', '\u{0}']), ('\u{ef}', ['\u{cf}', '\u{0}', '\u{0}']), + ('\u{f0}', ['\u{d0}', '\u{0}', '\u{0}']), ('\u{f1}', ['\u{d1}', '\u{0}', '\u{0}']), + ('\u{f2}', ['\u{d2}', '\u{0}', '\u{0}']), ('\u{f3}', ['\u{d3}', '\u{0}', '\u{0}']), + ('\u{f4}', ['\u{d4}', '\u{0}', '\u{0}']), ('\u{f5}', ['\u{d5}', '\u{0}', '\u{0}']), + ('\u{f6}', ['\u{d6}', '\u{0}', '\u{0}']), ('\u{f8}', ['\u{d8}', '\u{0}', '\u{0}']), + ('\u{f9}', ['\u{d9}', '\u{0}', '\u{0}']), ('\u{fa}', ['\u{da}', '\u{0}', '\u{0}']), + ('\u{fb}', ['\u{db}', '\u{0}', '\u{0}']), ('\u{fc}', ['\u{dc}', '\u{0}', '\u{0}']), + ('\u{fd}', ['\u{dd}', '\u{0}', '\u{0}']), ('\u{fe}', ['\u{de}', '\u{0}', '\u{0}']), + ('\u{ff}', ['\u{178}', '\u{0}', '\u{0}']), ('\u{101}', ['\u{100}', '\u{0}', '\u{0}']), + ('\u{103}', ['\u{102}', '\u{0}', '\u{0}']), ('\u{105}', ['\u{104}', '\u{0}', '\u{0}']), + ('\u{107}', ['\u{106}', '\u{0}', '\u{0}']), ('\u{109}', ['\u{108}', '\u{0}', '\u{0}']), + ('\u{10b}', ['\u{10a}', '\u{0}', '\u{0}']), ('\u{10d}', ['\u{10c}', '\u{0}', '\u{0}']), + ('\u{10f}', ['\u{10e}', '\u{0}', '\u{0}']), ('\u{111}', ['\u{110}', '\u{0}', '\u{0}']), + ('\u{113}', ['\u{112}', '\u{0}', '\u{0}']), ('\u{115}', ['\u{114}', '\u{0}', '\u{0}']), + ('\u{117}', ['\u{116}', '\u{0}', '\u{0}']), ('\u{119}', ['\u{118}', '\u{0}', '\u{0}']), + ('\u{11b}', ['\u{11a}', '\u{0}', '\u{0}']), ('\u{11d}', ['\u{11c}', '\u{0}', '\u{0}']), + ('\u{11f}', ['\u{11e}', '\u{0}', '\u{0}']), ('\u{121}', ['\u{120}', '\u{0}', '\u{0}']), + ('\u{123}', ['\u{122}', '\u{0}', '\u{0}']), ('\u{125}', ['\u{124}', '\u{0}', '\u{0}']), + ('\u{127}', ['\u{126}', '\u{0}', '\u{0}']), ('\u{129}', ['\u{128}', '\u{0}', '\u{0}']), + ('\u{12b}', ['\u{12a}', '\u{0}', '\u{0}']), ('\u{12d}', ['\u{12c}', '\u{0}', '\u{0}']), + ('\u{12f}', ['\u{12e}', '\u{0}', '\u{0}']), ('\u{131}', ['I', '\u{0}', '\u{0}']), + ('\u{133}', ['\u{132}', '\u{0}', '\u{0}']), ('\u{135}', ['\u{134}', '\u{0}', '\u{0}']), + ('\u{137}', ['\u{136}', '\u{0}', '\u{0}']), ('\u{13a}', ['\u{139}', '\u{0}', '\u{0}']), + ('\u{13c}', ['\u{13b}', '\u{0}', '\u{0}']), ('\u{13e}', ['\u{13d}', '\u{0}', '\u{0}']), + ('\u{140}', ['\u{13f}', '\u{0}', '\u{0}']), ('\u{142}', ['\u{141}', '\u{0}', '\u{0}']), + ('\u{144}', ['\u{143}', '\u{0}', '\u{0}']), ('\u{146}', ['\u{145}', '\u{0}', '\u{0}']), + ('\u{148}', ['\u{147}', '\u{0}', '\u{0}']), ('\u{149}', ['\u{2bc}', 'N', '\u{0}']), + ('\u{14b}', ['\u{14a}', '\u{0}', '\u{0}']), ('\u{14d}', ['\u{14c}', '\u{0}', '\u{0}']), + ('\u{14f}', ['\u{14e}', '\u{0}', '\u{0}']), ('\u{151}', ['\u{150}', '\u{0}', '\u{0}']), + ('\u{153}', ['\u{152}', '\u{0}', '\u{0}']), ('\u{155}', ['\u{154}', '\u{0}', '\u{0}']), + ('\u{157}', ['\u{156}', '\u{0}', '\u{0}']), ('\u{159}', ['\u{158}', '\u{0}', '\u{0}']), + ('\u{15b}', ['\u{15a}', '\u{0}', '\u{0}']), ('\u{15d}', ['\u{15c}', '\u{0}', '\u{0}']), + ('\u{15f}', ['\u{15e}', '\u{0}', '\u{0}']), ('\u{161}', ['\u{160}', '\u{0}', '\u{0}']), + ('\u{163}', ['\u{162}', '\u{0}', '\u{0}']), ('\u{165}', ['\u{164}', '\u{0}', '\u{0}']), + ('\u{167}', ['\u{166}', '\u{0}', '\u{0}']), ('\u{169}', ['\u{168}', '\u{0}', '\u{0}']), + ('\u{16b}', ['\u{16a}', '\u{0}', '\u{0}']), ('\u{16d}', ['\u{16c}', '\u{0}', '\u{0}']), + ('\u{16f}', ['\u{16e}', '\u{0}', '\u{0}']), ('\u{171}', ['\u{170}', '\u{0}', '\u{0}']), + ('\u{173}', ['\u{172}', '\u{0}', '\u{0}']), ('\u{175}', ['\u{174}', '\u{0}', '\u{0}']), + ('\u{177}', ['\u{176}', '\u{0}', '\u{0}']), ('\u{17a}', ['\u{179}', '\u{0}', '\u{0}']), + ('\u{17c}', ['\u{17b}', '\u{0}', '\u{0}']), ('\u{17e}', ['\u{17d}', '\u{0}', '\u{0}']), + ('\u{17f}', ['S', '\u{0}', '\u{0}']), ('\u{180}', ['\u{243}', '\u{0}', '\u{0}']), + ('\u{183}', ['\u{182}', '\u{0}', '\u{0}']), ('\u{185}', ['\u{184}', '\u{0}', '\u{0}']), + ('\u{188}', ['\u{187}', '\u{0}', '\u{0}']), ('\u{18c}', ['\u{18b}', '\u{0}', '\u{0}']), + ('\u{192}', ['\u{191}', '\u{0}', '\u{0}']), ('\u{195}', ['\u{1f6}', '\u{0}', '\u{0}']), + ('\u{199}', ['\u{198}', '\u{0}', '\u{0}']), ('\u{19a}', ['\u{23d}', '\u{0}', '\u{0}']), + ('\u{19e}', ['\u{220}', '\u{0}', '\u{0}']), ('\u{1a1}', ['\u{1a0}', '\u{0}', '\u{0}']), + ('\u{1a3}', ['\u{1a2}', '\u{0}', '\u{0}']), ('\u{1a5}', ['\u{1a4}', '\u{0}', '\u{0}']), + ('\u{1a8}', ['\u{1a7}', '\u{0}', '\u{0}']), ('\u{1ad}', ['\u{1ac}', '\u{0}', '\u{0}']), + ('\u{1b0}', ['\u{1af}', '\u{0}', '\u{0}']), ('\u{1b4}', ['\u{1b3}', '\u{0}', '\u{0}']), + ('\u{1b6}', ['\u{1b5}', '\u{0}', '\u{0}']), ('\u{1b9}', ['\u{1b8}', '\u{0}', '\u{0}']), + ('\u{1bd}', ['\u{1bc}', '\u{0}', '\u{0}']), ('\u{1bf}', ['\u{1f7}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c4}', '\u{0}', '\u{0}']), ('\u{1c6}', ['\u{1c4}', '\u{0}', '\u{0}']), + ('\u{1c8}', ['\u{1c7}', '\u{0}', '\u{0}']), ('\u{1c9}', ['\u{1c7}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1ca}', '\u{0}', '\u{0}']), ('\u{1cc}', ['\u{1ca}', '\u{0}', '\u{0}']), + ('\u{1ce}', ['\u{1cd}', '\u{0}', '\u{0}']), ('\u{1d0}', ['\u{1cf}', '\u{0}', '\u{0}']), + ('\u{1d2}', ['\u{1d1}', '\u{0}', '\u{0}']), ('\u{1d4}', ['\u{1d3}', '\u{0}', '\u{0}']), + ('\u{1d6}', ['\u{1d5}', '\u{0}', '\u{0}']), ('\u{1d8}', ['\u{1d7}', '\u{0}', '\u{0}']), + ('\u{1da}', ['\u{1d9}', '\u{0}', '\u{0}']), ('\u{1dc}', ['\u{1db}', '\u{0}', '\u{0}']), + ('\u{1dd}', ['\u{18e}', '\u{0}', '\u{0}']), ('\u{1df}', ['\u{1de}', '\u{0}', '\u{0}']), + ('\u{1e1}', ['\u{1e0}', '\u{0}', '\u{0}']), ('\u{1e3}', ['\u{1e2}', '\u{0}', '\u{0}']), + ('\u{1e5}', ['\u{1e4}', '\u{0}', '\u{0}']), ('\u{1e7}', ['\u{1e6}', '\u{0}', '\u{0}']), + ('\u{1e9}', ['\u{1e8}', '\u{0}', '\u{0}']), ('\u{1eb}', ['\u{1ea}', '\u{0}', '\u{0}']), + ('\u{1ed}', ['\u{1ec}', '\u{0}', '\u{0}']), ('\u{1ef}', ['\u{1ee}', '\u{0}', '\u{0}']), + ('\u{1f0}', ['J', '\u{30c}', '\u{0}']), ('\u{1f2}', ['\u{1f1}', '\u{0}', '\u{0}']), + ('\u{1f3}', ['\u{1f1}', '\u{0}', '\u{0}']), ('\u{1f5}', ['\u{1f4}', '\u{0}', '\u{0}']), + ('\u{1f9}', ['\u{1f8}', '\u{0}', '\u{0}']), ('\u{1fb}', ['\u{1fa}', '\u{0}', '\u{0}']), + ('\u{1fd}', ['\u{1fc}', '\u{0}', '\u{0}']), ('\u{1ff}', ['\u{1fe}', '\u{0}', '\u{0}']), + ('\u{201}', ['\u{200}', '\u{0}', '\u{0}']), ('\u{203}', ['\u{202}', '\u{0}', '\u{0}']), + ('\u{205}', ['\u{204}', '\u{0}', '\u{0}']), ('\u{207}', ['\u{206}', '\u{0}', '\u{0}']), + ('\u{209}', ['\u{208}', '\u{0}', '\u{0}']), ('\u{20b}', ['\u{20a}', '\u{0}', '\u{0}']), + ('\u{20d}', ['\u{20c}', '\u{0}', '\u{0}']), ('\u{20f}', ['\u{20e}', '\u{0}', '\u{0}']), + ('\u{211}', ['\u{210}', '\u{0}', '\u{0}']), ('\u{213}', ['\u{212}', '\u{0}', '\u{0}']), + ('\u{215}', ['\u{214}', '\u{0}', '\u{0}']), ('\u{217}', ['\u{216}', '\u{0}', '\u{0}']), + ('\u{219}', ['\u{218}', '\u{0}', '\u{0}']), ('\u{21b}', ['\u{21a}', '\u{0}', '\u{0}']), + ('\u{21d}', ['\u{21c}', '\u{0}', '\u{0}']), ('\u{21f}', ['\u{21e}', '\u{0}', '\u{0}']), + ('\u{223}', ['\u{222}', '\u{0}', '\u{0}']), ('\u{225}', ['\u{224}', '\u{0}', '\u{0}']), + ('\u{227}', ['\u{226}', '\u{0}', '\u{0}']), ('\u{229}', ['\u{228}', '\u{0}', '\u{0}']), + ('\u{22b}', ['\u{22a}', '\u{0}', '\u{0}']), ('\u{22d}', ['\u{22c}', '\u{0}', '\u{0}']), + ('\u{22f}', ['\u{22e}', '\u{0}', '\u{0}']), ('\u{231}', ['\u{230}', '\u{0}', '\u{0}']), + ('\u{233}', ['\u{232}', '\u{0}', '\u{0}']), ('\u{23c}', ['\u{23b}', '\u{0}', '\u{0}']), + ('\u{23f}', ['\u{2c7e}', '\u{0}', '\u{0}']), ('\u{240}', ['\u{2c7f}', '\u{0}', '\u{0}']), + ('\u{242}', ['\u{241}', '\u{0}', '\u{0}']), ('\u{247}', ['\u{246}', '\u{0}', '\u{0}']), + ('\u{249}', ['\u{248}', '\u{0}', '\u{0}']), ('\u{24b}', ['\u{24a}', '\u{0}', '\u{0}']), + ('\u{24d}', ['\u{24c}', '\u{0}', '\u{0}']), ('\u{24f}', ['\u{24e}', '\u{0}', '\u{0}']), + ('\u{250}', ['\u{2c6f}', '\u{0}', '\u{0}']), ('\u{251}', ['\u{2c6d}', '\u{0}', '\u{0}']), + ('\u{252}', ['\u{2c70}', '\u{0}', '\u{0}']), ('\u{253}', ['\u{181}', '\u{0}', '\u{0}']), + ('\u{254}', ['\u{186}', '\u{0}', '\u{0}']), ('\u{256}', ['\u{189}', '\u{0}', '\u{0}']), + ('\u{257}', ['\u{18a}', '\u{0}', '\u{0}']), ('\u{259}', ['\u{18f}', '\u{0}', '\u{0}']), + ('\u{25b}', ['\u{190}', '\u{0}', '\u{0}']), ('\u{25c}', ['\u{a7ab}', '\u{0}', '\u{0}']), + ('\u{260}', ['\u{193}', '\u{0}', '\u{0}']), ('\u{261}', ['\u{a7ac}', '\u{0}', '\u{0}']), + ('\u{263}', ['\u{194}', '\u{0}', '\u{0}']), ('\u{265}', ['\u{a78d}', '\u{0}', '\u{0}']), + ('\u{266}', ['\u{a7aa}', '\u{0}', '\u{0}']), ('\u{268}', ['\u{197}', '\u{0}', '\u{0}']), + ('\u{269}', ['\u{196}', '\u{0}', '\u{0}']), ('\u{26a}', ['\u{a7ae}', '\u{0}', '\u{0}']), + ('\u{26b}', ['\u{2c62}', '\u{0}', '\u{0}']), ('\u{26c}', ['\u{a7ad}', '\u{0}', '\u{0}']), + ('\u{26f}', ['\u{19c}', '\u{0}', '\u{0}']), ('\u{271}', ['\u{2c6e}', '\u{0}', '\u{0}']), + ('\u{272}', ['\u{19d}', '\u{0}', '\u{0}']), ('\u{275}', ['\u{19f}', '\u{0}', '\u{0}']), + ('\u{27d}', ['\u{2c64}', '\u{0}', '\u{0}']), ('\u{280}', ['\u{1a6}', '\u{0}', '\u{0}']), + ('\u{282}', ['\u{a7c5}', '\u{0}', '\u{0}']), ('\u{283}', ['\u{1a9}', '\u{0}', '\u{0}']), + ('\u{287}', ['\u{a7b1}', '\u{0}', '\u{0}']), ('\u{288}', ['\u{1ae}', '\u{0}', '\u{0}']), + ('\u{289}', ['\u{244}', '\u{0}', '\u{0}']), ('\u{28a}', ['\u{1b1}', '\u{0}', '\u{0}']), + ('\u{28b}', ['\u{1b2}', '\u{0}', '\u{0}']), ('\u{28c}', ['\u{245}', '\u{0}', '\u{0}']), + ('\u{292}', ['\u{1b7}', '\u{0}', '\u{0}']), ('\u{29d}', ['\u{a7b2}', '\u{0}', '\u{0}']), + ('\u{29e}', ['\u{a7b0}', '\u{0}', '\u{0}']), ('\u{345}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{371}', ['\u{370}', '\u{0}', '\u{0}']), ('\u{373}', ['\u{372}', '\u{0}', '\u{0}']), + ('\u{377}', ['\u{376}', '\u{0}', '\u{0}']), ('\u{37b}', ['\u{3fd}', '\u{0}', '\u{0}']), + ('\u{37c}', ['\u{3fe}', '\u{0}', '\u{0}']), ('\u{37d}', ['\u{3ff}', '\u{0}', '\u{0}']), + ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\u{0}', '\u{0}']), + ('\u{3ad}', ['\u{388}', '\u{0}', '\u{0}']), ('\u{3ae}', ['\u{389}', '\u{0}', '\u{0}']), + ('\u{3af}', ['\u{38a}', '\u{0}', '\u{0}']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{3b1}', ['\u{391}', '\u{0}', '\u{0}']), ('\u{3b2}', ['\u{392}', '\u{0}', '\u{0}']), + ('\u{3b3}', ['\u{393}', '\u{0}', '\u{0}']), ('\u{3b4}', ['\u{394}', '\u{0}', '\u{0}']), + ('\u{3b5}', ['\u{395}', '\u{0}', '\u{0}']), ('\u{3b6}', ['\u{396}', '\u{0}', '\u{0}']), + ('\u{3b7}', ['\u{397}', '\u{0}', '\u{0}']), ('\u{3b8}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3b9}', ['\u{399}', '\u{0}', '\u{0}']), ('\u{3ba}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3bb}', ['\u{39b}', '\u{0}', '\u{0}']), ('\u{3bc}', ['\u{39c}', '\u{0}', '\u{0}']), + ('\u{3bd}', ['\u{39d}', '\u{0}', '\u{0}']), ('\u{3be}', ['\u{39e}', '\u{0}', '\u{0}']), + ('\u{3bf}', ['\u{39f}', '\u{0}', '\u{0}']), ('\u{3c0}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3c1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3c2}', ['\u{3a3}', '\u{0}', '\u{0}']), + ('\u{3c3}', ['\u{3a3}', '\u{0}', '\u{0}']), ('\u{3c4}', ['\u{3a4}', '\u{0}', '\u{0}']), + ('\u{3c5}', ['\u{3a5}', '\u{0}', '\u{0}']), ('\u{3c6}', ['\u{3a6}', '\u{0}', '\u{0}']), + ('\u{3c7}', ['\u{3a7}', '\u{0}', '\u{0}']), ('\u{3c8}', ['\u{3a8}', '\u{0}', '\u{0}']), + ('\u{3c9}', ['\u{3a9}', '\u{0}', '\u{0}']), ('\u{3ca}', ['\u{3aa}', '\u{0}', '\u{0}']), + ('\u{3cb}', ['\u{3ab}', '\u{0}', '\u{0}']), ('\u{3cc}', ['\u{38c}', '\u{0}', '\u{0}']), + ('\u{3cd}', ['\u{38e}', '\u{0}', '\u{0}']), ('\u{3ce}', ['\u{38f}', '\u{0}', '\u{0}']), + ('\u{3d0}', ['\u{392}', '\u{0}', '\u{0}']), ('\u{3d1}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3d5}', ['\u{3a6}', '\u{0}', '\u{0}']), ('\u{3d6}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3d7}', ['\u{3cf}', '\u{0}', '\u{0}']), ('\u{3d9}', ['\u{3d8}', '\u{0}', '\u{0}']), + ('\u{3db}', ['\u{3da}', '\u{0}', '\u{0}']), ('\u{3dd}', ['\u{3dc}', '\u{0}', '\u{0}']), + ('\u{3df}', ['\u{3de}', '\u{0}', '\u{0}']), ('\u{3e1}', ['\u{3e0}', '\u{0}', '\u{0}']), + ('\u{3e3}', ['\u{3e2}', '\u{0}', '\u{0}']), ('\u{3e5}', ['\u{3e4}', '\u{0}', '\u{0}']), + ('\u{3e7}', ['\u{3e6}', '\u{0}', '\u{0}']), ('\u{3e9}', ['\u{3e8}', '\u{0}', '\u{0}']), + ('\u{3eb}', ['\u{3ea}', '\u{0}', '\u{0}']), ('\u{3ed}', ['\u{3ec}', '\u{0}', '\u{0}']), + ('\u{3ef}', ['\u{3ee}', '\u{0}', '\u{0}']), ('\u{3f0}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3f1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3f2}', ['\u{3f9}', '\u{0}', '\u{0}']), + ('\u{3f3}', ['\u{37f}', '\u{0}', '\u{0}']), ('\u{3f5}', ['\u{395}', '\u{0}', '\u{0}']), + ('\u{3f8}', ['\u{3f7}', '\u{0}', '\u{0}']), ('\u{3fb}', ['\u{3fa}', '\u{0}', '\u{0}']), + ('\u{430}', ['\u{410}', '\u{0}', '\u{0}']), ('\u{431}', ['\u{411}', '\u{0}', '\u{0}']), + ('\u{432}', ['\u{412}', '\u{0}', '\u{0}']), ('\u{433}', ['\u{413}', '\u{0}', '\u{0}']), + ('\u{434}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{435}', ['\u{415}', '\u{0}', '\u{0}']), + ('\u{436}', ['\u{416}', '\u{0}', '\u{0}']), ('\u{437}', ['\u{417}', '\u{0}', '\u{0}']), + ('\u{438}', ['\u{418}', '\u{0}', '\u{0}']), ('\u{439}', ['\u{419}', '\u{0}', '\u{0}']), + ('\u{43a}', ['\u{41a}', '\u{0}', '\u{0}']), ('\u{43b}', ['\u{41b}', '\u{0}', '\u{0}']), + ('\u{43c}', ['\u{41c}', '\u{0}', '\u{0}']), ('\u{43d}', ['\u{41d}', '\u{0}', '\u{0}']), + ('\u{43e}', ['\u{41e}', '\u{0}', '\u{0}']), ('\u{43f}', ['\u{41f}', '\u{0}', '\u{0}']), + ('\u{440}', ['\u{420}', '\u{0}', '\u{0}']), ('\u{441}', ['\u{421}', '\u{0}', '\u{0}']), + ('\u{442}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{443}', ['\u{423}', '\u{0}', '\u{0}']), + ('\u{444}', ['\u{424}', '\u{0}', '\u{0}']), ('\u{445}', ['\u{425}', '\u{0}', '\u{0}']), + ('\u{446}', ['\u{426}', '\u{0}', '\u{0}']), ('\u{447}', ['\u{427}', '\u{0}', '\u{0}']), + ('\u{448}', ['\u{428}', '\u{0}', '\u{0}']), ('\u{449}', ['\u{429}', '\u{0}', '\u{0}']), + ('\u{44a}', ['\u{42a}', '\u{0}', '\u{0}']), ('\u{44b}', ['\u{42b}', '\u{0}', '\u{0}']), + ('\u{44c}', ['\u{42c}', '\u{0}', '\u{0}']), ('\u{44d}', ['\u{42d}', '\u{0}', '\u{0}']), + ('\u{44e}', ['\u{42e}', '\u{0}', '\u{0}']), ('\u{44f}', ['\u{42f}', '\u{0}', '\u{0}']), + ('\u{450}', ['\u{400}', '\u{0}', '\u{0}']), ('\u{451}', ['\u{401}', '\u{0}', '\u{0}']), + ('\u{452}', ['\u{402}', '\u{0}', '\u{0}']), ('\u{453}', ['\u{403}', '\u{0}', '\u{0}']), + ('\u{454}', ['\u{404}', '\u{0}', '\u{0}']), ('\u{455}', ['\u{405}', '\u{0}', '\u{0}']), + ('\u{456}', ['\u{406}', '\u{0}', '\u{0}']), ('\u{457}', ['\u{407}', '\u{0}', '\u{0}']), + ('\u{458}', ['\u{408}', '\u{0}', '\u{0}']), ('\u{459}', ['\u{409}', '\u{0}', '\u{0}']), + ('\u{45a}', ['\u{40a}', '\u{0}', '\u{0}']), ('\u{45b}', ['\u{40b}', '\u{0}', '\u{0}']), + ('\u{45c}', ['\u{40c}', '\u{0}', '\u{0}']), ('\u{45d}', ['\u{40d}', '\u{0}', '\u{0}']), + ('\u{45e}', ['\u{40e}', '\u{0}', '\u{0}']), ('\u{45f}', ['\u{40f}', '\u{0}', '\u{0}']), + ('\u{461}', ['\u{460}', '\u{0}', '\u{0}']), ('\u{463}', ['\u{462}', '\u{0}', '\u{0}']), + ('\u{465}', ['\u{464}', '\u{0}', '\u{0}']), ('\u{467}', ['\u{466}', '\u{0}', '\u{0}']), + ('\u{469}', ['\u{468}', '\u{0}', '\u{0}']), ('\u{46b}', ['\u{46a}', '\u{0}', '\u{0}']), + ('\u{46d}', ['\u{46c}', '\u{0}', '\u{0}']), ('\u{46f}', ['\u{46e}', '\u{0}', '\u{0}']), + ('\u{471}', ['\u{470}', '\u{0}', '\u{0}']), ('\u{473}', ['\u{472}', '\u{0}', '\u{0}']), + ('\u{475}', ['\u{474}', '\u{0}', '\u{0}']), ('\u{477}', ['\u{476}', '\u{0}', '\u{0}']), + ('\u{479}', ['\u{478}', '\u{0}', '\u{0}']), ('\u{47b}', ['\u{47a}', '\u{0}', '\u{0}']), + ('\u{47d}', ['\u{47c}', '\u{0}', '\u{0}']), ('\u{47f}', ['\u{47e}', '\u{0}', '\u{0}']), + ('\u{481}', ['\u{480}', '\u{0}', '\u{0}']), ('\u{48b}', ['\u{48a}', '\u{0}', '\u{0}']), + ('\u{48d}', ['\u{48c}', '\u{0}', '\u{0}']), ('\u{48f}', ['\u{48e}', '\u{0}', '\u{0}']), + ('\u{491}', ['\u{490}', '\u{0}', '\u{0}']), ('\u{493}', ['\u{492}', '\u{0}', '\u{0}']), + ('\u{495}', ['\u{494}', '\u{0}', '\u{0}']), ('\u{497}', ['\u{496}', '\u{0}', '\u{0}']), + ('\u{499}', ['\u{498}', '\u{0}', '\u{0}']), ('\u{49b}', ['\u{49a}', '\u{0}', '\u{0}']), + ('\u{49d}', ['\u{49c}', '\u{0}', '\u{0}']), ('\u{49f}', ['\u{49e}', '\u{0}', '\u{0}']), + ('\u{4a1}', ['\u{4a0}', '\u{0}', '\u{0}']), ('\u{4a3}', ['\u{4a2}', '\u{0}', '\u{0}']), + ('\u{4a5}', ['\u{4a4}', '\u{0}', '\u{0}']), ('\u{4a7}', ['\u{4a6}', '\u{0}', '\u{0}']), + ('\u{4a9}', ['\u{4a8}', '\u{0}', '\u{0}']), ('\u{4ab}', ['\u{4aa}', '\u{0}', '\u{0}']), + ('\u{4ad}', ['\u{4ac}', '\u{0}', '\u{0}']), ('\u{4af}', ['\u{4ae}', '\u{0}', '\u{0}']), + ('\u{4b1}', ['\u{4b0}', '\u{0}', '\u{0}']), ('\u{4b3}', ['\u{4b2}', '\u{0}', '\u{0}']), + ('\u{4b5}', ['\u{4b4}', '\u{0}', '\u{0}']), ('\u{4b7}', ['\u{4b6}', '\u{0}', '\u{0}']), + ('\u{4b9}', ['\u{4b8}', '\u{0}', '\u{0}']), ('\u{4bb}', ['\u{4ba}', '\u{0}', '\u{0}']), + ('\u{4bd}', ['\u{4bc}', '\u{0}', '\u{0}']), ('\u{4bf}', ['\u{4be}', '\u{0}', '\u{0}']), + ('\u{4c2}', ['\u{4c1}', '\u{0}', '\u{0}']), ('\u{4c4}', ['\u{4c3}', '\u{0}', '\u{0}']), + ('\u{4c6}', ['\u{4c5}', '\u{0}', '\u{0}']), ('\u{4c8}', ['\u{4c7}', '\u{0}', '\u{0}']), + ('\u{4ca}', ['\u{4c9}', '\u{0}', '\u{0}']), ('\u{4cc}', ['\u{4cb}', '\u{0}', '\u{0}']), + ('\u{4ce}', ['\u{4cd}', '\u{0}', '\u{0}']), ('\u{4cf}', ['\u{4c0}', '\u{0}', '\u{0}']), + ('\u{4d1}', ['\u{4d0}', '\u{0}', '\u{0}']), ('\u{4d3}', ['\u{4d2}', '\u{0}', '\u{0}']), + ('\u{4d5}', ['\u{4d4}', '\u{0}', '\u{0}']), ('\u{4d7}', ['\u{4d6}', '\u{0}', '\u{0}']), + ('\u{4d9}', ['\u{4d8}', '\u{0}', '\u{0}']), ('\u{4db}', ['\u{4da}', '\u{0}', '\u{0}']), + ('\u{4dd}', ['\u{4dc}', '\u{0}', '\u{0}']), ('\u{4df}', ['\u{4de}', '\u{0}', '\u{0}']), + ('\u{4e1}', ['\u{4e0}', '\u{0}', '\u{0}']), ('\u{4e3}', ['\u{4e2}', '\u{0}', '\u{0}']), + ('\u{4e5}', ['\u{4e4}', '\u{0}', '\u{0}']), ('\u{4e7}', ['\u{4e6}', '\u{0}', '\u{0}']), + ('\u{4e9}', ['\u{4e8}', '\u{0}', '\u{0}']), ('\u{4eb}', ['\u{4ea}', '\u{0}', '\u{0}']), + ('\u{4ed}', ['\u{4ec}', '\u{0}', '\u{0}']), ('\u{4ef}', ['\u{4ee}', '\u{0}', '\u{0}']), + ('\u{4f1}', ['\u{4f0}', '\u{0}', '\u{0}']), ('\u{4f3}', ['\u{4f2}', '\u{0}', '\u{0}']), + ('\u{4f5}', ['\u{4f4}', '\u{0}', '\u{0}']), ('\u{4f7}', ['\u{4f6}', '\u{0}', '\u{0}']), + ('\u{4f9}', ['\u{4f8}', '\u{0}', '\u{0}']), ('\u{4fb}', ['\u{4fa}', '\u{0}', '\u{0}']), + ('\u{4fd}', ['\u{4fc}', '\u{0}', '\u{0}']), ('\u{4ff}', ['\u{4fe}', '\u{0}', '\u{0}']), + ('\u{501}', ['\u{500}', '\u{0}', '\u{0}']), ('\u{503}', ['\u{502}', '\u{0}', '\u{0}']), + ('\u{505}', ['\u{504}', '\u{0}', '\u{0}']), ('\u{507}', ['\u{506}', '\u{0}', '\u{0}']), + ('\u{509}', ['\u{508}', '\u{0}', '\u{0}']), ('\u{50b}', ['\u{50a}', '\u{0}', '\u{0}']), + ('\u{50d}', ['\u{50c}', '\u{0}', '\u{0}']), ('\u{50f}', ['\u{50e}', '\u{0}', '\u{0}']), + ('\u{511}', ['\u{510}', '\u{0}', '\u{0}']), ('\u{513}', ['\u{512}', '\u{0}', '\u{0}']), + ('\u{515}', ['\u{514}', '\u{0}', '\u{0}']), ('\u{517}', ['\u{516}', '\u{0}', '\u{0}']), + ('\u{519}', ['\u{518}', '\u{0}', '\u{0}']), ('\u{51b}', ['\u{51a}', '\u{0}', '\u{0}']), + ('\u{51d}', ['\u{51c}', '\u{0}', '\u{0}']), ('\u{51f}', ['\u{51e}', '\u{0}', '\u{0}']), + ('\u{521}', ['\u{520}', '\u{0}', '\u{0}']), ('\u{523}', ['\u{522}', '\u{0}', '\u{0}']), + ('\u{525}', ['\u{524}', '\u{0}', '\u{0}']), ('\u{527}', ['\u{526}', '\u{0}', '\u{0}']), + ('\u{529}', ['\u{528}', '\u{0}', '\u{0}']), ('\u{52b}', ['\u{52a}', '\u{0}', '\u{0}']), + ('\u{52d}', ['\u{52c}', '\u{0}', '\u{0}']), ('\u{52f}', ['\u{52e}', '\u{0}', '\u{0}']), + ('\u{561}', ['\u{531}', '\u{0}', '\u{0}']), ('\u{562}', ['\u{532}', '\u{0}', '\u{0}']), + ('\u{563}', ['\u{533}', '\u{0}', '\u{0}']), ('\u{564}', ['\u{534}', '\u{0}', '\u{0}']), + ('\u{565}', ['\u{535}', '\u{0}', '\u{0}']), ('\u{566}', ['\u{536}', '\u{0}', '\u{0}']), + ('\u{567}', ['\u{537}', '\u{0}', '\u{0}']), ('\u{568}', ['\u{538}', '\u{0}', '\u{0}']), + ('\u{569}', ['\u{539}', '\u{0}', '\u{0}']), ('\u{56a}', ['\u{53a}', '\u{0}', '\u{0}']), + ('\u{56b}', ['\u{53b}', '\u{0}', '\u{0}']), ('\u{56c}', ['\u{53c}', '\u{0}', '\u{0}']), + ('\u{56d}', ['\u{53d}', '\u{0}', '\u{0}']), ('\u{56e}', ['\u{53e}', '\u{0}', '\u{0}']), + ('\u{56f}', ['\u{53f}', '\u{0}', '\u{0}']), ('\u{570}', ['\u{540}', '\u{0}', '\u{0}']), + ('\u{571}', ['\u{541}', '\u{0}', '\u{0}']), ('\u{572}', ['\u{542}', '\u{0}', '\u{0}']), + ('\u{573}', ['\u{543}', '\u{0}', '\u{0}']), ('\u{574}', ['\u{544}', '\u{0}', '\u{0}']), + ('\u{575}', ['\u{545}', '\u{0}', '\u{0}']), ('\u{576}', ['\u{546}', '\u{0}', '\u{0}']), + ('\u{577}', ['\u{547}', '\u{0}', '\u{0}']), ('\u{578}', ['\u{548}', '\u{0}', '\u{0}']), + ('\u{579}', ['\u{549}', '\u{0}', '\u{0}']), ('\u{57a}', ['\u{54a}', '\u{0}', '\u{0}']), + ('\u{57b}', ['\u{54b}', '\u{0}', '\u{0}']), ('\u{57c}', ['\u{54c}', '\u{0}', '\u{0}']), + ('\u{57d}', ['\u{54d}', '\u{0}', '\u{0}']), ('\u{57e}', ['\u{54e}', '\u{0}', '\u{0}']), + ('\u{57f}', ['\u{54f}', '\u{0}', '\u{0}']), ('\u{580}', ['\u{550}', '\u{0}', '\u{0}']), + ('\u{581}', ['\u{551}', '\u{0}', '\u{0}']), ('\u{582}', ['\u{552}', '\u{0}', '\u{0}']), + ('\u{583}', ['\u{553}', '\u{0}', '\u{0}']), ('\u{584}', ['\u{554}', '\u{0}', '\u{0}']), + ('\u{585}', ['\u{555}', '\u{0}', '\u{0}']), ('\u{586}', ['\u{556}', '\u{0}', '\u{0}']), + ('\u{587}', ['\u{535}', '\u{552}', '\u{0}']), ('\u{10d0}', ['\u{1c90}', '\u{0}', '\u{0}']), + ('\u{10d1}', ['\u{1c91}', '\u{0}', '\u{0}']), ('\u{10d2}', ['\u{1c92}', '\u{0}', '\u{0}']), + ('\u{10d3}', ['\u{1c93}', '\u{0}', '\u{0}']), ('\u{10d4}', ['\u{1c94}', '\u{0}', '\u{0}']), + ('\u{10d5}', ['\u{1c95}', '\u{0}', '\u{0}']), ('\u{10d6}', ['\u{1c96}', '\u{0}', '\u{0}']), + ('\u{10d7}', ['\u{1c97}', '\u{0}', '\u{0}']), ('\u{10d8}', ['\u{1c98}', '\u{0}', '\u{0}']), + ('\u{10d9}', ['\u{1c99}', '\u{0}', '\u{0}']), ('\u{10da}', ['\u{1c9a}', '\u{0}', '\u{0}']), + ('\u{10db}', ['\u{1c9b}', '\u{0}', '\u{0}']), ('\u{10dc}', ['\u{1c9c}', '\u{0}', '\u{0}']), + ('\u{10dd}', ['\u{1c9d}', '\u{0}', '\u{0}']), ('\u{10de}', ['\u{1c9e}', '\u{0}', '\u{0}']), + ('\u{10df}', ['\u{1c9f}', '\u{0}', '\u{0}']), ('\u{10e0}', ['\u{1ca0}', '\u{0}', '\u{0}']), + ('\u{10e1}', ['\u{1ca1}', '\u{0}', '\u{0}']), ('\u{10e2}', ['\u{1ca2}', '\u{0}', '\u{0}']), + ('\u{10e3}', ['\u{1ca3}', '\u{0}', '\u{0}']), ('\u{10e4}', ['\u{1ca4}', '\u{0}', '\u{0}']), + ('\u{10e5}', ['\u{1ca5}', '\u{0}', '\u{0}']), ('\u{10e6}', ['\u{1ca6}', '\u{0}', '\u{0}']), + ('\u{10e7}', ['\u{1ca7}', '\u{0}', '\u{0}']), ('\u{10e8}', ['\u{1ca8}', '\u{0}', '\u{0}']), + ('\u{10e9}', ['\u{1ca9}', '\u{0}', '\u{0}']), ('\u{10ea}', ['\u{1caa}', '\u{0}', '\u{0}']), + ('\u{10eb}', ['\u{1cab}', '\u{0}', '\u{0}']), ('\u{10ec}', ['\u{1cac}', '\u{0}', '\u{0}']), + ('\u{10ed}', ['\u{1cad}', '\u{0}', '\u{0}']), ('\u{10ee}', ['\u{1cae}', '\u{0}', '\u{0}']), + ('\u{10ef}', ['\u{1caf}', '\u{0}', '\u{0}']), ('\u{10f0}', ['\u{1cb0}', '\u{0}', '\u{0}']), + ('\u{10f1}', ['\u{1cb1}', '\u{0}', '\u{0}']), ('\u{10f2}', ['\u{1cb2}', '\u{0}', '\u{0}']), + ('\u{10f3}', ['\u{1cb3}', '\u{0}', '\u{0}']), ('\u{10f4}', ['\u{1cb4}', '\u{0}', '\u{0}']), + ('\u{10f5}', ['\u{1cb5}', '\u{0}', '\u{0}']), ('\u{10f6}', ['\u{1cb6}', '\u{0}', '\u{0}']), + ('\u{10f7}', ['\u{1cb7}', '\u{0}', '\u{0}']), ('\u{10f8}', ['\u{1cb8}', '\u{0}', '\u{0}']), + ('\u{10f9}', ['\u{1cb9}', '\u{0}', '\u{0}']), ('\u{10fa}', ['\u{1cba}', '\u{0}', '\u{0}']), + ('\u{10fd}', ['\u{1cbd}', '\u{0}', '\u{0}']), ('\u{10fe}', ['\u{1cbe}', '\u{0}', '\u{0}']), + ('\u{10ff}', ['\u{1cbf}', '\u{0}', '\u{0}']), ('\u{13f8}', ['\u{13f0}', '\u{0}', '\u{0}']), + ('\u{13f9}', ['\u{13f1}', '\u{0}', '\u{0}']), ('\u{13fa}', ['\u{13f2}', '\u{0}', '\u{0}']), + ('\u{13fb}', ['\u{13f3}', '\u{0}', '\u{0}']), ('\u{13fc}', ['\u{13f4}', '\u{0}', '\u{0}']), + ('\u{13fd}', ['\u{13f5}', '\u{0}', '\u{0}']), ('\u{1c80}', ['\u{412}', '\u{0}', '\u{0}']), + ('\u{1c81}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{1c82}', ['\u{41e}', '\u{0}', '\u{0}']), + ('\u{1c83}', ['\u{421}', '\u{0}', '\u{0}']), ('\u{1c84}', ['\u{422}', '\u{0}', '\u{0}']), + ('\u{1c85}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{1c86}', ['\u{42a}', '\u{0}', '\u{0}']), + ('\u{1c87}', ['\u{462}', '\u{0}', '\u{0}']), ('\u{1c88}', ['\u{a64a}', '\u{0}', '\u{0}']), + ('\u{1d79}', ['\u{a77d}', '\u{0}', '\u{0}']), ('\u{1d7d}', ['\u{2c63}', '\u{0}', '\u{0}']), + ('\u{1d8e}', ['\u{a7c6}', '\u{0}', '\u{0}']), ('\u{1e01}', ['\u{1e00}', '\u{0}', '\u{0}']), + ('\u{1e03}', ['\u{1e02}', '\u{0}', '\u{0}']), ('\u{1e05}', ['\u{1e04}', '\u{0}', '\u{0}']), + ('\u{1e07}', ['\u{1e06}', '\u{0}', '\u{0}']), ('\u{1e09}', ['\u{1e08}', '\u{0}', '\u{0}']), + ('\u{1e0b}', ['\u{1e0a}', '\u{0}', '\u{0}']), ('\u{1e0d}', ['\u{1e0c}', '\u{0}', '\u{0}']), + ('\u{1e0f}', ['\u{1e0e}', '\u{0}', '\u{0}']), ('\u{1e11}', ['\u{1e10}', '\u{0}', '\u{0}']), + ('\u{1e13}', ['\u{1e12}', '\u{0}', '\u{0}']), ('\u{1e15}', ['\u{1e14}', '\u{0}', '\u{0}']), + ('\u{1e17}', ['\u{1e16}', '\u{0}', '\u{0}']), ('\u{1e19}', ['\u{1e18}', '\u{0}', '\u{0}']), + ('\u{1e1b}', ['\u{1e1a}', '\u{0}', '\u{0}']), ('\u{1e1d}', ['\u{1e1c}', '\u{0}', '\u{0}']), + ('\u{1e1f}', ['\u{1e1e}', '\u{0}', '\u{0}']), ('\u{1e21}', ['\u{1e20}', '\u{0}', '\u{0}']), + ('\u{1e23}', ['\u{1e22}', '\u{0}', '\u{0}']), ('\u{1e25}', ['\u{1e24}', '\u{0}', '\u{0}']), + ('\u{1e27}', ['\u{1e26}', '\u{0}', '\u{0}']), ('\u{1e29}', ['\u{1e28}', '\u{0}', '\u{0}']), + ('\u{1e2b}', ['\u{1e2a}', '\u{0}', '\u{0}']), ('\u{1e2d}', ['\u{1e2c}', '\u{0}', '\u{0}']), + ('\u{1e2f}', ['\u{1e2e}', '\u{0}', '\u{0}']), ('\u{1e31}', ['\u{1e30}', '\u{0}', '\u{0}']), + ('\u{1e33}', ['\u{1e32}', '\u{0}', '\u{0}']), ('\u{1e35}', ['\u{1e34}', '\u{0}', '\u{0}']), + ('\u{1e37}', ['\u{1e36}', '\u{0}', '\u{0}']), ('\u{1e39}', ['\u{1e38}', '\u{0}', '\u{0}']), + ('\u{1e3b}', ['\u{1e3a}', '\u{0}', '\u{0}']), ('\u{1e3d}', ['\u{1e3c}', '\u{0}', '\u{0}']), + ('\u{1e3f}', ['\u{1e3e}', '\u{0}', '\u{0}']), ('\u{1e41}', ['\u{1e40}', '\u{0}', '\u{0}']), + ('\u{1e43}', ['\u{1e42}', '\u{0}', '\u{0}']), ('\u{1e45}', ['\u{1e44}', '\u{0}', '\u{0}']), + ('\u{1e47}', ['\u{1e46}', '\u{0}', '\u{0}']), ('\u{1e49}', ['\u{1e48}', '\u{0}', '\u{0}']), + ('\u{1e4b}', ['\u{1e4a}', '\u{0}', '\u{0}']), ('\u{1e4d}', ['\u{1e4c}', '\u{0}', '\u{0}']), + ('\u{1e4f}', ['\u{1e4e}', '\u{0}', '\u{0}']), ('\u{1e51}', ['\u{1e50}', '\u{0}', '\u{0}']), + ('\u{1e53}', ['\u{1e52}', '\u{0}', '\u{0}']), ('\u{1e55}', ['\u{1e54}', '\u{0}', '\u{0}']), + ('\u{1e57}', ['\u{1e56}', '\u{0}', '\u{0}']), ('\u{1e59}', ['\u{1e58}', '\u{0}', '\u{0}']), + ('\u{1e5b}', ['\u{1e5a}', '\u{0}', '\u{0}']), ('\u{1e5d}', ['\u{1e5c}', '\u{0}', '\u{0}']), + ('\u{1e5f}', ['\u{1e5e}', '\u{0}', '\u{0}']), ('\u{1e61}', ['\u{1e60}', '\u{0}', '\u{0}']), + ('\u{1e63}', ['\u{1e62}', '\u{0}', '\u{0}']), ('\u{1e65}', ['\u{1e64}', '\u{0}', '\u{0}']), + ('\u{1e67}', ['\u{1e66}', '\u{0}', '\u{0}']), ('\u{1e69}', ['\u{1e68}', '\u{0}', '\u{0}']), + ('\u{1e6b}', ['\u{1e6a}', '\u{0}', '\u{0}']), ('\u{1e6d}', ['\u{1e6c}', '\u{0}', '\u{0}']), + ('\u{1e6f}', ['\u{1e6e}', '\u{0}', '\u{0}']), ('\u{1e71}', ['\u{1e70}', '\u{0}', '\u{0}']), + ('\u{1e73}', ['\u{1e72}', '\u{0}', '\u{0}']), ('\u{1e75}', ['\u{1e74}', '\u{0}', '\u{0}']), + ('\u{1e77}', ['\u{1e76}', '\u{0}', '\u{0}']), ('\u{1e79}', ['\u{1e78}', '\u{0}', '\u{0}']), + ('\u{1e7b}', ['\u{1e7a}', '\u{0}', '\u{0}']), ('\u{1e7d}', ['\u{1e7c}', '\u{0}', '\u{0}']), + ('\u{1e7f}', ['\u{1e7e}', '\u{0}', '\u{0}']), ('\u{1e81}', ['\u{1e80}', '\u{0}', '\u{0}']), + ('\u{1e83}', ['\u{1e82}', '\u{0}', '\u{0}']), ('\u{1e85}', ['\u{1e84}', '\u{0}', '\u{0}']), + ('\u{1e87}', ['\u{1e86}', '\u{0}', '\u{0}']), ('\u{1e89}', ['\u{1e88}', '\u{0}', '\u{0}']), + ('\u{1e8b}', ['\u{1e8a}', '\u{0}', '\u{0}']), ('\u{1e8d}', ['\u{1e8c}', '\u{0}', '\u{0}']), + ('\u{1e8f}', ['\u{1e8e}', '\u{0}', '\u{0}']), ('\u{1e91}', ['\u{1e90}', '\u{0}', '\u{0}']), + ('\u{1e93}', ['\u{1e92}', '\u{0}', '\u{0}']), ('\u{1e95}', ['\u{1e94}', '\u{0}', '\u{0}']), + ('\u{1e96}', ['H', '\u{331}', '\u{0}']), ('\u{1e97}', ['T', '\u{308}', '\u{0}']), + ('\u{1e98}', ['W', '\u{30a}', '\u{0}']), ('\u{1e99}', ['Y', '\u{30a}', '\u{0}']), + ('\u{1e9a}', ['A', '\u{2be}', '\u{0}']), ('\u{1e9b}', ['\u{1e60}', '\u{0}', '\u{0}']), + ('\u{1ea1}', ['\u{1ea0}', '\u{0}', '\u{0}']), ('\u{1ea3}', ['\u{1ea2}', '\u{0}', '\u{0}']), + ('\u{1ea5}', ['\u{1ea4}', '\u{0}', '\u{0}']), ('\u{1ea7}', ['\u{1ea6}', '\u{0}', '\u{0}']), + ('\u{1ea9}', ['\u{1ea8}', '\u{0}', '\u{0}']), ('\u{1eab}', ['\u{1eaa}', '\u{0}', '\u{0}']), + ('\u{1ead}', ['\u{1eac}', '\u{0}', '\u{0}']), ('\u{1eaf}', ['\u{1eae}', '\u{0}', '\u{0}']), + ('\u{1eb1}', ['\u{1eb0}', '\u{0}', '\u{0}']), ('\u{1eb3}', ['\u{1eb2}', '\u{0}', '\u{0}']), + ('\u{1eb5}', ['\u{1eb4}', '\u{0}', '\u{0}']), ('\u{1eb7}', ['\u{1eb6}', '\u{0}', '\u{0}']), + ('\u{1eb9}', ['\u{1eb8}', '\u{0}', '\u{0}']), ('\u{1ebb}', ['\u{1eba}', '\u{0}', '\u{0}']), + ('\u{1ebd}', ['\u{1ebc}', '\u{0}', '\u{0}']), ('\u{1ebf}', ['\u{1ebe}', '\u{0}', '\u{0}']), + ('\u{1ec1}', ['\u{1ec0}', '\u{0}', '\u{0}']), ('\u{1ec3}', ['\u{1ec2}', '\u{0}', '\u{0}']), + ('\u{1ec5}', ['\u{1ec4}', '\u{0}', '\u{0}']), ('\u{1ec7}', ['\u{1ec6}', '\u{0}', '\u{0}']), + ('\u{1ec9}', ['\u{1ec8}', '\u{0}', '\u{0}']), ('\u{1ecb}', ['\u{1eca}', '\u{0}', '\u{0}']), + ('\u{1ecd}', ['\u{1ecc}', '\u{0}', '\u{0}']), ('\u{1ecf}', ['\u{1ece}', '\u{0}', '\u{0}']), + ('\u{1ed1}', ['\u{1ed0}', '\u{0}', '\u{0}']), ('\u{1ed3}', ['\u{1ed2}', '\u{0}', '\u{0}']), + ('\u{1ed5}', ['\u{1ed4}', '\u{0}', '\u{0}']), ('\u{1ed7}', ['\u{1ed6}', '\u{0}', '\u{0}']), + ('\u{1ed9}', ['\u{1ed8}', '\u{0}', '\u{0}']), ('\u{1edb}', ['\u{1eda}', '\u{0}', '\u{0}']), + ('\u{1edd}', ['\u{1edc}', '\u{0}', '\u{0}']), ('\u{1edf}', ['\u{1ede}', '\u{0}', '\u{0}']), + ('\u{1ee1}', ['\u{1ee0}', '\u{0}', '\u{0}']), ('\u{1ee3}', ['\u{1ee2}', '\u{0}', '\u{0}']), + ('\u{1ee5}', ['\u{1ee4}', '\u{0}', '\u{0}']), ('\u{1ee7}', ['\u{1ee6}', '\u{0}', '\u{0}']), + ('\u{1ee9}', ['\u{1ee8}', '\u{0}', '\u{0}']), ('\u{1eeb}', ['\u{1eea}', '\u{0}', '\u{0}']), + ('\u{1eed}', ['\u{1eec}', '\u{0}', '\u{0}']), ('\u{1eef}', ['\u{1eee}', '\u{0}', '\u{0}']), + ('\u{1ef1}', ['\u{1ef0}', '\u{0}', '\u{0}']), ('\u{1ef3}', ['\u{1ef2}', '\u{0}', '\u{0}']), + ('\u{1ef5}', ['\u{1ef4}', '\u{0}', '\u{0}']), ('\u{1ef7}', ['\u{1ef6}', '\u{0}', '\u{0}']), + ('\u{1ef9}', ['\u{1ef8}', '\u{0}', '\u{0}']), ('\u{1efb}', ['\u{1efa}', '\u{0}', '\u{0}']), + ('\u{1efd}', ['\u{1efc}', '\u{0}', '\u{0}']), ('\u{1eff}', ['\u{1efe}', '\u{0}', '\u{0}']), + ('\u{1f00}', ['\u{1f08}', '\u{0}', '\u{0}']), ('\u{1f01}', ['\u{1f09}', '\u{0}', '\u{0}']), + ('\u{1f02}', ['\u{1f0a}', '\u{0}', '\u{0}']), ('\u{1f03}', ['\u{1f0b}', '\u{0}', '\u{0}']), + ('\u{1f04}', ['\u{1f0c}', '\u{0}', '\u{0}']), ('\u{1f05}', ['\u{1f0d}', '\u{0}', '\u{0}']), + ('\u{1f06}', ['\u{1f0e}', '\u{0}', '\u{0}']), ('\u{1f07}', ['\u{1f0f}', '\u{0}', '\u{0}']), + ('\u{1f10}', ['\u{1f18}', '\u{0}', '\u{0}']), ('\u{1f11}', ['\u{1f19}', '\u{0}', '\u{0}']), + ('\u{1f12}', ['\u{1f1a}', '\u{0}', '\u{0}']), ('\u{1f13}', ['\u{1f1b}', '\u{0}', '\u{0}']), + ('\u{1f14}', ['\u{1f1c}', '\u{0}', '\u{0}']), ('\u{1f15}', ['\u{1f1d}', '\u{0}', '\u{0}']), + ('\u{1f20}', ['\u{1f28}', '\u{0}', '\u{0}']), ('\u{1f21}', ['\u{1f29}', '\u{0}', '\u{0}']), + ('\u{1f22}', ['\u{1f2a}', '\u{0}', '\u{0}']), ('\u{1f23}', ['\u{1f2b}', '\u{0}', '\u{0}']), + ('\u{1f24}', ['\u{1f2c}', '\u{0}', '\u{0}']), ('\u{1f25}', ['\u{1f2d}', '\u{0}', '\u{0}']), + ('\u{1f26}', ['\u{1f2e}', '\u{0}', '\u{0}']), ('\u{1f27}', ['\u{1f2f}', '\u{0}', '\u{0}']), + ('\u{1f30}', ['\u{1f38}', '\u{0}', '\u{0}']), ('\u{1f31}', ['\u{1f39}', '\u{0}', '\u{0}']), + ('\u{1f32}', ['\u{1f3a}', '\u{0}', '\u{0}']), ('\u{1f33}', ['\u{1f3b}', '\u{0}', '\u{0}']), + ('\u{1f34}', ['\u{1f3c}', '\u{0}', '\u{0}']), ('\u{1f35}', ['\u{1f3d}', '\u{0}', '\u{0}']), + ('\u{1f36}', ['\u{1f3e}', '\u{0}', '\u{0}']), ('\u{1f37}', ['\u{1f3f}', '\u{0}', '\u{0}']), + ('\u{1f40}', ['\u{1f48}', '\u{0}', '\u{0}']), ('\u{1f41}', ['\u{1f49}', '\u{0}', '\u{0}']), + ('\u{1f42}', ['\u{1f4a}', '\u{0}', '\u{0}']), ('\u{1f43}', ['\u{1f4b}', '\u{0}', '\u{0}']), + ('\u{1f44}', ['\u{1f4c}', '\u{0}', '\u{0}']), ('\u{1f45}', ['\u{1f4d}', '\u{0}', '\u{0}']), + ('\u{1f50}', ['\u{3a5}', '\u{313}', '\u{0}']), ('\u{1f51}', ['\u{1f59}', '\u{0}', '\u{0}']), + ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), + ('\u{1f53}', ['\u{1f5b}', '\u{0}', '\u{0}']), + ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), + ('\u{1f55}', ['\u{1f5d}', '\u{0}', '\u{0}']), + ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), + ('\u{1f57}', ['\u{1f5f}', '\u{0}', '\u{0}']), ('\u{1f60}', ['\u{1f68}', '\u{0}', '\u{0}']), + ('\u{1f61}', ['\u{1f69}', '\u{0}', '\u{0}']), ('\u{1f62}', ['\u{1f6a}', '\u{0}', '\u{0}']), + ('\u{1f63}', ['\u{1f6b}', '\u{0}', '\u{0}']), ('\u{1f64}', ['\u{1f6c}', '\u{0}', '\u{0}']), + ('\u{1f65}', ['\u{1f6d}', '\u{0}', '\u{0}']), ('\u{1f66}', ['\u{1f6e}', '\u{0}', '\u{0}']), + ('\u{1f67}', ['\u{1f6f}', '\u{0}', '\u{0}']), ('\u{1f70}', ['\u{1fba}', '\u{0}', '\u{0}']), + ('\u{1f71}', ['\u{1fbb}', '\u{0}', '\u{0}']), ('\u{1f72}', ['\u{1fc8}', '\u{0}', '\u{0}']), + ('\u{1f73}', ['\u{1fc9}', '\u{0}', '\u{0}']), ('\u{1f74}', ['\u{1fca}', '\u{0}', '\u{0}']), + ('\u{1f75}', ['\u{1fcb}', '\u{0}', '\u{0}']), ('\u{1f76}', ['\u{1fda}', '\u{0}', '\u{0}']), + ('\u{1f77}', ['\u{1fdb}', '\u{0}', '\u{0}']), ('\u{1f78}', ['\u{1ff8}', '\u{0}', '\u{0}']), + ('\u{1f79}', ['\u{1ff9}', '\u{0}', '\u{0}']), ('\u{1f7a}', ['\u{1fea}', '\u{0}', '\u{0}']), + ('\u{1f7b}', ['\u{1feb}', '\u{0}', '\u{0}']), ('\u{1f7c}', ['\u{1ffa}', '\u{0}', '\u{0}']), + ('\u{1f7d}', ['\u{1ffb}', '\u{0}', '\u{0}']), + ('\u{1f80}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f81}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f88}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f89}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f90}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f91}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1f98}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f99}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fb0}', ['\u{1fb8}', '\u{0}', '\u{0}']), ('\u{1fb1}', ['\u{1fb9}', '\u{0}', '\u{0}']), + ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\u{0}']), + ('\u{1fb3}', ['\u{391}', '\u{399}', '\u{0}']), + ('\u{1fb4}', ['\u{386}', '\u{399}', '\u{0}']), + ('\u{1fb6}', ['\u{391}', '\u{342}', '\u{0}']), + ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), + ('\u{1fbc}', ['\u{391}', '\u{399}', '\u{0}']), ('\u{1fbe}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\u{0}']), + ('\u{1fc3}', ['\u{397}', '\u{399}', '\u{0}']), + ('\u{1fc4}', ['\u{389}', '\u{399}', '\u{0}']), + ('\u{1fc6}', ['\u{397}', '\u{342}', '\u{0}']), + ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), + ('\u{1fcc}', ['\u{397}', '\u{399}', '\u{0}']), ('\u{1fd0}', ['\u{1fd8}', '\u{0}', '\u{0}']), + ('\u{1fd1}', ['\u{1fd9}', '\u{0}', '\u{0}']), + ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), + ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), + ('\u{1fd6}', ['\u{399}', '\u{342}', '\u{0}']), + ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), + ('\u{1fe0}', ['\u{1fe8}', '\u{0}', '\u{0}']), ('\u{1fe1}', ['\u{1fe9}', '\u{0}', '\u{0}']), + ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), + ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\u{0}']), ('\u{1fe5}', ['\u{1fec}', '\u{0}', '\u{0}']), + ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\u{0}']), + ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), + ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\u{0}']), + ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\u{0}']), + ('\u{1ff4}', ['\u{38f}', '\u{399}', '\u{0}']), + ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\u{0}']), + ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), + ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\u{0}']), ('\u{214e}', ['\u{2132}', '\u{0}', '\u{0}']), + ('\u{2170}', ['\u{2160}', '\u{0}', '\u{0}']), ('\u{2171}', ['\u{2161}', '\u{0}', '\u{0}']), + ('\u{2172}', ['\u{2162}', '\u{0}', '\u{0}']), ('\u{2173}', ['\u{2163}', '\u{0}', '\u{0}']), + ('\u{2174}', ['\u{2164}', '\u{0}', '\u{0}']), ('\u{2175}', ['\u{2165}', '\u{0}', '\u{0}']), + ('\u{2176}', ['\u{2166}', '\u{0}', '\u{0}']), ('\u{2177}', ['\u{2167}', '\u{0}', '\u{0}']), + ('\u{2178}', ['\u{2168}', '\u{0}', '\u{0}']), ('\u{2179}', ['\u{2169}', '\u{0}', '\u{0}']), + ('\u{217a}', ['\u{216a}', '\u{0}', '\u{0}']), ('\u{217b}', ['\u{216b}', '\u{0}', '\u{0}']), + ('\u{217c}', ['\u{216c}', '\u{0}', '\u{0}']), ('\u{217d}', ['\u{216d}', '\u{0}', '\u{0}']), + ('\u{217e}', ['\u{216e}', '\u{0}', '\u{0}']), ('\u{217f}', ['\u{216f}', '\u{0}', '\u{0}']), + ('\u{2184}', ['\u{2183}', '\u{0}', '\u{0}']), ('\u{24d0}', ['\u{24b6}', '\u{0}', '\u{0}']), + ('\u{24d1}', ['\u{24b7}', '\u{0}', '\u{0}']), ('\u{24d2}', ['\u{24b8}', '\u{0}', '\u{0}']), + ('\u{24d3}', ['\u{24b9}', '\u{0}', '\u{0}']), ('\u{24d4}', ['\u{24ba}', '\u{0}', '\u{0}']), + ('\u{24d5}', ['\u{24bb}', '\u{0}', '\u{0}']), ('\u{24d6}', ['\u{24bc}', '\u{0}', '\u{0}']), + ('\u{24d7}', ['\u{24bd}', '\u{0}', '\u{0}']), ('\u{24d8}', ['\u{24be}', '\u{0}', '\u{0}']), + ('\u{24d9}', ['\u{24bf}', '\u{0}', '\u{0}']), ('\u{24da}', ['\u{24c0}', '\u{0}', '\u{0}']), + ('\u{24db}', ['\u{24c1}', '\u{0}', '\u{0}']), ('\u{24dc}', ['\u{24c2}', '\u{0}', '\u{0}']), + ('\u{24dd}', ['\u{24c3}', '\u{0}', '\u{0}']), ('\u{24de}', ['\u{24c4}', '\u{0}', '\u{0}']), + ('\u{24df}', ['\u{24c5}', '\u{0}', '\u{0}']), ('\u{24e0}', ['\u{24c6}', '\u{0}', '\u{0}']), + ('\u{24e1}', ['\u{24c7}', '\u{0}', '\u{0}']), ('\u{24e2}', ['\u{24c8}', '\u{0}', '\u{0}']), + ('\u{24e3}', ['\u{24c9}', '\u{0}', '\u{0}']), ('\u{24e4}', ['\u{24ca}', '\u{0}', '\u{0}']), + ('\u{24e5}', ['\u{24cb}', '\u{0}', '\u{0}']), ('\u{24e6}', ['\u{24cc}', '\u{0}', '\u{0}']), + ('\u{24e7}', ['\u{24cd}', '\u{0}', '\u{0}']), ('\u{24e8}', ['\u{24ce}', '\u{0}', '\u{0}']), + ('\u{24e9}', ['\u{24cf}', '\u{0}', '\u{0}']), ('\u{2c30}', ['\u{2c00}', '\u{0}', '\u{0}']), + ('\u{2c31}', ['\u{2c01}', '\u{0}', '\u{0}']), ('\u{2c32}', ['\u{2c02}', '\u{0}', '\u{0}']), + ('\u{2c33}', ['\u{2c03}', '\u{0}', '\u{0}']), ('\u{2c34}', ['\u{2c04}', '\u{0}', '\u{0}']), + ('\u{2c35}', ['\u{2c05}', '\u{0}', '\u{0}']), ('\u{2c36}', ['\u{2c06}', '\u{0}', '\u{0}']), + ('\u{2c37}', ['\u{2c07}', '\u{0}', '\u{0}']), ('\u{2c38}', ['\u{2c08}', '\u{0}', '\u{0}']), + ('\u{2c39}', ['\u{2c09}', '\u{0}', '\u{0}']), ('\u{2c3a}', ['\u{2c0a}', '\u{0}', '\u{0}']), + ('\u{2c3b}', ['\u{2c0b}', '\u{0}', '\u{0}']), ('\u{2c3c}', ['\u{2c0c}', '\u{0}', '\u{0}']), + ('\u{2c3d}', ['\u{2c0d}', '\u{0}', '\u{0}']), ('\u{2c3e}', ['\u{2c0e}', '\u{0}', '\u{0}']), + ('\u{2c3f}', ['\u{2c0f}', '\u{0}', '\u{0}']), ('\u{2c40}', ['\u{2c10}', '\u{0}', '\u{0}']), + ('\u{2c41}', ['\u{2c11}', '\u{0}', '\u{0}']), ('\u{2c42}', ['\u{2c12}', '\u{0}', '\u{0}']), + ('\u{2c43}', ['\u{2c13}', '\u{0}', '\u{0}']), ('\u{2c44}', ['\u{2c14}', '\u{0}', '\u{0}']), + ('\u{2c45}', ['\u{2c15}', '\u{0}', '\u{0}']), ('\u{2c46}', ['\u{2c16}', '\u{0}', '\u{0}']), + ('\u{2c47}', ['\u{2c17}', '\u{0}', '\u{0}']), ('\u{2c48}', ['\u{2c18}', '\u{0}', '\u{0}']), + ('\u{2c49}', ['\u{2c19}', '\u{0}', '\u{0}']), ('\u{2c4a}', ['\u{2c1a}', '\u{0}', '\u{0}']), + ('\u{2c4b}', ['\u{2c1b}', '\u{0}', '\u{0}']), ('\u{2c4c}', ['\u{2c1c}', '\u{0}', '\u{0}']), + ('\u{2c4d}', ['\u{2c1d}', '\u{0}', '\u{0}']), ('\u{2c4e}', ['\u{2c1e}', '\u{0}', '\u{0}']), + ('\u{2c4f}', ['\u{2c1f}', '\u{0}', '\u{0}']), ('\u{2c50}', ['\u{2c20}', '\u{0}', '\u{0}']), + ('\u{2c51}', ['\u{2c21}', '\u{0}', '\u{0}']), ('\u{2c52}', ['\u{2c22}', '\u{0}', '\u{0}']), + ('\u{2c53}', ['\u{2c23}', '\u{0}', '\u{0}']), ('\u{2c54}', ['\u{2c24}', '\u{0}', '\u{0}']), + ('\u{2c55}', ['\u{2c25}', '\u{0}', '\u{0}']), ('\u{2c56}', ['\u{2c26}', '\u{0}', '\u{0}']), + ('\u{2c57}', ['\u{2c27}', '\u{0}', '\u{0}']), ('\u{2c58}', ['\u{2c28}', '\u{0}', '\u{0}']), + ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']), + ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']), + ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']), + ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), + ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), + ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), + ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), + ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), + ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), + ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), + ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), + ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), + ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), + ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), + ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), + ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), + ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), + ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), + ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), + ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), + ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), + ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), + ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), + ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), + ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), + ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), + ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), + ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), + ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), + ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), + ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), + ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), + ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), + ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), + ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), + ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), + ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), + ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), + ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), + ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), + ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), + ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), + ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), + ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), + ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), + ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), + ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), + ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), + ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), + ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), + ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), + ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), + ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), + ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), + ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), + ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), + ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), + ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), + ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), + ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), + ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), + ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), + ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), + ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), + ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), + ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), + ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), + ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), + ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), + ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), + ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), + ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), + ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), + ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), + ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), + ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), + ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), + ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), + ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), + ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), + ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), + ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), + ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), + ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), + ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), + ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), + ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), + ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), + ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), + ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), + ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), + ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), + ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), + ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), + ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), + ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), + ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), + ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), + ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), + ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), + ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), + ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), + ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), + ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), + ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']), + ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), + ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), + ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), + ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), + ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), + ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), + ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), + ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), + ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), + ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), + ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), + ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), + ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), + ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), + ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), + ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), + ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), + ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), + ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), + ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), + ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), + ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), + ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), + ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), + ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), + ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), + ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), + ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), + ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), + ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), + ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), + ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), + ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), + ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), + ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), + ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), + ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), + ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), + ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), + ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), + ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'F', '\u{0}']), + ('\u{fb01}', ['F', 'I', '\u{0}']), ('\u{fb02}', ['F', 'L', '\u{0}']), + ('\u{fb03}', ['F', 'F', 'I']), ('\u{fb04}', ['F', 'F', 'L']), + ('\u{fb05}', ['S', 'T', '\u{0}']), ('\u{fb06}', ['S', 'T', '\u{0}']), + ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']), + ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']), + ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']), + ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']), + ('\u{fb17}', ['\u{544}', '\u{53d}', '\u{0}']), ('\u{ff41}', ['\u{ff21}', '\u{0}', '\u{0}']), + ('\u{ff42}', ['\u{ff22}', '\u{0}', '\u{0}']), ('\u{ff43}', ['\u{ff23}', '\u{0}', '\u{0}']), + ('\u{ff44}', ['\u{ff24}', '\u{0}', '\u{0}']), ('\u{ff45}', ['\u{ff25}', '\u{0}', '\u{0}']), + ('\u{ff46}', ['\u{ff26}', '\u{0}', '\u{0}']), ('\u{ff47}', ['\u{ff27}', '\u{0}', '\u{0}']), + ('\u{ff48}', ['\u{ff28}', '\u{0}', '\u{0}']), ('\u{ff49}', ['\u{ff29}', '\u{0}', '\u{0}']), + ('\u{ff4a}', ['\u{ff2a}', '\u{0}', '\u{0}']), ('\u{ff4b}', ['\u{ff2b}', '\u{0}', '\u{0}']), + ('\u{ff4c}', ['\u{ff2c}', '\u{0}', '\u{0}']), ('\u{ff4d}', ['\u{ff2d}', '\u{0}', '\u{0}']), + ('\u{ff4e}', ['\u{ff2e}', '\u{0}', '\u{0}']), ('\u{ff4f}', ['\u{ff2f}', '\u{0}', '\u{0}']), + ('\u{ff50}', ['\u{ff30}', '\u{0}', '\u{0}']), ('\u{ff51}', ['\u{ff31}', '\u{0}', '\u{0}']), + ('\u{ff52}', ['\u{ff32}', '\u{0}', '\u{0}']), ('\u{ff53}', ['\u{ff33}', '\u{0}', '\u{0}']), + ('\u{ff54}', ['\u{ff34}', '\u{0}', '\u{0}']), ('\u{ff55}', ['\u{ff35}', '\u{0}', '\u{0}']), + ('\u{ff56}', ['\u{ff36}', '\u{0}', '\u{0}']), ('\u{ff57}', ['\u{ff37}', '\u{0}', '\u{0}']), + ('\u{ff58}', ['\u{ff38}', '\u{0}', '\u{0}']), ('\u{ff59}', ['\u{ff39}', '\u{0}', '\u{0}']), + ('\u{ff5a}', ['\u{ff3a}', '\u{0}', '\u{0}']), + ('\u{10428}', ['\u{10400}', '\u{0}', '\u{0}']), + ('\u{10429}', ['\u{10401}', '\u{0}', '\u{0}']), + ('\u{1042a}', ['\u{10402}', '\u{0}', '\u{0}']), + ('\u{1042b}', ['\u{10403}', '\u{0}', '\u{0}']), + ('\u{1042c}', ['\u{10404}', '\u{0}', '\u{0}']), + ('\u{1042d}', ['\u{10405}', '\u{0}', '\u{0}']), + ('\u{1042e}', ['\u{10406}', '\u{0}', '\u{0}']), + ('\u{1042f}', ['\u{10407}', '\u{0}', '\u{0}']), + ('\u{10430}', ['\u{10408}', '\u{0}', '\u{0}']), + ('\u{10431}', ['\u{10409}', '\u{0}', '\u{0}']), + ('\u{10432}', ['\u{1040a}', '\u{0}', '\u{0}']), + ('\u{10433}', ['\u{1040b}', '\u{0}', '\u{0}']), + ('\u{10434}', ['\u{1040c}', '\u{0}', '\u{0}']), + ('\u{10435}', ['\u{1040d}', '\u{0}', '\u{0}']), + ('\u{10436}', ['\u{1040e}', '\u{0}', '\u{0}']), + ('\u{10437}', ['\u{1040f}', '\u{0}', '\u{0}']), + ('\u{10438}', ['\u{10410}', '\u{0}', '\u{0}']), + ('\u{10439}', ['\u{10411}', '\u{0}', '\u{0}']), + ('\u{1043a}', ['\u{10412}', '\u{0}', '\u{0}']), + ('\u{1043b}', ['\u{10413}', '\u{0}', '\u{0}']), + ('\u{1043c}', ['\u{10414}', '\u{0}', '\u{0}']), + ('\u{1043d}', ['\u{10415}', '\u{0}', '\u{0}']), + ('\u{1043e}', ['\u{10416}', '\u{0}', '\u{0}']), + ('\u{1043f}', ['\u{10417}', '\u{0}', '\u{0}']), + ('\u{10440}', ['\u{10418}', '\u{0}', '\u{0}']), + ('\u{10441}', ['\u{10419}', '\u{0}', '\u{0}']), + ('\u{10442}', ['\u{1041a}', '\u{0}', '\u{0}']), + ('\u{10443}', ['\u{1041b}', '\u{0}', '\u{0}']), + ('\u{10444}', ['\u{1041c}', '\u{0}', '\u{0}']), + ('\u{10445}', ['\u{1041d}', '\u{0}', '\u{0}']), + ('\u{10446}', ['\u{1041e}', '\u{0}', '\u{0}']), + ('\u{10447}', ['\u{1041f}', '\u{0}', '\u{0}']), + ('\u{10448}', ['\u{10420}', '\u{0}', '\u{0}']), + ('\u{10449}', ['\u{10421}', '\u{0}', '\u{0}']), + ('\u{1044a}', ['\u{10422}', '\u{0}', '\u{0}']), + ('\u{1044b}', ['\u{10423}', '\u{0}', '\u{0}']), + ('\u{1044c}', ['\u{10424}', '\u{0}', '\u{0}']), + ('\u{1044d}', ['\u{10425}', '\u{0}', '\u{0}']), + ('\u{1044e}', ['\u{10426}', '\u{0}', '\u{0}']), + ('\u{1044f}', ['\u{10427}', '\u{0}', '\u{0}']), + ('\u{104d8}', ['\u{104b0}', '\u{0}', '\u{0}']), + ('\u{104d9}', ['\u{104b1}', '\u{0}', '\u{0}']), + ('\u{104da}', ['\u{104b2}', '\u{0}', '\u{0}']), + ('\u{104db}', ['\u{104b3}', '\u{0}', '\u{0}']), + ('\u{104dc}', ['\u{104b4}', '\u{0}', '\u{0}']), + ('\u{104dd}', ['\u{104b5}', '\u{0}', '\u{0}']), + ('\u{104de}', ['\u{104b6}', '\u{0}', '\u{0}']), + ('\u{104df}', ['\u{104b7}', '\u{0}', '\u{0}']), + ('\u{104e0}', ['\u{104b8}', '\u{0}', '\u{0}']), + ('\u{104e1}', ['\u{104b9}', '\u{0}', '\u{0}']), + ('\u{104e2}', ['\u{104ba}', '\u{0}', '\u{0}']), + ('\u{104e3}', ['\u{104bb}', '\u{0}', '\u{0}']), + ('\u{104e4}', ['\u{104bc}', '\u{0}', '\u{0}']), + ('\u{104e5}', ['\u{104bd}', '\u{0}', '\u{0}']), + ('\u{104e6}', ['\u{104be}', '\u{0}', '\u{0}']), + ('\u{104e7}', ['\u{104bf}', '\u{0}', '\u{0}']), + ('\u{104e8}', ['\u{104c0}', '\u{0}', '\u{0}']), + ('\u{104e9}', ['\u{104c1}', '\u{0}', '\u{0}']), + ('\u{104ea}', ['\u{104c2}', '\u{0}', '\u{0}']), + ('\u{104eb}', ['\u{104c3}', '\u{0}', '\u{0}']), + ('\u{104ec}', ['\u{104c4}', '\u{0}', '\u{0}']), + ('\u{104ed}', ['\u{104c5}', '\u{0}', '\u{0}']), + ('\u{104ee}', ['\u{104c6}', '\u{0}', '\u{0}']), + ('\u{104ef}', ['\u{104c7}', '\u{0}', '\u{0}']), + ('\u{104f0}', ['\u{104c8}', '\u{0}', '\u{0}']), + ('\u{104f1}', ['\u{104c9}', '\u{0}', '\u{0}']), + ('\u{104f2}', ['\u{104ca}', '\u{0}', '\u{0}']), + ('\u{104f3}', ['\u{104cb}', '\u{0}', '\u{0}']), + ('\u{104f4}', ['\u{104cc}', '\u{0}', '\u{0}']), + ('\u{104f5}', ['\u{104cd}', '\u{0}', '\u{0}']), + ('\u{104f6}', ['\u{104ce}', '\u{0}', '\u{0}']), + ('\u{104f7}', ['\u{104cf}', '\u{0}', '\u{0}']), + ('\u{104f8}', ['\u{104d0}', '\u{0}', '\u{0}']), + ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']), + ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']), + ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']), + ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']), + ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']), + ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']), + ('\u{10cc3}', ['\u{10c83}', '\u{0}', '\u{0}']), + ('\u{10cc4}', ['\u{10c84}', '\u{0}', '\u{0}']), + ('\u{10cc5}', ['\u{10c85}', '\u{0}', '\u{0}']), + ('\u{10cc6}', ['\u{10c86}', '\u{0}', '\u{0}']), + ('\u{10cc7}', ['\u{10c87}', '\u{0}', '\u{0}']), + ('\u{10cc8}', ['\u{10c88}', '\u{0}', '\u{0}']), + ('\u{10cc9}', ['\u{10c89}', '\u{0}', '\u{0}']), + ('\u{10cca}', ['\u{10c8a}', '\u{0}', '\u{0}']), + ('\u{10ccb}', ['\u{10c8b}', '\u{0}', '\u{0}']), + ('\u{10ccc}', ['\u{10c8c}', '\u{0}', '\u{0}']), + ('\u{10ccd}', ['\u{10c8d}', '\u{0}', '\u{0}']), + ('\u{10cce}', ['\u{10c8e}', '\u{0}', '\u{0}']), + ('\u{10ccf}', ['\u{10c8f}', '\u{0}', '\u{0}']), + ('\u{10cd0}', ['\u{10c90}', '\u{0}', '\u{0}']), + ('\u{10cd1}', ['\u{10c91}', '\u{0}', '\u{0}']), + ('\u{10cd2}', ['\u{10c92}', '\u{0}', '\u{0}']), + ('\u{10cd3}', ['\u{10c93}', '\u{0}', '\u{0}']), + ('\u{10cd4}', ['\u{10c94}', '\u{0}', '\u{0}']), + ('\u{10cd5}', ['\u{10c95}', '\u{0}', '\u{0}']), + ('\u{10cd6}', ['\u{10c96}', '\u{0}', '\u{0}']), + ('\u{10cd7}', ['\u{10c97}', '\u{0}', '\u{0}']), + ('\u{10cd8}', ['\u{10c98}', '\u{0}', '\u{0}']), + ('\u{10cd9}', ['\u{10c99}', '\u{0}', '\u{0}']), + ('\u{10cda}', ['\u{10c9a}', '\u{0}', '\u{0}']), + ('\u{10cdb}', ['\u{10c9b}', '\u{0}', '\u{0}']), + ('\u{10cdc}', ['\u{10c9c}', '\u{0}', '\u{0}']), + ('\u{10cdd}', ['\u{10c9d}', '\u{0}', '\u{0}']), + ('\u{10cde}', ['\u{10c9e}', '\u{0}', '\u{0}']), + ('\u{10cdf}', ['\u{10c9f}', '\u{0}', '\u{0}']), + ('\u{10ce0}', ['\u{10ca0}', '\u{0}', '\u{0}']), + ('\u{10ce1}', ['\u{10ca1}', '\u{0}', '\u{0}']), + ('\u{10ce2}', ['\u{10ca2}', '\u{0}', '\u{0}']), + ('\u{10ce3}', ['\u{10ca3}', '\u{0}', '\u{0}']), + ('\u{10ce4}', ['\u{10ca4}', '\u{0}', '\u{0}']), + ('\u{10ce5}', ['\u{10ca5}', '\u{0}', '\u{0}']), + ('\u{10ce6}', ['\u{10ca6}', '\u{0}', '\u{0}']), + ('\u{10ce7}', ['\u{10ca7}', '\u{0}', '\u{0}']), + ('\u{10ce8}', ['\u{10ca8}', '\u{0}', '\u{0}']), + ('\u{10ce9}', ['\u{10ca9}', '\u{0}', '\u{0}']), + ('\u{10cea}', ['\u{10caa}', '\u{0}', '\u{0}']), + ('\u{10ceb}', ['\u{10cab}', '\u{0}', '\u{0}']), + ('\u{10cec}', ['\u{10cac}', '\u{0}', '\u{0}']), + ('\u{10ced}', ['\u{10cad}', '\u{0}', '\u{0}']), + ('\u{10cee}', ['\u{10cae}', '\u{0}', '\u{0}']), + ('\u{10cef}', ['\u{10caf}', '\u{0}', '\u{0}']), + ('\u{10cf0}', ['\u{10cb0}', '\u{0}', '\u{0}']), + ('\u{10cf1}', ['\u{10cb1}', '\u{0}', '\u{0}']), + ('\u{10cf2}', ['\u{10cb2}', '\u{0}', '\u{0}']), + ('\u{118c0}', ['\u{118a0}', '\u{0}', '\u{0}']), + ('\u{118c1}', ['\u{118a1}', '\u{0}', '\u{0}']), + ('\u{118c2}', ['\u{118a2}', '\u{0}', '\u{0}']), + ('\u{118c3}', ['\u{118a3}', '\u{0}', '\u{0}']), + ('\u{118c4}', ['\u{118a4}', '\u{0}', '\u{0}']), + ('\u{118c5}', ['\u{118a5}', '\u{0}', '\u{0}']), + ('\u{118c6}', ['\u{118a6}', '\u{0}', '\u{0}']), + ('\u{118c7}', ['\u{118a7}', '\u{0}', '\u{0}']), + ('\u{118c8}', ['\u{118a8}', '\u{0}', '\u{0}']), + ('\u{118c9}', ['\u{118a9}', '\u{0}', '\u{0}']), + ('\u{118ca}', ['\u{118aa}', '\u{0}', '\u{0}']), + ('\u{118cb}', ['\u{118ab}', '\u{0}', '\u{0}']), + ('\u{118cc}', ['\u{118ac}', '\u{0}', '\u{0}']), + ('\u{118cd}', ['\u{118ad}', '\u{0}', '\u{0}']), + ('\u{118ce}', ['\u{118ae}', '\u{0}', '\u{0}']), + ('\u{118cf}', ['\u{118af}', '\u{0}', '\u{0}']), + ('\u{118d0}', ['\u{118b0}', '\u{0}', '\u{0}']), + ('\u{118d1}', ['\u{118b1}', '\u{0}', '\u{0}']), + ('\u{118d2}', ['\u{118b2}', '\u{0}', '\u{0}']), + ('\u{118d3}', ['\u{118b3}', '\u{0}', '\u{0}']), + ('\u{118d4}', ['\u{118b4}', '\u{0}', '\u{0}']), + ('\u{118d5}', ['\u{118b5}', '\u{0}', '\u{0}']), + ('\u{118d6}', ['\u{118b6}', '\u{0}', '\u{0}']), + ('\u{118d7}', ['\u{118b7}', '\u{0}', '\u{0}']), + ('\u{118d8}', ['\u{118b8}', '\u{0}', '\u{0}']), + ('\u{118d9}', ['\u{118b9}', '\u{0}', '\u{0}']), + ('\u{118da}', ['\u{118ba}', '\u{0}', '\u{0}']), + ('\u{118db}', ['\u{118bb}', '\u{0}', '\u{0}']), + ('\u{118dc}', ['\u{118bc}', '\u{0}', '\u{0}']), + ('\u{118dd}', ['\u{118bd}', '\u{0}', '\u{0}']), + ('\u{118de}', ['\u{118be}', '\u{0}', '\u{0}']), + ('\u{118df}', ['\u{118bf}', '\u{0}', '\u{0}']), + ('\u{16e60}', ['\u{16e40}', '\u{0}', '\u{0}']), + ('\u{16e61}', ['\u{16e41}', '\u{0}', '\u{0}']), + ('\u{16e62}', ['\u{16e42}', '\u{0}', '\u{0}']), + ('\u{16e63}', ['\u{16e43}', '\u{0}', '\u{0}']), + ('\u{16e64}', ['\u{16e44}', '\u{0}', '\u{0}']), + ('\u{16e65}', ['\u{16e45}', '\u{0}', '\u{0}']), + ('\u{16e66}', ['\u{16e46}', '\u{0}', '\u{0}']), + ('\u{16e67}', ['\u{16e47}', '\u{0}', '\u{0}']), + ('\u{16e68}', ['\u{16e48}', '\u{0}', '\u{0}']), + ('\u{16e69}', ['\u{16e49}', '\u{0}', '\u{0}']), + ('\u{16e6a}', ['\u{16e4a}', '\u{0}', '\u{0}']), + ('\u{16e6b}', ['\u{16e4b}', '\u{0}', '\u{0}']), + ('\u{16e6c}', ['\u{16e4c}', '\u{0}', '\u{0}']), + ('\u{16e6d}', ['\u{16e4d}', '\u{0}', '\u{0}']), + ('\u{16e6e}', ['\u{16e4e}', '\u{0}', '\u{0}']), + ('\u{16e6f}', ['\u{16e4f}', '\u{0}', '\u{0}']), + ('\u{16e70}', ['\u{16e50}', '\u{0}', '\u{0}']), + ('\u{16e71}', ['\u{16e51}', '\u{0}', '\u{0}']), + ('\u{16e72}', ['\u{16e52}', '\u{0}', '\u{0}']), + ('\u{16e73}', ['\u{16e53}', '\u{0}', '\u{0}']), + ('\u{16e74}', ['\u{16e54}', '\u{0}', '\u{0}']), + ('\u{16e75}', ['\u{16e55}', '\u{0}', '\u{0}']), + ('\u{16e76}', ['\u{16e56}', '\u{0}', '\u{0}']), + ('\u{16e77}', ['\u{16e57}', '\u{0}', '\u{0}']), + ('\u{16e78}', ['\u{16e58}', '\u{0}', '\u{0}']), + ('\u{16e79}', ['\u{16e59}', '\u{0}', '\u{0}']), + ('\u{16e7a}', ['\u{16e5a}', '\u{0}', '\u{0}']), + ('\u{16e7b}', ['\u{16e5b}', '\u{0}', '\u{0}']), + ('\u{16e7c}', ['\u{16e5c}', '\u{0}', '\u{0}']), + ('\u{16e7d}', ['\u{16e5d}', '\u{0}', '\u{0}']), + ('\u{16e7e}', ['\u{16e5e}', '\u{0}', '\u{0}']), + ('\u{16e7f}', ['\u{16e5f}', '\u{0}', '\u{0}']), + ('\u{1e922}', ['\u{1e900}', '\u{0}', '\u{0}']), + ('\u{1e923}', ['\u{1e901}', '\u{0}', '\u{0}']), + ('\u{1e924}', ['\u{1e902}', '\u{0}', '\u{0}']), + ('\u{1e925}', ['\u{1e903}', '\u{0}', '\u{0}']), + ('\u{1e926}', ['\u{1e904}', '\u{0}', '\u{0}']), + ('\u{1e927}', ['\u{1e905}', '\u{0}', '\u{0}']), + ('\u{1e928}', ['\u{1e906}', '\u{0}', '\u{0}']), + ('\u{1e929}', ['\u{1e907}', '\u{0}', '\u{0}']), + ('\u{1e92a}', ['\u{1e908}', '\u{0}', '\u{0}']), + ('\u{1e92b}', ['\u{1e909}', '\u{0}', '\u{0}']), + ('\u{1e92c}', ['\u{1e90a}', '\u{0}', '\u{0}']), + ('\u{1e92d}', ['\u{1e90b}', '\u{0}', '\u{0}']), + ('\u{1e92e}', ['\u{1e90c}', '\u{0}', '\u{0}']), + ('\u{1e92f}', ['\u{1e90d}', '\u{0}', '\u{0}']), + ('\u{1e930}', ['\u{1e90e}', '\u{0}', '\u{0}']), + ('\u{1e931}', ['\u{1e90f}', '\u{0}', '\u{0}']), + ('\u{1e932}', ['\u{1e910}', '\u{0}', '\u{0}']), + ('\u{1e933}', ['\u{1e911}', '\u{0}', '\u{0}']), + ('\u{1e934}', ['\u{1e912}', '\u{0}', '\u{0}']), + ('\u{1e935}', ['\u{1e913}', '\u{0}', '\u{0}']), + ('\u{1e936}', ['\u{1e914}', '\u{0}', '\u{0}']), + ('\u{1e937}', ['\u{1e915}', '\u{0}', '\u{0}']), + ('\u{1e938}', ['\u{1e916}', '\u{0}', '\u{0}']), + ('\u{1e939}', ['\u{1e917}', '\u{0}', '\u{0}']), + ('\u{1e93a}', ['\u{1e918}', '\u{0}', '\u{0}']), + ('\u{1e93b}', ['\u{1e919}', '\u{0}', '\u{0}']), + ('\u{1e93c}', ['\u{1e91a}', '\u{0}', '\u{0}']), + ('\u{1e93d}', ['\u{1e91b}', '\u{0}', '\u{0}']), + ('\u{1e93e}', ['\u{1e91c}', '\u{0}', '\u{0}']), + ('\u{1e93f}', ['\u{1e91d}', '\u{0}', '\u{0}']), + ('\u{1e940}', ['\u{1e91e}', '\u{0}', '\u{0}']), + ('\u{1e941}', ['\u{1e91f}', '\u{0}', '\u{0}']), + ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), + ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), + ]; +} From 47dce1be81b17512db9e730fdd04adf01f7cf10f Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 12 Nov 2019 16:12:15 -0800 Subject: [PATCH 0346/1253] Add test for `ResultsCursor` This is a unit test that ensures the `seek` functions work correctly. --- src/librustc/mir/mod.rs | 25 ++ src/librustc_mir/dataflow/generic/mod.rs | 3 + src/librustc_mir/dataflow/generic/tests.rs | 328 +++++++++++++++++++++ 3 files changed, 356 insertions(+) create mode 100644 src/librustc_mir/dataflow/generic/tests.rs diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ccd2a968ded4c..3a7c650c4618c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -215,6 +215,31 @@ impl<'tcx> Body<'tcx> { } } + /// Returns a partially initialized MIR body containing only a list of basic blocks. + /// + /// The returned MIR contains no `LocalDecl`s (even for the return place) or source scopes. It + /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different + /// crate. + pub fn new_cfg_only(basic_blocks: IndexVec>) -> Self { + Body { + phase: MirPhase::Build, + basic_blocks, + source_scopes: IndexVec::new(), + yield_ty: None, + generator_drop: None, + generator_layout: None, + local_decls: IndexVec::new(), + user_type_annotations: IndexVec::new(), + arg_count: 0, + spread_arg: None, + span: DUMMY_SP, + control_flow_destroyed: Vec::new(), + generator_kind: None, + var_debug_info: Vec::new(), + ignore_interior_mut_in_const_validation: false, + } + } + #[inline] pub fn basic_blocks(&self) -> &IndexVec> { &self.basic_blocks diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index 1b628f2c7eb8e..a80e7375482ed 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -307,3 +307,6 @@ impl GenKill for BitSet { self.remove(elem); } } + +#[cfg(test)] +mod tests; diff --git a/src/librustc_mir/dataflow/generic/tests.rs b/src/librustc_mir/dataflow/generic/tests.rs new file mode 100644 index 0000000000000..add9bfd03a818 --- /dev/null +++ b/src/librustc_mir/dataflow/generic/tests.rs @@ -0,0 +1,328 @@ +//! A test for the logic that updates the state in a `ResultsCursor` during seek. + +use rustc::mir::{self, BasicBlock, Location}; +use rustc::ty; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; + +use super::*; +use crate::dataflow::BottomValue; + +/// Returns `true` if the given location points to a `Call` terminator that can return +/// successfully. +fn is_call_terminator_non_diverging(body: &mir::Body<'_>, loc: Location) -> bool { + loc == body.terminator_loc(loc.block) + && matches!( + body[loc.block].terminator().kind, + mir::TerminatorKind::Call { destination: Some(_), .. } + ) +} + +/// Creates a `mir::Body` with a few disconnected basic blocks. +/// +/// This is the `Body` that will be used by the `MockAnalysis` below. The shape of its CFG is not +/// important. +fn mock_body() -> mir::Body<'static> { + let span = syntax_pos::DUMMY_SP; + let source_info = mir::SourceInfo { scope: mir::OUTERMOST_SOURCE_SCOPE, span }; + + let mut blocks = IndexVec::new(); + let mut block = |n, kind| { + let nop = mir::Statement { source_info, kind: mir::StatementKind::Nop }; + + blocks.push(mir::BasicBlockData { + statements: std::iter::repeat(&nop).cloned().take(n).collect(), + terminator: Some(mir::Terminator { source_info, kind }), + is_cleanup: false, + }) + }; + + let dummy_place = mir::Place { local: mir::RETURN_PLACE, projection: ty::List::empty() }; + + block(4, mir::TerminatorKind::Return); + block(1, mir::TerminatorKind::Return); + block( + 2, + mir::TerminatorKind::Call { + func: mir::Operand::Copy(dummy_place.clone()), + args: vec![], + destination: Some((dummy_place.clone(), mir::START_BLOCK)), + cleanup: None, + from_hir_call: false, + }, + ); + block(3, mir::TerminatorKind::Return); + block(0, mir::TerminatorKind::Return); + block( + 4, + mir::TerminatorKind::Call { + func: mir::Operand::Copy(dummy_place.clone()), + args: vec![], + destination: Some((dummy_place.clone(), mir::START_BLOCK)), + cleanup: None, + from_hir_call: false, + }, + ); + + mir::Body::new_cfg_only(blocks) +} + +/// A dataflow analysis whose state is unique at every possible `SeekTarget`. +/// +/// Uniqueness is achieved by having a *locally* unique effect before and after each statement and +/// terminator (see `effect_at_target`) while ensuring that the entry set for each block is +/// *globally* unique (see `mock_entry_set`). +/// +/// For example, a `BasicBlock` with ID `2` and a `Call` terminator has the following state at each +/// location ("+x" indicates that "x" is added to the state). +/// +/// | Location | Before | After | +/// |------------------------|-------------------|--------| +/// | (on_entry) | {102} || +/// | Statement 0 | +0 | +1 | +/// | statement 1 | +2 | +3 | +/// | `Call` terminator | +4 | +5 | +/// | (on unwind) | {102,0,1,2,3,4,5} || +/// | (on successful return) | +6 || +/// +/// The `102` in the block's entry set is derived from the basic block index and ensures that the +/// expected state is unique across all basic blocks. Remember, it is generated by +/// `mock_entry_sets`, not from actually running `MockAnalysis` to fixpoint. +struct MockAnalysis<'tcx> { + body: &'tcx mir::Body<'tcx>, +} + +impl MockAnalysis<'tcx> { + const BASIC_BLOCK_OFFSET: usize = 100; + + /// The entry set for each `BasicBlock` is the ID of that block offset by a fixed amount to + /// avoid colliding with the statement/terminator effects. + fn mock_entry_set(self, bb: BasicBlock) -> BitSet { + let mut ret = BitSet::new_empty(self.bits_per_block(body)); + ret.insert(Self::BASIC_BLOCK_OFFSET + bb.index()); + ret + } + + fn mock_entry_sets(&self) -> IndexVec> { + let empty = BitSet::new_empty(self.bits_per_block(body)); + let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks()); + + for (bb, _) in self.body.basic_blocks().iter_enumerated() { + ret[bb] = self.mock_entry_set(bb); + } + + ret + } + + /// Returns the index that should be added to the dataflow state at the given target. + /// + /// This index is only unique within a given basic block. `SeekAfter` and + /// `SeekAfterAssumeCallReturns` have the same effect unless `target` is a `Call` terminator. + fn effect_at_target(&self, target: SeekTarget) -> Option { + use SeekTarget::*; + + let idx = match target { + BlockStart(_) => return None, + + AfterAssumeCallReturns(loc) if is_call_terminator_non_diverging(self.body, loc) => { + loc.statement_index * 2 + 2 + } + + Before(loc) => loc.statement_index * 2, + After(loc) | AfterAssumeCallReturns(loc) => loc.statement_index * 2 + 1, + }; + + assert!(idx < Self::BASIC_BLOCK_OFFSET, "Too many statements in basic block"); + Some(idx) + } + + /// Returns the expected state at the given `SeekTarget`. + /// + /// This is the union of index of the target basic block, the index assigned to the + /// target statement or terminator, and the indices of all preceding statements in the target + /// basic block. + /// + /// For example, the expected state when calling + /// `seek_before(Location { block: 2, statement_index: 2 })` would be `[102, 0, 1, 2, 3, 4]`. + fn expected_state_at_target(&self, target: SeekTarget) -> BitSet { + let mut ret = BitSet::new_empty(self.bits_per_block(self.body)); + ret.insert(Self::BASIC_BLOCK_OFFSET + target.block().index()); + + if let Some(target_effect) = self.effect_at_target(target) { + for i in 0..=target_effect { + ret.insert(i); + } + } + + ret + } +} + +impl BottomValue for MockAnalysis<'tcx> { + const BOTTOM_VALUE: bool = false; +} + +impl AnalysisDomain<'tcx> for MockAnalysis<'tcx> { + type Idx = usize; + + const NAME: &'static str = "mock"; + + fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize { + Self::BASIC_BLOCK_OFFSET + body.basic_blocks().len() + } + + fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut BitSet) { + unimplemented!("This is never called since `MockAnalysis` is never iterated to fixpoint"); + } +} + +impl Analysis<'tcx> for MockAnalysis<'tcx> { + fn apply_statement_effect( + &self, + state: &mut BitSet, + _statement: &mir::Statement<'tcx>, + location: Location, + ) { + let idx = SeekTarget::After(location).effect(self.body).unwrap(); + assert!(state.insert(idx)); + } + + fn apply_before_statement_effect( + &self, + state: &mut BitSet, + _statement: &mir::Statement<'tcx>, + location: Location, + ) { + let idx = SeekTarget::Before(location).effect(self.body).unwrap(); + assert!(state.insert(idx)); + } + + fn apply_terminator_effect( + &self, + state: &mut BitSet, + _terminator: &mir::Terminator<'tcx>, + location: Location, + ) { + let idx = SeekTarget::After(location).effect(self.body).unwrap(); + assert!(state.insert(idx)); + } + + fn apply_before_terminator_effect( + &self, + state: &mut BitSet, + _terminator: &mir::Terminator<'tcx>, + location: Location, + ) { + let idx = SeekTarget::Before(location).effect(self.body).unwrap(); + assert!(state.insert(idx)); + } + + fn apply_call_return_effect( + &self, + state: &mut BitSet, + block: BasicBlock, + _func: &mir::Operand<'tcx>, + _args: &[mir::Operand<'tcx>], + _return_place: &mir::Place<'tcx>, + ) { + let location = self.body.terminator_loc(block); + let idx = SeekTarget::AfterAssumeCallReturns(location).effect(self.body).unwrap(); + assert!(state.insert(idx)); + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum SeekTarget { + BlockStart(BasicBlock), + Before(Location), + After(Location), + AfterAssumeCallReturns(Location), +} + +impl SeekTarget { + fn block(&self) -> BasicBlock { + use SeekTarget::*; + + match *self { + BlockStart(block) => block, + Before(loc) | After(loc) | AfterAssumeCallReturns(loc) => loc.block, + } + } + + /// An iterator over all possible `SeekTarget`s in a given block in order, starting with + /// `BlockStart`. + /// + /// This includes both `After` and `AfterAssumeCallReturns` for every `Location`. + fn iter_in_block(body: &mir::Body<'_>, block: BasicBlock) -> impl Iterator { + let statements_and_terminator = (0..=body[block].statements.len()) + .flat_map(|i| (0..3).map(move |j| (i, j))) + .map(move |(i, kind)| { + let loc = Location { block, statement_index: i }; + match kind { + 0 => SeekTarget::Before(loc), + 1 => SeekTarget::After(loc), + 2 => SeekTarget::AfterAssumeCallReturns(loc), + _ => unreachable!(), + } + }); + + std::iter::once(SeekTarget::BlockStart(block)).chain(statements_and_terminator) + } +} + +#[test] +fn cursor_seek() { + let body = mock_body(); + let body = &body; + let analysis = MockAnalysis { body }; + + let mut cursor = Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_cursor(body); + + // Sanity check: the mock call return effect is unique and actually being applied. + let call_terminator_loc = Location { block: BasicBlock::from_usize(2), statement_index: 2 }; + assert!(is_call_terminator_non_diverging(body, call_terminator_loc)); + + let call_return_effect = cursor + .analysis() + .effect_at_target(SeekTarget::AfterAssumeCallReturns(call_terminator_loc)) + .unwrap(); + assert_ne!(call_return_effect, SeekTarget::After(call_terminator_loc).effect(body).unwrap()); + + cursor.seek_after(call_terminator_loc); + assert!(!cursor.get().contains(call_return_effect)); + cursor.seek_after_assume_call_returns(call_terminator_loc); + assert!(cursor.get().contains(call_return_effect)); + + let every_target = || { + body.basic_blocks() + .iter_enumerated() + .flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb)) + }; + + let mut seek_to_target = |targ| { + use SeekTarget::*; + + match targ { + BlockStart(block) => cursor.seek_to_block_start(block), + Before(loc) => cursor.seek_before(loc), + After(loc) => cursor.seek_after(loc), + AfterAssumeCallReturns(loc) => cursor.seek_after_assume_call_returns(loc), + } + + assert_eq!(cursor.get(), &cursor.analysis().expected_state_at_target(targ)); + }; + + // Seek *to* every possible `SeekTarget` *from* every possible `SeekTarget`. + // + // By resetting the cursor to `from` each time it changes, we end up checking some edges twice. + // What we really want is an Eulerian cycle for the complete digraph over all possible + // `SeekTarget`s, but it's not worth spending the time to compute it. + for from in every_target() { + seek_to_target(from); + + for to in every_target() { + seek_to_target(to); + seek_to_target(from); + } + } +} From 2727f10b216fc6ac7d3a22f216f55e46e9c99506 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 14 Jan 2020 14:52:54 -0800 Subject: [PATCH 0347/1253] Improve docs for new framework --- src/librustc_mir/dataflow/generic/mod.rs | 38 ++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index a80e7375482ed..bf18bc7a5d036 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -1,4 +1,36 @@ -//! A framework for expressing dataflow problems. +//! A framework that can express both [gen-kill] and generic dataflow problems. +//! +//! There is another interface for dataflow in the compiler in `librustc_mir/dataflow/mod.rs`. The +//! interface in this module will eventually [replace that one][design-meeting]. +//! +//! To actually use this framework, you must implement either the `Analysis` or the +//! `GenKillAnalysis` trait. If your transfer function can be expressed with only gen/kill +//! operations, prefer `GenKillAnalysis` as it will perform better. Create an `Engine` using the +//! appropriate constructor and call `iterate_to_fixpoint`. You can use a `ResultsCursor` to +//! inspect the fixpoint solution to your dataflow problem. +//! +//! ```ignore(cross-crate-imports) +//! fn do_my_analysis(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, did: DefId) { +//! let analysis = MyAnalysis::new(); +//! +//! // If `MyAnalysis` implements `GenKillAnalysis`. +//! let results = Engine::new_gen_kill(tcx, body, did, analysis).iterate_to_fixpoint(); +//! +//! // If `MyAnalysis` implements `Analysis`. +//! // let results = Engine::new_generic(tcx, body, did, analysis).iterate_to_fixpoint(); +//! +//! let mut cursor = ResultsCursor::new(body, results); +//! +//! for (_, statement_index) in body.block_data[START_BLOCK].statements.iter_enumerated() { +//! cursor.seek_after(Location { block: START_BLOCK, statement_index }); +//! let state = cursor.get(); +//! println!("{:?}", state); +//! } +//! } +//! ``` +//! +//! [gen-kill]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems +//! [design-meeting]https://github.com/rust-lang/compiler-team/issues/202 use std::io; @@ -68,7 +100,7 @@ pub trait AnalysisDomain<'tcx>: BottomValue { } } -/// Define a dataflow problem with an arbitrarily complex transfer function. +/// A dataflow problem with an arbitrarily complex transfer function. pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { /// Updates the current dataflow state with the effect of evaluating a statement. fn apply_statement_effect( @@ -134,7 +166,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { ); } -/// Define a gen/kill dataflow problem. +/// A gen/kill dataflow problem. /// /// Each method in this trait has a corresponding one in `Analysis`. However, these methods only /// allow modification of the dataflow state via "gen" and "kill" operations. By defining transfer From b70898d5eeb9f7fc994035eb90b609c49f53f745 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 14 Jan 2020 15:05:16 -0800 Subject: [PATCH 0348/1253] Improve docs for `GenKill` and `GenKillSet` --- src/librustc_mir/dataflow/generic/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index bf18bc7a5d036..09ca72e75b651 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -273,21 +273,19 @@ where } /// The legal operations for a transfer function in a gen/kill problem. -pub trait GenKill: Sized { - /// Inserts `elem` into the `gen` set, removing it the `kill` set if present. +pub trait GenKill { + /// Inserts `elem` into the state vector. fn gen(&mut self, elem: T); - /// Inserts `elem` into the `kill` set, removing it the `gen` set if present. + /// Removes `elem` from the state vector. fn kill(&mut self, elem: T); - /// Inserts the given elements into the `gen` set, removing them from the `kill` set if present. fn gen_all(&mut self, elems: impl IntoIterator) { for elem in elems { self.gen(elem); } } - /// Inserts the given elements into the `kill` set, removing them from the `gen` set if present. fn kill_all(&mut self, elems: impl IntoIterator) { for elem in elems { self.kill(elem); @@ -296,6 +294,10 @@ pub trait GenKill: Sized { } /// Stores a transfer function for a gen/kill problem. +/// +/// Calling `gen`/`kill` on a `GenKillSet` will "build up" a transfer function so that it can be +/// applied to a state vector efficiently. When there are multiple calls to `gen` and/or `kill` for +/// the same element, the most recent one takes precedence. #[derive(Clone)] pub struct GenKillSet { gen: HybridBitSet, @@ -311,7 +313,7 @@ impl GenKillSet { } } - /// Applies this transfer function to the given bitset. + /// Applies this transfer function to the given state vector. pub fn apply(&self, state: &mut BitSet) { state.union(&self.gen); state.subtract(&self.kill); From 268a1ff3fbd234ecdacf8b2ac0985f18d91c9851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 16:18:21 -0800 Subject: [PATCH 0349/1253] Account for `Path`s on `is_suggestable_infer_ty` Fix #68162. --- src/librustc_typeck/collect.rs | 27 ++++-- .../ui/typeck/typeck_type_placeholder_item.rs | 7 ++ .../typeck_type_placeholder_item.stderr | 97 +++++++++++-------- 3 files changed, 86 insertions(+), 45 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ad750d5ab8341..dca3289747e4c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1806,6 +1806,16 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } +fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool { + generic_args + .iter() + .filter_map(|arg| match arg { + hir::GenericArg::Type(ty) => Some(ty), + _ => None, + }) + .any(is_suggestable_infer_ty) +} + /// Whether `ty` is a type with `_` placeholders that can be infered. Used in diagnostics only to /// use inference to provide suggestions for the appropriate type if possible. fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { @@ -1815,13 +1825,16 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty), Tup(tys) => tys.iter().any(is_suggestable_infer_ty), Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), - Def(_, generic_args) => generic_args - .iter() - .filter_map(|arg| match arg { - hir::GenericArg::Type(ty) => Some(ty), - _ => None, - }) - .any(is_suggestable_infer_ty), + Def(_, generic_args) => are_suggestable_generic_args(generic_args), + Path(hir::QPath::TypeRelative(ty, segment)) => { + is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args) + } + Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => { + ty_opt.map_or(false, is_suggestable_infer_ty) + || segments + .iter() + .any(|segment| are_suggestable_generic_args(segment.generic_args().args)) + } _ => false, } } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index adecbd7e5b40e..86c7c52b27166 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -68,6 +68,13 @@ struct Test10 { } pub fn main() { + static A = 42; + //~^ ERROR missing type for `static` item + static B: _ = 42; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + static C: Option<_> = Some(42); + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn fn_test() -> _ { 5 } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 05326a3e07a93..f740a9f7f34b1 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:146:18 + --> $DIR/typeck_type_placeholder_item.rs:153:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:149:16 + --> $DIR/typeck_type_placeholder_item.rs:156:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:159:19 + --> $DIR/typeck_type_placeholder_item.rs:166:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:159:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:164:19 + --> $DIR/typeck_type_placeholder_item.rs:171:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:159:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -177,8 +177,29 @@ LL | LL | b: (T, T), | +error: missing type for `static` item + --> $DIR/typeck_type_placeholder_item.rs:71:12 + | +LL | static A = 42; + | ^ help: provide a type for the item: `A: i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:73:15 + | +LL | static B: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:75:15 + | +LL | static C: Option<_> = Some(42); + | ^^^^^^^^^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:71:21 + --> $DIR/typeck_type_placeholder_item.rs:78:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -187,7 +208,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:74:23 + --> $DIR/typeck_type_placeholder_item.rs:81:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -197,7 +218,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:77:22 + --> $DIR/typeck_type_placeholder_item.rs:84:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -206,7 +227,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:80:22 + --> $DIR/typeck_type_placeholder_item.rs:87:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -215,13 +236,13 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:83:22 + --> $DIR/typeck_type_placeholder_item.rs:90:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:86:20 + --> $DIR/typeck_type_placeholder_item.rs:93:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -232,7 +253,7 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:89:20 + --> $DIR/typeck_type_placeholder_item.rs:96:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -243,13 +264,13 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:29 + --> $DIR/typeck_type_placeholder_item.rs:99:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:29 + --> $DIR/typeck_type_placeholder_item.rs:99:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -260,7 +281,7 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:115:12 + --> $DIR/typeck_type_placeholder_item.rs:122:12 | LL | a: _, | ^ not allowed in type signatures @@ -279,13 +300,13 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:120:27 + --> $DIR/typeck_type_placeholder_item.rs:127:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^^^^^^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:120:28 + --> $DIR/typeck_type_placeholder_item.rs:127:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -293,7 +314,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:124:30 + --> $DIR/typeck_type_placeholder_item.rs:131:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -303,7 +324,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:33 + --> $DIR/typeck_type_placeholder_item.rs:134:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -312,7 +333,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:21 + --> $DIR/typeck_type_placeholder_item.rs:153:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -323,7 +344,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:151:15 + --> $DIR/typeck_type_placeholder_item.rs:158:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -336,13 +357,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:154:34 + --> $DIR/typeck_type_placeholder_item.rs:161:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:159:25 + --> $DIR/typeck_type_placeholder_item.rs:166:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -353,7 +374,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:164:25 + --> $DIR/typeck_type_placeholder_item.rs:171:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -364,7 +385,7 @@ LL | struct BadStruct2(K, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:168:14 + --> $DIR/typeck_type_placeholder_item.rs:175:14 | LL | type X = Box<_>; | ^ not allowed in type signatures @@ -381,7 +402,7 @@ LL | fn test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:132:31 + --> $DIR/typeck_type_placeholder_item.rs:139:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -392,7 +413,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:134:31 + --> $DIR/typeck_type_placeholder_item.rs:141:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -405,7 +426,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:136:31 + --> $DIR/typeck_type_placeholder_item.rs:143:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -416,7 +437,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:138:26 + --> $DIR/typeck_type_placeholder_item.rs:145:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -427,7 +448,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:140:26 + --> $DIR/typeck_type_placeholder_item.rs:147:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -440,7 +461,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:142:28 + --> $DIR/typeck_type_placeholder_item.rs:149:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -462,7 +483,7 @@ LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:102:34 + --> $DIR/typeck_type_placeholder_item.rs:109:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -473,7 +494,7 @@ LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:110:41 + --> $DIR/typeck_type_placeholder_item.rs:117:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -484,7 +505,7 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:174:21 + --> $DIR/typeck_type_placeholder_item.rs:181:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures @@ -508,7 +529,7 @@ LL | fn clone(&self) -> _ { Test9 } | help: replace with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:31 + --> $DIR/typeck_type_placeholder_item.rs:106:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -517,7 +538,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:107:28 + --> $DIR/typeck_type_placeholder_item.rs:114:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -525,7 +546,7 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `main::FnTest9` -error: aborting due to 55 previous errors +error: aborting due to 58 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. From f76177ce4376ea15b1b303da347e8f653679cf88 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Tue, 14 Jan 2020 16:45:11 -0500 Subject: [PATCH 0350/1253] Stabilize ptr::slice_from_raw_parts[_mut] --- src/liballoc/lib.rs | 1 - src/libcore/ptr/mod.rs | 11 +++++------ src/libcore/tests/lib.rs | 1 - 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index fdabf109b2ead..38c6fa91cc55c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -104,7 +104,6 @@ #![feature(ptr_offset_from)] #![feature(rustc_attrs)] #![feature(receiver_trait)] -#![feature(slice_from_raw_parts)] #![feature(specialization)] #![feature(staged_api)] #![feature(std_internals)] diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index d7b351f13458a..80f865d79e49a 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -248,17 +248,16 @@ pub(crate) struct FatPtr { /// # Examples /// /// ```rust -/// #![feature(slice_from_raw_parts)] /// use std::ptr; /// /// // create a slice pointer when starting out with a pointer to the first element -/// let mut x = [5, 6, 7]; -/// let ptr = &mut x[0] as *mut _; -/// let slice = ptr::slice_from_raw_parts_mut(ptr, 3); +/// let x = [5, 6, 7]; +/// let ptr = &x[0] as *const _; +/// let slice = ptr::slice_from_raw_parts(ptr, 3); /// assert_eq!(unsafe { &*slice }[2], 7); /// ``` #[inline] -#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")] +#[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { unsafe { Repr { raw: FatPtr { data, len } }.rust } @@ -275,7 +274,7 @@ pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { /// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html /// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html #[inline] -#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")] +#[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 39f6133f2a689..6cd1f1e03278c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -37,7 +37,6 @@ #![feature(iter_is_partitioned)] #![feature(iter_order_by)] #![feature(cmp_min_max_by)] -#![feature(slice_from_raw_parts)] #![feature(const_slice_from_raw_parts)] #![feature(const_raw_ptr_deref)] From 1006ad036a447f23b2f9f88a300bf56d7bcf8b64 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 14 Jan 2020 18:43:31 -0800 Subject: [PATCH 0351/1253] Fix test --- src/librustc_mir/dataflow/generic/tests.rs | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/tests.rs b/src/librustc_mir/dataflow/generic/tests.rs index add9bfd03a818..cc339cf8ce955 100644 --- a/src/librustc_mir/dataflow/generic/tests.rs +++ b/src/librustc_mir/dataflow/generic/tests.rs @@ -4,6 +4,7 @@ use rustc::mir::{self, BasicBlock, Location}; use rustc::ty; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; +use rustc_span::DUMMY_SP; use super::*; use crate::dataflow::BottomValue; @@ -23,8 +24,7 @@ fn is_call_terminator_non_diverging(body: &mir::Body<'_>, loc: Location) -> bool /// This is the `Body` that will be used by the `MockAnalysis` below. The shape of its CFG is not /// important. fn mock_body() -> mir::Body<'static> { - let span = syntax_pos::DUMMY_SP; - let source_info = mir::SourceInfo { scope: mir::OUTERMOST_SOURCE_SCOPE, span }; + let source_info = mir::SourceInfo { scope: mir::OUTERMOST_SOURCE_SCOPE, span: DUMMY_SP }; let mut blocks = IndexVec::new(); let mut block = |n, kind| { @@ -97,14 +97,14 @@ impl MockAnalysis<'tcx> { /// The entry set for each `BasicBlock` is the ID of that block offset by a fixed amount to /// avoid colliding with the statement/terminator effects. - fn mock_entry_set(self, bb: BasicBlock) -> BitSet { - let mut ret = BitSet::new_empty(self.bits_per_block(body)); + fn mock_entry_set(&self, bb: BasicBlock) -> BitSet { + let mut ret = BitSet::new_empty(self.bits_per_block(self.body)); ret.insert(Self::BASIC_BLOCK_OFFSET + bb.index()); ret } fn mock_entry_sets(&self) -> IndexVec> { - let empty = BitSet::new_empty(self.bits_per_block(body)); + let empty = BitSet::new_empty(self.bits_per_block(self.body)); let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks()); for (bb, _) in self.body.basic_blocks().iter_enumerated() { @@ -183,7 +183,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - let idx = SeekTarget::After(location).effect(self.body).unwrap(); + let idx = self.effect_at_target(SeekTarget::After(location)).unwrap(); assert!(state.insert(idx)); } @@ -193,7 +193,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - let idx = SeekTarget::Before(location).effect(self.body).unwrap(); + let idx = self.effect_at_target(SeekTarget::Before(location)).unwrap(); assert!(state.insert(idx)); } @@ -203,7 +203,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { _terminator: &mir::Terminator<'tcx>, location: Location, ) { - let idx = SeekTarget::After(location).effect(self.body).unwrap(); + let idx = self.effect_at_target(SeekTarget::After(location)).unwrap(); assert!(state.insert(idx)); } @@ -213,7 +213,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { _terminator: &mir::Terminator<'tcx>, location: Location, ) { - let idx = SeekTarget::Before(location).effect(self.body).unwrap(); + let idx = self.effect_at_target(SeekTarget::Before(location)).unwrap(); assert!(state.insert(idx)); } @@ -226,7 +226,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { _return_place: &mir::Place<'tcx>, ) { let location = self.body.terminator_loc(block); - let idx = SeekTarget::AfterAssumeCallReturns(location).effect(self.body).unwrap(); + let idx = self.effect_at_target(SeekTarget::AfterAssumeCallReturns(location)).unwrap(); assert!(state.insert(idx)); } } @@ -286,7 +286,10 @@ fn cursor_seek() { .analysis() .effect_at_target(SeekTarget::AfterAssumeCallReturns(call_terminator_loc)) .unwrap(); - assert_ne!(call_return_effect, SeekTarget::After(call_terminator_loc).effect(body).unwrap()); + assert_ne!( + call_return_effect, + cursor.analysis().effect_at_target(SeekTarget::After(call_terminator_loc)).unwrap() + ); cursor.seek_after(call_terminator_loc); assert!(!cursor.get().contains(call_return_effect)); From 6801cf436bf3549db72c364a912da43ac38d0e79 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 15 Jan 2020 11:52:21 +0530 Subject: [PATCH 0352/1253] Update E0170.md --- src/librustc_error_codes/error_codes/E0170.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0170.md b/src/librustc_error_codes/error_codes/E0170.md index 56e1b5aa241d2..9678cd173b7ca 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/src/librustc_error_codes/error_codes/E0170.md @@ -1,4 +1,4 @@ -A pattern binding is using the same name as one of the variants a type. +A pattern binding is using the same name as one of the variants of a type. Erroneous code example: From 4eb47ded54610300c54291aee74d5585a711e75b Mon Sep 17 00:00:00 2001 From: csmoe Date: Wed, 15 Jan 2020 15:13:51 +0800 Subject: [PATCH 0353/1253] wrap expr id into GeneratorInteriorTypeCause --- src/librustc/traits/error_reporting.rs | 7 +++---- src/librustc/ty/context.rs | 7 ++++--- .../check/generator_interior.rs | 21 ++++++++++++------- src/test/ui/generator/not-send-sync.stderr | 2 +- .../recursive-impl-trait-type-indirect.stderr | 4 ++-- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index aaad0be9a048c..c1df1149bbdfc 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { + .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we // want to erase them when comparing (and anyway, @@ -2479,7 +2479,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); eq }) - .map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| { + .map(|ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. }| { (span, source_map.span_to_snippet(*span), scope_span, expr) }); @@ -2585,8 +2585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; // Look at the last interior type to get a span for the `.await`. - let await_span = - tables.generator_interior_types.iter().map(|(i, _)| i.span).last().unwrap(); + let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap(); let mut span = MultiSpan::from_span(await_span); span.push_span_label( await_span, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d64e049c47b54..ef776c88a8f7c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -315,8 +315,7 @@ pub struct ResolvedOpaqueTy<'tcx> { /// /// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for /// the scope that contains `x`. -#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq)] -#[derive(HashStable, TypeFoldable)] +#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)] pub struct GeneratorInteriorTypeCause<'tcx> { /// Type of the captured binding. pub ty: Ty<'tcx>, @@ -324,6 +323,8 @@ pub struct GeneratorInteriorTypeCause<'tcx> { pub span: Span, /// Span of the scope of the captured binding. pub scope_span: Option, + /// Expr which the type evaluated from. + pub expr: Option, } #[derive(RustcEncodable, RustcDecodable, Debug)] @@ -438,7 +439,7 @@ pub struct TypeckTables<'tcx> { /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec<(GeneratorInteriorTypeCause<'tcx>, Option)>, + pub generator_interior_types: Vec>, } impl<'tcx> TypeckTables<'tcx> { diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 7185de76fcbb6..fc02d17a50f37 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -18,7 +18,6 @@ use rustc_span::Span; struct InteriorVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, types: FxHashMap, usize>, - exprs: Vec>, region_scope_tree: &'tcx region::ScopeTree, expr_count: usize, kind: hir::GeneratorKind, @@ -98,9 +97,9 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { span: source_span, ty: &ty, scope_span, + expr: expr.map(|e| e.hir_id), }) .or_insert(entries); - self.exprs.push(expr.map(|e| e.hir_id)); } } else { debug!( @@ -138,7 +137,6 @@ pub fn resolve_interior<'a, 'tcx>( expr_count: 0, kind, prev_unresolved_span: None, - exprs: vec![], }; intravisit::walk_body(&mut visitor, body); @@ -167,18 +165,25 @@ pub fn resolve_interior<'a, 'tcx>( // which means that none of the regions inside relate to any other, even if // typeck had previously found constraints that would cause them to be related. let mut counter = 0; - let types = fcx.tcx.fold_regions(&types, &mut false, |_, current_depth| { + let fold_types: Vec<_> = types.iter().map(|(t, _)| t.ty).collect(); + let folded_types = fcx.tcx.fold_regions(&fold_types, &mut false, |_, current_depth| { counter += 1; fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter))) }); // Store the generator types and spans into the tables for this generator. - let interior_types = - types.iter().zip(visitor.exprs).map(|(t, e)| (t.0.clone(), e)).collect::>(); - visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types; + let types = types + .into_iter() + .zip(&folded_types) + .map(|((mut interior_cause, _), ty)| { + interior_cause.ty = ty; + interior_cause + }) + .collect(); + visitor.fcx.inh.tables.borrow_mut().generator_interior_types = types; // Extract type components - let type_list = fcx.tcx.mk_type_list(types.into_iter().map(|t| (t.0).ty)); + let type_list = fcx.tcx.mk_type_list(folded_types.iter()); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 0ac1d189b79b0..18d9012b3acf6 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -20,7 +20,7 @@ LL | fn assert_sync(_: T) {} LL | assert_sync(|| { | ^^^^^^^^^^^ future returned by `main` is not `Sync` | - = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` + = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, (), ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` note: future is not `Sync` as this value is used across an yield --> $DIR/not-send-sync.rs:12:9 | diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr index b7ba0d6ab177c..15a028f60ae11 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr @@ -76,7 +76,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_capture() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {(), ()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:53:26 @@ -92,7 +92,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_hold() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, ()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, (), ()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:69:26 From 0e14b9ff268b6987f935847d7857969a69b7ee7d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 10:30:26 +0100 Subject: [PATCH 0354/1253] Add tests --- src/test/ui/consts/huge-values.rs | 6 +++++ src/test/ui/consts/validate_never_arrays.rs | 6 ++++- .../ui/consts/validate_never_arrays.stderr | 22 ++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/test/ui/consts/huge-values.rs b/src/test/ui/consts/huge-values.rs index ab09922d7614a..70a5b10e9be99 100644 --- a/src/test/ui/consts/huge-values.rs +++ b/src/test/ui/consts/huge-values.rs @@ -1,6 +1,10 @@ // build-pass // ignore-32bit +// This test is a canary test that will essentially not compile in a reasonable time frame +// (so it'll take hours) if any of the optimizations regress. With the optimizations, these compile +// in milliseconds just as if the length were set to `1`. + #[derive(Clone, Copy)] struct Foo; @@ -8,4 +12,6 @@ fn main() { let _ = [(); 4_000_000_000]; let _ = [0u8; 4_000_000_000]; let _ = [Foo; 4_000_000_000]; + let _ = [(Foo, (), Foo, ((), Foo, [0; 0])); 4_000_000_000]; + let _ = [[0; 0]; 4_000_000_000]; } diff --git a/src/test/ui/consts/validate_never_arrays.rs b/src/test/ui/consts/validate_never_arrays.rs index 9610b7b22f161..c7144f05ec7a4 100644 --- a/src/test/ui/consts/validate_never_arrays.rs +++ b/src/test/ui/consts/validate_never_arrays.rs @@ -1,5 +1,9 @@ #![feature(const_raw_ptr_deref, never_type)] -const FOO: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!; 0] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; //~ ERROR undefined behavior fn main() {} diff --git a/src/test/ui/consts/validate_never_arrays.stderr b/src/test/ui/consts/validate_never_arrays.stderr index c4c7a33718279..cb995b8216f4e 100644 --- a/src/test/ui/consts/validate_never_arrays.stderr +++ b/src/test/ui/consts/validate_never_arrays.stderr @@ -1,11 +1,27 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/validate_never_arrays.rs:3:1 | -LL | const FOO: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at . +LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at . | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. -error: aborting due to previous error +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:6:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:7:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. From 10f439a0116df86f737d83cc620289b14c88660f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 25 Dec 2019 13:58:02 +0100 Subject: [PATCH 0355/1253] Promoteds can contain raw pointers, but these must still only point to immutable allocations --- src/librustc_mir/const_eval.rs | 4 +- src/librustc_mir/const_eval/eval_queries.rs | 13 ++++-- src/librustc_mir/interpret/intern.rs | 46 ++++++++++++++++----- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 8 ++-- src/test/ui/consts/raw_pointer_promoted.rs | 5 +++ 6 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/consts/raw_pointer_promoted.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index aa7be3d80e1dc..aad0e1629359a 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -5,7 +5,7 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::{self, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; -use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx}; +use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx}; mod error; mod eval_queries; @@ -52,7 +52,7 @@ pub(crate) fn const_caller_location<'tcx>( let loc_ty = tcx.caller_location_ty(); let loc_place = ecx.alloc_caller_location(file, line, col); - intern_const_alloc_recursive(&mut ecx, None, loc_place, false).unwrap(); + intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place, false).unwrap(); let loc_const = ty::Const { ty: loc_ty, val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())), diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index d260a6808d120..442baf85f2baf 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -1,9 +1,9 @@ use super::{error_to_const_error, CompileTimeEvalContext, CompileTimeInterpreter, MemoryExtra}; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InterpCx, - InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, ScalarMaybeUndef, - StackPopCleanup, + intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InternKind, + InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, + ScalarMaybeUndef, StackPopCleanup, }; use rustc::mir; use rustc::mir::interpret::{ConstEvalErr, ErrorHandled}; @@ -56,9 +56,14 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.run()?; // Intern the result + let intern_kind = match tcx.static_mutability(cid.instance.def_id()) { + Some(m) => InternKind::Static(m), + None if cid.promoted.is_some() => InternKind::Promoted, + _ => InternKind::Constant, + }; intern_const_alloc_recursive( ecx, - tcx.static_mutability(cid.instance.def_id()), + intern_kind, ret, body.ignore_interior_mut_in_const_validation, )?; diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 220761ce28d81..8ff78ffb5baf9 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -268,19 +268,27 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx } } +pub enum InternKind { + /// The `mutability` of the static, ignoring the type which may have interior mutability. + Static(hir::Mutability), + Constant, + Promoted, + ConstProp, +} + pub fn intern_const_alloc_recursive>( ecx: &mut InterpCx<'mir, 'tcx, M>, - // The `mutability` of the place, ignoring the type. - place_mut: Option, + intern_kind: InternKind, ret: MPlaceTy<'tcx>, ignore_interior_mut_in_const_validation: bool, ) -> InterpResult<'tcx> { let tcx = ecx.tcx; - let (base_mutability, base_intern_mode) = match place_mut { + let (base_mutability, base_intern_mode) = match intern_kind { // `static mut` doesn't care about interior mutability, it's mutable anyway - Some(mutbl) => (mutbl, InternMode::Static), - // consts, promoteds. FIXME: what about array lengths, array initializers? - None => (Mutability::Not, InternMode::ConstBase), + InternKind::Static(mutbl) => (mutbl, InternMode::Static), + // FIXME: what about array lengths, array initializers? + InternKind::Constant | InternKind::ConstProp => (Mutability::Not, InternMode::ConstBase), + InternKind::Promoted => (Mutability::Not, InternMode::ConstBase), }; // Type based interning. @@ -338,10 +346,23 @@ pub fn intern_const_alloc_recursive>( // We can't call the `intern_shallow` method here, as its logic is tailored to safe // references and a `leftover_allocations` set (where we only have a todo-list here). // So we hand-roll the interning logic here again. - match base_intern_mode { - InternMode::Static => {} - InternMode::Const | InternMode::ConstBase => { - // If it's not a static, it *must* be immutable. + match intern_kind { + // Mutable statics may contain mutable allocations even behind relocations + InternKind::Static(hir::Mutability::Mut) => {} + // Once we get heap allocations we need to revisit whether immutable statics can + // refer to mutable (e.g. via interior mutability) allocations. + InternKind::Static(hir::Mutability::Not) => { + alloc.mutability = Mutability::Not; + } + // Raw pointers in promoteds may only point to immutable things so we mark + // everything as immutable. Creating a promoted with interior mutability is UB, but + // there's no way we can check whether the user is using raw pointers correctly. + // So all we can do is mark this as immutable here. + InternKind::Promoted => { + alloc.mutability = Mutability::Not; + } + InternKind::Constant | InternKind::ConstProp => { + // If it's a constant, it *must* be immutable. // We cannot have mutable memory inside a constant. // We use `delay_span_bug` here, because this can be reached in the presence // of fancy transmutes. @@ -363,7 +384,10 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) - } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() { + } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { + // FIXME: check if the allocation is ok as per the interning rules as if we interned + // it right here. + } else { span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 2e8fbb95ca2e5..a519f38e71208 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -32,6 +32,6 @@ pub use self::visitor::{MutValueVisitor, ValueVisitor}; pub use self::validity::RefTracking; -pub use self::intern::intern_const_alloc_recursive; +pub use self::intern::{intern_const_alloc_recursive, InternKind}; crate use self::intrinsics::eval_nullary_intrinsic; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..7dd82e6a6f9dc 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -29,9 +29,9 @@ use syntax::ast::Mutability; use crate::const_eval::error_to_const_error; use crate::interpret::{ - self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx, - LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, - ScalarMaybeUndef, StackPopCleanup, + self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InternKind, + InterpCx, LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, + Pointer, ScalarMaybeUndef, StackPopCleanup, }; use crate::transform::{MirPass, MirSource}; @@ -726,7 +726,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { )) => l.is_bits() && r.is_bits(), interpret::Operand::Indirect(_) if mir_opt_level >= 2 => { let mplace = op.assert_mem_place(&self.ecx); - intern_const_alloc_recursive(&mut self.ecx, None, mplace, false) + intern_const_alloc_recursive(&mut self.ecx, InternKind::ConstProp, mplace, false) .expect("failed to intern alloc"); true } diff --git a/src/test/ui/consts/raw_pointer_promoted.rs b/src/test/ui/consts/raw_pointer_promoted.rs new file mode 100644 index 0000000000000..4c62ad444a512 --- /dev/null +++ b/src/test/ui/consts/raw_pointer_promoted.rs @@ -0,0 +1,5 @@ +// check-pass + +pub const FOO: &'static *const i32 = &(&0 as _); + +fn main() {} From 658c27b011b88dff18fd0137559123991a05f380 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 26 Dec 2019 00:30:02 +0100 Subject: [PATCH 0356/1253] Elaborate on comments --- src/librustc_mir/interpret/intern.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 8ff78ffb5baf9..4c7dab338ab25 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -351,6 +351,9 @@ pub fn intern_const_alloc_recursive>( InternKind::Static(hir::Mutability::Mut) => {} // Once we get heap allocations we need to revisit whether immutable statics can // refer to mutable (e.g. via interior mutability) allocations. + // Note: this is never the base value of the static, we can only get here for + // pointers encountered inside the base allocation, and then only for ones not at + // reference type, as that is checked by the type based main interner. InternKind::Static(hir::Mutability::Not) => { alloc.mutability = Mutability::Not; } @@ -385,6 +388,17 @@ pub fn intern_const_alloc_recursive>( // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { + // If we encounter an `AllocId` that points to a mutable `Allocation`, + // (directly or via relocations in its `Allocation`), we should panic, + // the static rules should prevent this. + // We may hit an `AllocId` that belongs to an already interned static, + // and are thus not interning any further. + // But since we are also checking things during interning, + // we should probably continue doing those checks no matter what we encounter. + + // E.g. this should be unreachable for `InternKind::Promoted` except for allocations + // created for string and byte string literals. + // FIXME: check if the allocation is ok as per the interning rules as if we interned // it right here. } else { From 1ea44663c562ac40fbb81f59698e3861d622695b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 8 Jan 2020 10:16:47 +0100 Subject: [PATCH 0357/1253] Elaborate on the details in some comments --- src/librustc_mir/interpret/intern.rs | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 4c7dab338ab25..6008834a5731c 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -361,6 +361,9 @@ pub fn intern_const_alloc_recursive>( // everything as immutable. Creating a promoted with interior mutability is UB, but // there's no way we can check whether the user is using raw pointers correctly. // So all we can do is mark this as immutable here. + // It is UB to mutate through a raw pointer obtained via an immutable reference. + // Since all references and pointers inside a promoted must by their very definition + // be created from an immutable reference, mutating though them would be UB. InternKind::Promoted => { alloc.mutability = Mutability::Not; } @@ -388,19 +391,27 @@ pub fn intern_const_alloc_recursive>( // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { - // If we encounter an `AllocId` that points to a mutable `Allocation`, - // (directly or via relocations in its `Allocation`), we should panic, - // the static rules should prevent this. - // We may hit an `AllocId` that belongs to an already interned static, + // We have hit an `AllocId` that belongs to an already interned static, // and are thus not interning any further. - // But since we are also checking things during interning, - // we should probably continue doing those checks no matter what we encounter. // E.g. this should be unreachable for `InternKind::Promoted` except for allocations - // created for string and byte string literals. + // created for string and byte string literals, since these are interned immediately + // at creation time. - // FIXME: check if the allocation is ok as per the interning rules as if we interned - // it right here. + // FIXME(oli-obk): Since we are also checking things during interning, + // we should probably continue doing those checks no matter what we encounter. + // So we basically have to check if the allocation is ok as per the interning rules as + // if we interned it right here. + // This should be as simple as + /* + for &(_, ((), reloc)) in alloc.relocations().iter() { + if leftover_allocations.insert(reloc) { + todo.push(reloc); + } + } + */ + // But I (oli-obk) haven't thought about the ramnificatons yet. This also would cause + // compile-time regressions, so we should think about caching these. } else { span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } From eadfd63e3fc136aee68fa32e98ea91213ef2e075 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 17:14:54 +0100 Subject: [PATCH 0358/1253] Clean up comment --- src/librustc_mir/interpret/intern.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 6008834a5731c..0cafd7cbbc0d6 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -358,12 +358,12 @@ pub fn intern_const_alloc_recursive>( alloc.mutability = Mutability::Not; } // Raw pointers in promoteds may only point to immutable things so we mark - // everything as immutable. Creating a promoted with interior mutability is UB, but - // there's no way we can check whether the user is using raw pointers correctly. - // So all we can do is mark this as immutable here. + // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition // be created from an immutable reference, mutating though them would be UB. + // There's no way we can check whether the user is using raw pointers correctly, + // so all we can do is mark this as immutable here. InternKind::Promoted => { alloc.mutability = Mutability::Not; } @@ -394,7 +394,7 @@ pub fn intern_const_alloc_recursive>( // We have hit an `AllocId` that belongs to an already interned static, // and are thus not interning any further. - // E.g. this should be unreachable for `InternKind::Promoted` except for allocations + // For `InternKind::Promoted` this is only reachable for allocations // created for string and byte string literals, since these are interned immediately // at creation time. From b2c43dc1adcf1d264b981a506b1840ba42eeea7f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 11 Jan 2020 14:45:00 +0100 Subject: [PATCH 0359/1253] Update src/librustc_mir/interpret/intern.rs Co-Authored-By: Ralf Jung --- src/librustc_mir/interpret/intern.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 0cafd7cbbc0d6..6fd15cc79a22a 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -361,7 +361,8 @@ pub fn intern_const_alloc_recursive>( // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition - // be created from an immutable reference, mutating though them would be UB. + // be created from an immutable reference (and promotion also excludes interior + // mutability), mutating though them would be UB. // There's no way we can check whether the user is using raw pointers correctly, // so all we can do is mark this as immutable here. InternKind::Promoted => { From a81784a09a084e63add1e4618dd82e8a7035c4f5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 11 Jan 2020 15:01:58 +0100 Subject: [PATCH 0360/1253] Undo a change not neceesary for this bugfix --- src/librustc_mir/interpret/intern.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 6fd15cc79a22a..68ac945ca89a9 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -347,16 +347,10 @@ pub fn intern_const_alloc_recursive>( // references and a `leftover_allocations` set (where we only have a todo-list here). // So we hand-roll the interning logic here again. match intern_kind { - // Mutable statics may contain mutable allocations even behind relocations - InternKind::Static(hir::Mutability::Mut) => {} - // Once we get heap allocations we need to revisit whether immutable statics can - // refer to mutable (e.g. via interior mutability) allocations. - // Note: this is never the base value of the static, we can only get here for - // pointers encountered inside the base allocation, and then only for ones not at - // reference type, as that is checked by the type based main interner. - InternKind::Static(hir::Mutability::Not) => { - alloc.mutability = Mutability::Not; - } + // Statics may contain mutable allocations even behind relocations. + // Even for immutable statics it would be ok to have mutable allocations behind + // raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`. + InternKind::Static(_) => {} // Raw pointers in promoteds may only point to immutable things so we mark // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. From 7bd01ed3c46183253dd0c28d9efa8678c426599e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 11:33:49 +0100 Subject: [PATCH 0361/1253] Typo --- src/librustc_mir/interpret/intern.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 68ac945ca89a9..cb028d286fa3d 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -356,7 +356,7 @@ pub fn intern_const_alloc_recursive>( // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition // be created from an immutable reference (and promotion also excludes interior - // mutability), mutating though them would be UB. + // mutability), mutating through them would be UB. // There's no way we can check whether the user is using raw pointers correctly, // so all we can do is mark this as immutable here. InternKind::Promoted => { From 69ffe7bb1314ccfdbde419d242cf636413dfd5f6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 11:36:06 +0100 Subject: [PATCH 0362/1253] Address review comments --- src/librustc_mir/interpret/intern.rs | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index cb028d286fa3d..0c65b77a38240 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -385,29 +385,9 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) - } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { - // We have hit an `AllocId` that belongs to an already interned static, - // and are thus not interning any further. - - // For `InternKind::Promoted` this is only reachable for allocations - // created for string and byte string literals, since these are interned immediately - // at creation time. - - // FIXME(oli-obk): Since we are also checking things during interning, - // we should probably continue doing those checks no matter what we encounter. - // So we basically have to check if the allocation is ok as per the interning rules as - // if we interned it right here. - // This should be as simple as - /* - for &(_, ((), reloc)) in alloc.relocations().iter() { - if leftover_allocations.insert(reloc) { - todo.push(reloc); - } - } - */ - // But I (oli-obk) haven't thought about the ramnificatons yet. This also would cause - // compile-time regressions, so we should think about caching these. - } else { + } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() { + // We have hit an `AllocId` that is neither in local or global memory and isn't marked + // as dangling by local memory. span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } From 12f029b7eecc01a38fbeec0eebe9041aa1bab7a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 02:07:13 +0100 Subject: [PATCH 0363/1253] Fix deref impl on type alias --- src/librustdoc/clean/inline.rs | 18 ++++++++++++ src/librustdoc/clean/mod.rs | 24 ++++++++++++++-- src/librustdoc/clean/types.rs | 8 ++++++ src/librustdoc/html/render.rs | 24 +++++++++++----- src/librustdoc/html/render/cache.rs | 43 +++++++++++++++++------------ 5 files changed, 90 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..fc75bf35b250d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -273,6 +273,24 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef { clean::Typedef { type_: cx.tcx.type_of(did).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx), + item_type: build_type_alias_type(cx, did), + } +} + +fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option { + let type_ = cx.tcx.type_of(did).clean(cx); + type_.def_id().and_then(|did| build_ty(cx, did)) +} + +pub fn build_ty(cx: &DocContext, did: DefId) -> Option { + match cx.tcx.def_kind(did)? { + DefKind::Struct | + DefKind::Union | + DefKind::Enum | + DefKind::Const | + DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::TyAlias => build_type_alias_type(cx, did), + _ => None, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index be9654612f504..0cc4c55f49be8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1122,7 +1122,16 @@ impl Clean for hir::ImplItem<'_> { MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) } hir::ImplItemKind::TyAlias(ref ty) => { - TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true) + let type_ = ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); + TypedefItem( + Typedef { + type_, + generics: Generics::default(), + item_type, + }, + true, + ) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -1282,10 +1291,13 @@ impl Clean for ty::AssocItem { AssocTypeItem(bounds, ty.clean(cx)) } else { + let type_ = cx.tcx.type_of(self.def_id).clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); TypedefItem( Typedef { - type_: cx.tcx.type_of(self.def_id).clean(cx), + type_, generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + item_type, }, true, ) @@ -1989,6 +2001,8 @@ impl Clean for ast::Name { impl Clean for doctree::Typedef<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { + let type_ = self.ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), @@ -1998,7 +2012,11 @@ impl Clean for doctree::Typedef<'_> { stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), inner: TypedefItem( - Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) }, + Typedef { + type_, + generics: self.gen.clean(cx), + item_type, + }, false, ), } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5d8e27ecadb82..79a078ca7a991 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1406,6 +1406,14 @@ pub struct PathSegment { pub struct Typedef { pub type_: Type, pub generics: Generics, + // Type of target item. + pub item_type: Option, +} + +impl GetDefId for Typedef { + fn def_id(&self) -> Option { + self.type_.def_id() + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2d932eb7668c4..69e268f3f80c1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3469,22 +3469,27 @@ fn render_deref_methods( deref_mut: bool, ) { let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); - let target = impl_ + let (target, real_target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() .expect("Expected associated type binding"); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = target.def_id() { + if let Some(did) = real_target.def_id() { render_assoc_items(w, cx, container_item, did, what) } else { - if let Some(prim) = target.primitive_type() { + if let Some(prim) = real_target.primitive_type() { if let Some(&did) = cx.cache.primitive_locations.get(&prim) { render_assoc_items(w, cx, container_item, did, what); } @@ -4123,17 +4128,22 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() { - let inner_impl = target + let inner_impl = real_target .def_id() .or(target .primitive_type() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 22507443b0842..cdfd6b3073adf 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -277,7 +277,7 @@ impl DocFolder for Cache { | clean::StructFieldItem(..) | clean::VariantItem(..) => ( ( - Some(*self.parent_stack.last().unwrap()), + Some(*self.parent_stack.last().expect("parent_stack is empty")), Some(&self.stack[..self.stack.len() - 1]), ), false, @@ -286,7 +286,7 @@ impl DocFolder for Cache { if self.parent_stack.is_empty() { ((None, None), false) } else { - let last = self.parent_stack.last().unwrap(); + let last = self.parent_stack.last().expect("parent_stack is empty 2"); let did = *last; let path = match self.paths.get(&did) { // The current stack not necessarily has correlation @@ -468,7 +468,7 @@ impl DocFolder for Cache { self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); } } else { - let trait_did = impl_item.trait_did().unwrap(); + let trait_did = impl_item.trait_did().expect("no trait did"); self.orphan_trait_impls.push((trait_did, dids, impl_item)); } None @@ -478,10 +478,10 @@ impl DocFolder for Cache { }); if pushed { - self.stack.pop().unwrap(); + self.stack.pop().expect("stack already empty"); } if parent_pushed { - self.parent_stack.pop().unwrap(); + self.parent_stack.pop().expect("parent stack already empty"); } self.stripped_mod = orig_stripped_mod; self.parent_is_trait_impl = orig_parent_is_trait_impl; @@ -574,6 +574,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { + if item.name.is_none() { // this is most likely from a typedef + continue; + } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -592,19 +595,25 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = item.parent.map(|nodeid| { - if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).unwrap() - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + item.parent_idx = match item.parent { + Some(nodeid) => { + Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - let &(ref fqp, short) = paths.get(&nodeid).unwrap(); - crate_paths.push((short, fqp.last().unwrap().clone())); - pathid + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue + } + pathid + }) } - }); + None => None, + }; // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { @@ -639,7 +648,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { items: crate_items, paths: crate_paths, }) - .unwrap() + .expect("failed serde conversion") ) } From fd4a88f3098ab1b20267716102d49c8a43d151d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:41:46 +0100 Subject: [PATCH 0364/1253] Add test for typedef deref --- src/test/rustdoc/deref-typedef.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/rustdoc/deref-typedef.rs diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs new file mode 100644 index 0000000000000..b2dc20a5030e7 --- /dev/null +++ b/src/test/rustdoc/deref-typedef.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +// @has 'foo/struct.Bar.html' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +pub struct FooA; +pub type FooB = FooA; + +impl FooA { + pub fn happy(&self) {} +} + +pub struct Bar; +impl std::ops::Deref for Bar { + type Target = FooB; + fn deref(&self) -> &FooB { unimplemented!() } +} From 81a5b94ac60cc1a9c8d365d8c6166c148279276c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:46:28 +0100 Subject: [PATCH 0365/1253] formatting --- src/librustdoc/clean/inline.rs | 8 +++----- src/librustdoc/clean/mod.rs | 18 ++--------------- src/librustdoc/html/render.rs | 20 ++++++++----------- src/librustdoc/html/render/cache.rs | 31 ++++++++++++++--------------- 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fc75bf35b250d..e54e716e042fe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -284,11 +284,9 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option pub fn build_ty(cx: &DocContext, did: DefId) -> Option { match cx.tcx.def_kind(did)? { - DefKind::Struct | - DefKind::Union | - DefKind::Enum | - DefKind::Const | - DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => { + Some(cx.tcx.type_of(did).clean(cx)) + } DefKind::TyAlias => build_type_alias_type(cx, did), _ => None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0cc4c55f49be8..027975a6d3288 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1124,14 +1124,7 @@ impl Clean for hir::ImplItem<'_> { hir::ImplItemKind::TyAlias(ref ty) => { let type_ = ty.clean(cx); let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); - TypedefItem( - Typedef { - type_, - generics: Generics::default(), - item_type, - }, - true, - ) + TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -2011,14 +2004,7 @@ impl Clean for doctree::Typedef<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), - inner: TypedefItem( - Typedef { - type_, - generics: self.gen.clean(cx), - item_type, - }, - false, - ), + inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 69e268f3f80c1..86d59a0cccd9a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3474,12 +3474,10 @@ fn render_deref_methods( .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() @@ -4133,12 +4131,10 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index cdfd6b3073adf..fd9c47d0c4a44 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,7 +574,8 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { // this is most likely from a typedef + if item.name.is_none() { + // this is most likely from a typedef continue; } search_index.push(IndexItem { @@ -596,22 +597,20 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { for item in search_index { item.parent_idx = match item.parent { - Some(nodeid) => { - Some(if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).expect("no pathid") - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue - } - pathid - }) - } + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue; + } + pathid + }), None => None, }; From 312c3a067a090dd7c970ba40c08909ca1281c312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 15 Jan 2020 15:00:25 +0100 Subject: [PATCH 0366/1253] remove redundant clones, found by clippy --- src/librustc_driver/pretty.rs | 2 -- src/librustc_parse/parser/ty.rs | 2 +- src/librustc_resolve/imports.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libtest/lib.rs | 4 ++-- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 8804a05b596ee..6ef6dcf87eddb 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -429,7 +429,6 @@ pub fn print_after_hir_lowering<'tcx>( PpmSource(s) => { // Silently ignores an identified node. let out = &mut out; - let src = src.clone(); call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); @@ -447,7 +446,6 @@ pub fn print_after_hir_lowering<'tcx>( PpmHir(s) => { let out = &mut out; - let src = src.clone(); call_with_pp_support_hir(&s, tcx, move |annotation, krate| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index ea14aa278ac29..065a3b14428c7 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -500,7 +500,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( lo.to(self.prev_span), "remove the parentheses", - snippet.to_owned(), + snippet, Applicability::MachineApplicable, ); } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 8fe17e89444cd..5bd10303162b2 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -718,7 +718,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !errors.is_empty() { - self.throw_unresolved_import_error(errors.clone(), None); + self.throw_unresolved_import_error(errors, None); } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index b5731ff0fec21..f899e722a5615 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -704,7 +704,7 @@ impl Tester for Collector { debug!("creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { - name: testing::DynTestName(name.clone()), + name: testing::DynTestName(name), ignore: match config.ignore { Ignore::All => true, Ignore::None => false, diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 884db85efe0a2..45669d120c7c2 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -553,7 +553,7 @@ fn run_test_in_process( Err(e) => calc_result(&desc, Err(e.as_ref()), &time_opts, &exec_time), }; let stdout = data.lock().unwrap().to_vec(); - let message = CompletedTest::new(desc.clone(), test_result, exec_time, stdout); + let message = CompletedTest::new(desc, test_result, exec_time, stdout); monitor_ch.send(message).unwrap(); } @@ -602,7 +602,7 @@ fn spawn_test_subprocess( (result, test_output, exec_time) })(); - let message = CompletedTest::new(desc.clone(), result, exec_time, test_output); + let message = CompletedTest::new(desc, result, exec_time, test_output); monitor_ch.send(message).unwrap(); } From 6e791464bcabc3d64b8fd5de6f2217c67d81a8b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:56:11 +0100 Subject: [PATCH 0367/1253] remove unneeded code from cache.rs --- src/librustdoc/html/render/cache.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index fd9c47d0c4a44..f1f83acdda59e 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,10 +574,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { - // this is most likely from a typedef - continue; - } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -596,23 +592,19 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = match item.parent { - Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + item.parent_idx = item.parent.map(|nodeid| { + if nodeid_to_pathid.contains_key(&nodeid) { *nodeid_to_pathid.get(&nodeid).expect("no pathid") } else { let pathid = lastpathid; nodeid_to_pathid.insert(nodeid, pathid); lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue; - } + let &(ref fqp, short) = paths.get(&nodeid).unwrap(); + crate_paths.push((short, fqp.last().unwrap().clone())); pathid - }), - None => None, - }; + } + }); // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { From 406049df4948a2c93d50f2c72cfa0e2811695ef5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:20 +0900 Subject: [PATCH 0368/1253] Add test for issue-64848 --- src/test/ui/associated-types/issue-64848.rs | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/ui/associated-types/issue-64848.rs diff --git a/src/test/ui/associated-types/issue-64848.rs b/src/test/ui/associated-types/issue-64848.rs new file mode 100644 index 0000000000000..77712168a0fd9 --- /dev/null +++ b/src/test/ui/associated-types/issue-64848.rs @@ -0,0 +1,29 @@ +// build-pass + +trait AssociatedConstant { + const DATA: (); +} + +impl AssociatedConstant for F +where + F: FnOnce() -> T, + T: AssociatedConstant, +{ + const DATA: () = T::DATA; +} + +impl AssociatedConstant for () { + const DATA: () = (); +} + +fn foo() -> impl AssociatedConstant { + () +} + +fn get_data(_: T) -> &'static () { + &T::DATA +} + +fn main() { + get_data(foo); +} From ce8fed65f5e6f75b91cff35aec21190714231091 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:33 +0900 Subject: [PATCH 0369/1253] Add test for issue-65918 --- .../ui/type-alias-impl-trait/issue-65918.rs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-65918.rs diff --git a/src/test/ui/type-alias-impl-trait/issue-65918.rs b/src/test/ui/type-alias-impl-trait/issue-65918.rs new file mode 100644 index 0000000000000..97efb85ef64c7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65918.rs @@ -0,0 +1,49 @@ +// build-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +/* copied Index and TryFrom for convinience (and simplicity) */ +trait MyIndex { + type O; + fn my_index(self) -> Self::O; +} +trait MyFrom: Sized { + type Error; + fn my_from(value: T) -> Result; +} + +/* MCVE starts here */ +trait F {} +impl F for () {} +type DummyT = impl F; +fn _dummy_t() -> DummyT {} + +struct Phantom1(PhantomData); +struct Phantom2(PhantomData); +struct Scope(Phantom2>); + +impl Scope { + fn new() -> Self { + unimplemented!() + } +} + +impl MyFrom> for Phantom1 { + type Error = (); + fn my_from(_: Phantom2) -> Result { + unimplemented!() + } +} + +impl>>, U> MyIndex> for Scope { + type O = T; + fn my_index(self) -> Self::O { + MyFrom::my_from(self.0).ok().unwrap() + } +} + +fn main() { + let _pos: Phantom1> = Scope::new().my_index(); +} From 27a810c719a1b9b245bb0b95e5774e3d092f7e6f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:51 +0900 Subject: [PATCH 0370/1253] Add test for issue-66473 --- src/test/ui/issues/issue-66473.rs | Bin 0 -> 113 bytes src/test/ui/issues/issue-66473.stderr | Bin 0 -> 2632 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/test/ui/issues/issue-66473.rs create mode 100644 src/test/ui/issues/issue-66473.stderr diff --git a/src/test/ui/issues/issue-66473.rs b/src/test/ui/issues/issue-66473.rs new file mode 100644 index 0000000000000000000000000000000000000000..cc298a28b97e5bc6e683fe5faee36d95d64720bf GIT binary patch literal 113 zcmdPbS4b@?$}iF_NGvHyEy}Y}D9y{x%P-GUC@x7XDpAN!Qz*&LPR--e$55DBQIMKk klA5BB5S^f-kd|MX2V|NhaB(T0?O?zFT->r|vJ4Dd0C6%O9{>OV literal 0 HcmV?d00001 diff --git a/src/test/ui/issues/issue-66473.stderr b/src/test/ui/issues/issue-66473.stderr new file mode 100644 index 0000000000000000000000000000000000000000..dbeef44bad0ec68b68ce3c3c06768df43587855c GIT binary patch literal 2632 zcmchZPfNov7>9d~pJDKV9_`%QrrFG4CojTIUX{_!W>N;p$R8D)cfXw9$xvZLWL*#A z&8d*`dqUuS@>A9tDc4fQLW2 g_IIdjtF^Jd)i2Nl6^kJh9ClW{wk9~}8l7Y82jcILL;wH) literal 0 HcmV?d00001 From 3ba15bda53272a73ee04b3d592ffb14d6ee177cb Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:35:44 +0900 Subject: [PATCH 0371/1253] Set mir-opt-level to 3 to prevent regressions --- src/test/mir-opt/inline/inline-into-box-place.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs index 0bb9dfa403d58..f368bdef6f8e2 100644 --- a/src/test/mir-opt/inline/inline-into-box-place.rs +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -1,5 +1,6 @@ // ignore-tidy-linelength // ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -Z mir-opt-level=3 #![feature(box_syntax)] fn main() { From 783a7dc8ed03a38910b9ea5ded11139616dfa67b Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 15 Jan 2020 08:31:24 -0800 Subject: [PATCH 0372/1253] Mark leading_trailing_ones with tracking issue 57969 --- src/libcore/num/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 77fae26953f09..91848abd68d36 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -407,7 +407,7 @@ let n = -1", stringify!($SelfT), "; assert_eq!(n.leading_ones(), ", stringify!($BITS), ");", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn leading_ones(self) -> u32 { (self as $UnsignedT).leading_ones() @@ -428,7 +428,7 @@ let n = 3", stringify!($SelfT), "; assert_eq!(n.trailing_ones(), 2);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn trailing_ones(self) -> u32 { (self as $UnsignedT).trailing_ones() @@ -2540,7 +2540,7 @@ let n = !(", stringify!($SelfT), "::max_value() >> 2); assert_eq!(n.leading_ones(), 2);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn leading_ones(self) -> u32 { (!self).leading_zeros() @@ -2561,7 +2561,7 @@ let n = 0b1010111", stringify!($SelfT), "; assert_eq!(n.trailing_ones(), 3);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn trailing_ones(self) -> u32 { (!self).trailing_zeros() From 470cdf54ac9acee20ab8da46ef7899bae9f58f29 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 15 Jan 2020 16:39:08 +0100 Subject: [PATCH 0373/1253] add bare metal ARM Cortex-A targets to rustc -> `rustc --target armv7-none-eabi` will work also build rust-std (rustup) components for them -> `rustup target add armv7-none-eabi` will work --- src/ci/docker/dist-various-1/Dockerfile | 4 ++ src/librustc_target/spec/armv7a_none_eabi.rs | 48 +++++++++++++++++++ .../spec/armv7a_none_eabihf.rs | 36 ++++++++++++++ src/librustc_target/spec/mod.rs | 3 ++ src/tools/build-manifest/src/main.rs | 2 + 5 files changed, 93 insertions(+) create mode 100644 src/librustc_target/spec/armv7a_none_eabi.rs create mode 100644 src/librustc_target/spec/armv7a_none_eabihf.rs diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 6bbf092878311..689e18c3b40ba 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -134,6 +134,8 @@ ENV TARGETS=$TARGETS,armebv7r-none-eabihf ENV TARGETS=$TARGETS,armv7r-none-eabi ENV TARGETS=$TARGETS,armv7r-none-eabihf ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf +ENV TARGETS=$TARGETS,armv7a-none-eabi +ENV TARGETS=$TARGETS,armv7a-none-eabihf # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not @@ -147,6 +149,8 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ + CC_armv7a_none_eabi=arm-none-eabi-gcc \ + CC_armv7a_none_eabihf=arm-none-eabi-gcc \ CC_riscv32i_unknown_none_elf=false \ CC_riscv32imc_unknown_none_elf=false \ CC_riscv32imac_unknown_none_elf=false \ diff --git a/src/librustc_target/spec/armv7a_none_eabi.rs b/src/librustc_target/spec/armv7a_none_eabi.rs new file mode 100644 index 0000000000000..2fbef154f814c --- /dev/null +++ b/src/librustc_target/spec/armv7a_none_eabi.rs @@ -0,0 +1,48 @@ +// Generic ARMv7-A target for bare-metal code - floating point disabled +// +// This is basically the `armv7-unknown-linux-gnueabi` target with some changes +// (listed below) to bring it closer to the bare-metal `thumb` & `aarch64` +// targets: +// +// - `TargetOptions.features`: added `+strict-align`. rationale: unaligned +// memory access is disabled on boot on these cores +// - linker changed to LLD. rationale: C is not strictly needed to build +// bare-metal binaries (the `gcc` linker has the advantage that it knows where C +// libraries and crt*.o are but it's not much of an advantage here); LLD is also +// faster +// - `target_os` set to `none`. rationale: matches `thumb` targets +// - `target_{env,vendor}` set to an empty string. rationale: matches `thumb` +// targets +// - `panic_strategy` set to `abort`. rationale: matches `thumb` targets +// - `relocation-model` set to `static`; also no PIE, no relro and no dynamic +// linking. rationale: matches `thumb` targets + +use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; + +pub fn target() -> Result { + let opts = TargetOptions { + linker: Some("rust-lld".to_owned()), + features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(), + executables: true, + relocation_model: "static".to_string(), + disable_redzone: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + abi_blacklist: super::arm_base::abi_blacklist(), + emit_debug_gdb_scripts: false, + ..Default::default() + }; + Ok(Target { + llvm_target: "armv7a-none-eabi".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + options: opts, + }) +} diff --git a/src/librustc_target/spec/armv7a_none_eabihf.rs b/src/librustc_target/spec/armv7a_none_eabihf.rs new file mode 100644 index 0000000000000..f31e68c5bd12a --- /dev/null +++ b/src/librustc_target/spec/armv7a_none_eabihf.rs @@ -0,0 +1,36 @@ +// Generic ARMv7-A target for bare-metal code - floating point enabled (assumes +// FPU is present and emits FPU instructions) +// +// This is basically the `armv7-unknown-linux-gnueabihf` target with some +// changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal +// `thumb` & `aarch64` targets. + +use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; + +pub fn target() -> Result { + let opts = TargetOptions { + linker: Some("rust-lld".to_owned()), + features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(), + executables: true, + relocation_model: "static".to_string(), + disable_redzone: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + abi_blacklist: super::arm_base::abi_blacklist(), + emit_debug_gdb_scripts: false, + ..Default::default() + }; + Ok(Target { + llvm_target: "armv7a-none-eabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + options: opts, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 528ffdf93a01a..67f45d3d230ef 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -472,6 +472,9 @@ supported_targets! { ("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi), ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf), + ("armv7a-none-eabi", armv7a_none_eabi), + ("armv7a-none-eabihf", armv7a_none_eabihf), + ("msp430-none-elf", msp430_none_elf), ("aarch64-unknown-cloudabi", aarch64_unknown_cloudabi), diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 481163a1a9abe..8281d20e4c886 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -69,6 +69,8 @@ static TARGETS: &[&str] = &[ "thumbv7neon-linux-androideabi", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", + "armv7a-none-eabi", + "armv7a-none-eabihf", "thumbv7neon-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", From e6ad49aa67b7e6e0d9c5bc4bd68f44a009f91595 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 15:07:27 +0100 Subject: [PATCH 0374/1253] Include type alias implementations --- src/librustdoc/html/render.rs | 53 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86d59a0cccd9a..aafc7a8a10ff6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: AssocItemRender<'_>, + what: &AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: deref_mut_ } + RenderMode::ForDeref { mut_: *deref_mut_ } } }; for i in &non_trait { @@ -3461,6 +3461,19 @@ fn render_assoc_items( } } +fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { + if let Some(did) = real_target.def_id() { + return Some(did); + } else { + if let Some(prim) = real_target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + return Some(did); + } + } + } + None +} + fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3475,23 +3488,21 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), + _ => (&t.type_, None), }), _ => None, }) .next() .expect("Expected associated type binding"); + let did = get_def_id(&target, cx); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = real_target.def_id() { - render_assoc_items(w, cx, container_item, did, what) - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - render_assoc_items(w, cx, container_item, did, what); - } - } + if let Some(did) = did { + render_assoc_items(w, cx, container_item, did, &what); + } + if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { + render_assoc_items(w, cx, container_item, did, &what); } } @@ -3873,7 +3884,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3894,7 +3905,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3915,7 +3926,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3930,7 +3941,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4602,7 +4613,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From f2fc35128b0592f6cdab3da1cf5da9ad8a0e2847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Jan 2020 00:00:00 +0000 Subject: [PATCH 0375/1253] Remove unused auxiliary file that was replaced with rust_test_helpers --- src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs diff --git a/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs deleted file mode 100644 index c1c5b70bc04e2..0000000000000 --- a/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic -#![crate_type = "staticlib"] - -#[no_mangle] -pub extern "C" fn foo(x:i32) -> i32 { x } From 5d00b5c4aae885a247d783f5c274df9ef0539d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Jan 2020 00:00:00 +0000 Subject: [PATCH 0376/1253] Enable leak sanitizer test case * Use `black_box` to avoid memory leak removal during optimization. * Leak multiple objects to make test case more robust. --- src/test/run-make-fulldeps/sanitizer-leak/Makefile | 6 +----- src/test/run-make-fulldeps/sanitizer-leak/leak.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile index d8598b8ac93f9..da370335ca918 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-leak/Makefile @@ -1,11 +1,7 @@ -include ../tools.mk # needs-sanitizer-support -# only-linux -# only-x86_64 -# ignore-test -# FIXME(#46126) ThinLTO for libstd broke this test all: - $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan + $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs index ab8df5c7bfd45..fb0a917dd98b6 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs +++ b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs @@ -1,6 +1,13 @@ +#![feature(test)] + +use std::hint::black_box; use std::mem; fn main() { - let xs = vec![1, 2, 3, 4]; - mem::forget(xs); + for _ in 0..10 { + let xs = vec![1, 2, 3]; + // Prevent compiler from removing the memory allocation. + let xs = black_box(xs); + mem::forget(xs); + } } From 33bc9ef513d632825ea600cfb4bb6d89f4a09269 Mon Sep 17 00:00:00 2001 From: SOFe Date: Wed, 15 Jan 2020 02:07:39 +0800 Subject: [PATCH 0377/1253] Use 3.6 instead of 3.5 in float fract() documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not self-explanatory whether the fract() function inverts the fractional part of negative numbers. Co-Authored-By: Mateusz Mikuła --- src/libstd/f32.rs | 8 ++++---- src/libstd/f64.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..209eea4a5ff73 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -131,10 +131,10 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = 3.5_f32; - /// let y = -3.5_f32; - /// let abs_difference_x = (x.fract() - 0.5).abs(); - /// let abs_difference_y = (y.fract() - (-0.5)).abs(); + /// let x = 3.6_f32; + /// let y = -3.6_f32; + /// let abs_difference_x = (x.fract() - 0.6).abs(); + /// let abs_difference_y = (y.fract() - (-0.6)).abs(); /// /// assert!(abs_difference_x <= f32::EPSILON); /// assert!(abs_difference_y <= f32::EPSILON); diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 61ce7b29e26fc..15fbb911d043a 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -109,10 +109,10 @@ impl f64 { /// # Examples /// /// ``` - /// let x = 3.5_f64; - /// let y = -3.5_f64; - /// let abs_difference_x = (x.fract() - 0.5).abs(); - /// let abs_difference_y = (y.fract() - (-0.5)).abs(); + /// let x = 3.6_f64; + /// let y = -3.6_f64; + /// let abs_difference_x = (x.fract() - 0.6).abs(); + /// let abs_difference_y = (y.fract() - (-0.6)).abs(); /// /// assert!(abs_difference_x < 1e-10); /// assert!(abs_difference_y < 1e-10); From d9d7877f0ea5aeca30322e80a26ef3916fc8b88e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 15 Jan 2020 20:03:22 +0100 Subject: [PATCH 0378/1253] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 4e44aa010c4c7..6a0f14bef7784 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 4e44aa010c4c7d616182a3078cafb39da6f6c0a2 +Subproject commit 6a0f14bef7784e57a57a996cae3f94dbd2490e7a From d755238172ead0c619ac404487615534abc51ef1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 18:52:04 +0100 Subject: [PATCH 0379/1253] Simplify deref impls for type aliases --- src/librustdoc/clean/mod.rs | 31 +++++++++++++++-- src/librustdoc/html/render.rs | 63 +++++++++++++++-------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 027975a6d3288..ae15b458fbaea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2105,7 +2105,7 @@ impl Clean> for doctree::Impl<'_> { build_deref_target_impls(cx, &items, &mut ret); } - let provided = trait_ + let provided: FxHashSet = trait_ .def_id() .map(|did| { cx.tcx @@ -2116,6 +2116,33 @@ impl Clean> for doctree::Impl<'_> { }) .unwrap_or_default(); + let for_ = self.for_.clean(cx); + let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) { + Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), + _ => None, + }); + if let Some(type_alias) = type_alias { + ret.push(Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_: trait_.clone(), + for_: type_alias, + items: items.clone(), + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), + }); + } ret.push(Item { name: None, attrs: self.attrs.clean(cx), @@ -2129,7 +2156,7 @@ impl Clean> for doctree::Impl<'_> { generics: self.generics.clean(cx), provided_trait_methods: provided, trait_, - for_: self.for_.clean(cx), + for_, items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aafc7a8a10ff6..aaacae045b903 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: &AssocItemRender<'_>, + what: AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: *deref_mut_ } + RenderMode::ForDeref { mut_: deref_mut_ } } }; for i in &non_trait { @@ -3461,19 +3461,6 @@ fn render_assoc_items( } } -fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { - if let Some(did) = real_target.def_id() { - return Some(did); - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - return Some(did); - } - } - } - None -} - fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3488,21 +3475,23 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), - _ => (&t.type_, None), + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) .next() .expect("Expected associated type binding"); - let did = get_def_id(&target, cx); let what = - AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = did { - render_assoc_items(w, cx, container_item, did, &what); - } - if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { - render_assoc_items(w, cx, container_item, did, &what); + AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; + if let Some(did) = target.def_id() { + render_assoc_items(w, cx, container_item, did, what); + } else { + if let Some(prim) = target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + render_assoc_items(w, cx, container_item, did, what); + } + } } } @@ -3884,7 +3873,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3905,7 +3894,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3926,7 +3915,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3941,7 +3930,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4137,20 +4126,20 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some((target, real_target)) = impl_ + if let Some(target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => type_, + _ => &t.type_, }), _ => None, }) .next() { - let inner_impl = real_target + let inner_impl = target .def_id() .or(target .primitive_type() @@ -4613,7 +4602,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From 8a9b951f578a1389507c7251b5c75258ac215bf9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 21:34:15 +0100 Subject: [PATCH 0380/1253] Fix rendering on sidebar and update tests --- src/librustdoc/html/render.rs | 8 ++++---- src/test/rustdoc/deref-typedef.rs | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aaacae045b903..9406803825350 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4126,14 +4126,14 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => type_, - _ => &t.type_, + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) @@ -4153,7 +4153,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { "{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print() )), - Escape(&format!("{:#}", target.print())) + Escape(&format!("{:#}", real_target.print())) )); out.push_str(""); let mut ret = impls diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index b2dc20a5030e7..770f8d7289c3b 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,19 +1,33 @@ #![crate_name = "foo"] // @has 'foo/struct.Bar.html' -// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' -// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' + pub struct FooA; pub type FooB = FooA; +pub type FooC = FooB; impl FooA { - pub fn happy(&self) {} + pub fn foo_a(&self) {} +} + +impl FooB { + pub fn foo_b(&self) {} +} + +impl FooC { + pub fn foo_c(&self) {} } pub struct Bar; impl std::ops::Deref for Bar { - type Target = FooB; - fn deref(&self) -> &FooB { unimplemented!() } + type Target = FooC; + fn deref(&self) -> &Self::Target { unimplemented!() } } From 1c0d4851a6a686d09b03fab575fb0847d1e9f665 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Wed, 15 Jan 2020 17:00:36 -0500 Subject: [PATCH 0381/1253] Fix incorrect slice->ptr conversion in slice_from_raw_parts docs --- src/libcore/ptr/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 80f865d79e49a..29956ae1a3646 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -252,7 +252,7 @@ pub(crate) struct FatPtr { /// /// // create a slice pointer when starting out with a pointer to the first element /// let x = [5, 6, 7]; -/// let ptr = &x[0] as *const _; +/// let ptr = x.as_ptr(); /// let slice = ptr::slice_from_raw_parts(ptr, 3); /// assert_eq!(unsafe { &*slice }[2], 7); /// ``` From baf2921ebc5f5da879d00dd5fb529e5d274dce6b Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 15 Jan 2020 22:42:04 +0000 Subject: [PATCH 0382/1253] rustdoc: HTML escape codeblocks which fail syntax highlighting --- src/librustdoc/html/highlight.rs | 2 +- src/test/rustdoc/bad-codeblock-syntax.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index fb6bdcdc9f48b..aa52b769c38ed 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -65,7 +65,7 @@ pub fn render_with_highlighting( Err(()) => { // If errors are encountered while trying to highlight, just emit // the unhighlighted source. - write!(out, "
{}
", src).unwrap(); + write!(out, "
{}
", Escape(src)).unwrap(); } } diff --git a/src/test/rustdoc/bad-codeblock-syntax.rs b/src/test/rustdoc/bad-codeblock-syntax.rs index 0ab2f68fcdebe..ae8fbe4a2a800 100644 --- a/src/test/rustdoc/bad-codeblock-syntax.rs +++ b/src/test/rustdoc/bad-codeblock-syntax.rs @@ -25,3 +25,11 @@ pub fn quux() {} /// \_ /// ``` pub fn ok() {} + +// @has bad_codeblock_syntax/fn.escape.html +// @has - '//*[@class="docblock"]/pre/code' '\_ ' +/// ``` +/// \_ +/// +/// ``` +pub fn escape() {} From ea64a3394312d65c95c7e74e7b8fa7e454685113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 16 Jan 2020 00:00:00 +0000 Subject: [PATCH 0383/1253] Update sanitizer tests * Move tests from src/test/run-make-fulldeps to src/test/ui. * Fix memory sanitizer test to detect the intended issue rather than an unrelated one caused by the use of an uninstrumented std. --- .../sanitizer-address/Makefile | 30 ------------- .../sanitizer-address/overflow.rs | 4 -- .../sanitizer-invalid-target/Makefile | 5 --- .../sanitizer-invalid-target/hello.rs | 3 -- .../run-make-fulldeps/sanitizer-leak/Makefile | 7 --- .../sanitizer-memory/Makefile | 11 ----- .../sanitizer-memory/maybeuninit.rs | 8 ---- .../sanitizer-memory/uninit.rs | 7 --- src/test/ui/sanitizer-address.rs | 21 +++++++++ .../leak.rs => ui/sanitizer-leak.rs} | 8 ++++ src/test/ui/sanitizer-memory.rs | 44 +++++++++++++++++++ src/test/ui/sanitizer-unsupported-target.rs | 7 +++ .../ui/sanitizer-unsupported-target.stderr | 4 ++ 13 files changed, 84 insertions(+), 75 deletions(-) delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/overflow.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-leak/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/uninit.rs create mode 100644 src/test/ui/sanitizer-address.rs rename src/test/{run-make-fulldeps/sanitizer-leak/leak.rs => ui/sanitizer-leak.rs} (62%) create mode 100644 src/test/ui/sanitizer-memory.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.stderr diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile deleted file mode 100644 index 7f5e9049b2f77..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# needs-sanitizer-support - --include ../tools.mk - -LOG := $(TMPDIR)/log.txt - -# NOTE the address sanitizer only supports x86_64 linux and macOS - -ifeq ($(TARGET),x86_64-apple-darwin) -EXTRA_RUSTFLAG=-C rpath -else -ifeq ($(TARGET),x86_64-unknown-linux-gnu) - -# Apparently there are very specific Linux kernels, notably the one that's -# currently on Travis CI, which contain a buggy commit that triggers failures in -# the ASan implementation, detailed at google/sanitizers#837. As noted in -# google/sanitizers#856 the "fix" is to avoid using PIE binaries, so we pass a -# different relocation model to avoid generating a PIE binary. Once Travis is no -# longer running kernel 4.4.0-93 we can remove this and pass an empty set of -# flags again. -EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic -endif -endif - -all: - $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) rustc_rt.asan - # Verify that stack buffer overflow is detected: - $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow - # Verify that variable name is included in address sanitizer report: - $(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'" diff --git a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs deleted file mode 100644 index b997a74cc3eb4..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let xs = [0, 1, 2, 3]; - let _y = unsafe { *xs.as_ptr().offset(4) }; -} diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile deleted file mode 100644 index 2a23f0fe3d4ef..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile +++ /dev/null @@ -1,5 +0,0 @@ --include ../tools.mk - -all: - $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | \ - $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target' diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs deleted file mode 100644 index d3dd5ed03d954..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![feature(no_core)] -#![no_core] -#![no_main] diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile deleted file mode 100644 index da370335ca918..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ /dev/null @@ -1,7 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support - -all: - $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan - $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile deleted file mode 100644 index 8bc9df1b4baeb..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile +++ /dev/null @@ -1,11 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support -# only-linux -# only-x86_64 - -all: - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value diff --git a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs deleted file mode 100644 index a9ae85f57639e..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::mem::MaybeUninit; - -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - let xs: [u8; 4] = unsafe { MaybeUninit::uninit().assume_init() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs deleted file mode 100644 index eae52508f6585..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - #[allow(deprecated)] - let xs: [u8; 4] = unsafe { std::mem::uninitialized() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/ui/sanitizer-address.rs b/src/test/ui/sanitizer-address.rs new file mode 100644 index 0000000000000..d27a30a2dc55f --- /dev/null +++ b/src/test/ui/sanitizer-address.rs @@ -0,0 +1,21 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=address -O +// +// run-fail +// error-pattern: AddressSanitizer: stack-buffer-overflow +// error-pattern: 'xs' <== Memory access at offset + +#![feature(test)] + +use std::hint::black_box; +use std::mem; + +fn main() { + let xs = [0, 1, 2, 3]; + // Avoid optimizing everything out. + let xs = black_box(xs.as_ptr()); + let code = unsafe { *xs.offset(4) }; + std::process::exit(code); +} diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/ui/sanitizer-leak.rs similarity index 62% rename from src/test/run-make-fulldeps/sanitizer-leak/leak.rs rename to src/test/ui/sanitizer-leak.rs index fb0a917dd98b6..5c2f2cb4e868b 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs +++ b/src/test/ui/sanitizer-leak.rs @@ -1,3 +1,11 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=leak -O +// +// run-fail +// error-pattern: LeakSanitizer: detected memory leaks + #![feature(test)] use std::hint::black_box; diff --git a/src/test/ui/sanitizer-memory.rs b/src/test/ui/sanitizer-memory.rs new file mode 100644 index 0000000000000..3e1cf4509a31f --- /dev/null +++ b/src/test/ui/sanitizer-memory.rs @@ -0,0 +1,44 @@ +// needs-sanitizer-support +// only-linux +// only-x86_64 +// +// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O +// +// run-fail +// error-pattern: MemorySanitizer: use-of-uninitialized-value +// error-pattern: Uninitialized value was created by an allocation +// error-pattern: in the stack frame of function 'random' +// +// This test case intentionally limits the usage of the std, +// since it will be linked with an uninstrumented version of it. + +#![feature(core_intrinsics)] +#![feature(start)] +#![feature(test)] + +use std::hint::black_box; +use std::mem::MaybeUninit; + +#[inline(never)] +#[no_mangle] +fn random() -> [isize; 32] { + let r = unsafe { MaybeUninit::uninit().assume_init() }; + // Avoid optimizing everything out. + black_box(r) +} + +#[inline(never)] +#[no_mangle] +fn xor(a: &[isize]) -> isize { + let mut s = 0; + for i in 0..a.len() { + s = s ^ a[i]; + } + s +} + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + let r = random(); + xor(&r) +} diff --git a/src/test/ui/sanitizer-unsupported-target.rs b/src/test/ui/sanitizer-unsupported-target.rs new file mode 100644 index 0000000000000..444333c3f01e2 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength +// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu +// error-pattern: error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/src/test/ui/sanitizer-unsupported-target.stderr b/src/test/ui/sanitizer-unsupported-target.stderr new file mode 100644 index 0000000000000..38be58dd4b365 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.stderr @@ -0,0 +1,4 @@ +error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +error: aborting due to previous error + From bf0a7845d7860c681a6d273697dd1ca9d1cda81a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 10:55:29 +0900 Subject: [PATCH 0384/1253] Fix issue number of `member_constraints` --- .../unstable-book/src/language-features/member-constraints.md | 4 ++-- src/librustc_feature/active.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md index 0d11c31aca6e9..3ba4a3e6b1f02 100644 --- a/src/doc/unstable-book/src/language-features/member-constraints.md +++ b/src/doc/unstable-book/src/language-features/member-constraints.md @@ -1,8 +1,8 @@ # `member_constraints` -The tracking issue for this feature is: [#61977] +The tracking issue for this feature is: [#61997] -[#61977]: https://github.com/rust-lang/rust/issues/61977 +[#61997]: https://github.com/rust-lang/rust/issues/61997 ------------------------ diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 319cd88f24586..0d1d1f8254439 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -481,7 +481,7 @@ declare_features! ( (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), /// Allows `impl Trait` with multiple unrelated lifetimes. - (active, member_constraints, "1.37.0", Some(61977), None), + (active, member_constraints, "1.37.0", Some(61997), None), /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), From 54b961658ba73f04d3603c8f839c1e36a7f989e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:30:27 +0100 Subject: [PATCH 0385/1253] Update f32.rs --- src/libstd/f32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..375624e6797a7 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -355,7 +355,7 @@ impl f32 { return unsafe { intrinsics::powf32(self, n) }; } - /// Takes the square root of a number. + /// Returns the square root of a number. /// /// Returns NaN if `self` is a negative number. /// From 3f337b312d0cfec712fc56539a08b3ea9923bbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:34:23 +0100 Subject: [PATCH 0386/1253] Update f64.rs --- src/libstd/f64.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 61ce7b29e26fc..2dbd942f3324d 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -323,7 +323,7 @@ impl f64 { unsafe { intrinsics::powf64(self, n) } } - /// Takes the square root of a number. + /// Returns the square root of a number. /// /// Returns NaN if `self` is a negative number. /// @@ -506,7 +506,7 @@ impl f64 { unsafe { cmath::fdim(self, other) } } - /// Takes the cubic root of a number. + /// Returns the cubic root of a number. /// /// # Examples /// From d0db6d5791a75bb6e6f7ebe98067e78753fc1986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:35:31 +0100 Subject: [PATCH 0387/1253] Update f32.rs --- src/libstd/f32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 375624e6797a7..171891b5dabc0 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -564,7 +564,7 @@ impl f32 { unsafe { cmath::fdimf(self, other) } } - /// Takes the cubic root of a number. + /// Returns the cubic root of a number. /// /// # Examples /// From be730e16de1c2590d20ff76c9dfa9a7536fd418a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 15 Jan 2020 18:41:17 -0800 Subject: [PATCH 0388/1253] Use trailing underscore for helper methods --- src/librustc_mir/dataflow/generic/cursor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/cursor.rs b/src/librustc_mir/dataflow/generic/cursor.rs index f819b0fb5d69a..d2eff494ad701 100644 --- a/src/librustc_mir/dataflow/generic/cursor.rs +++ b/src/librustc_mir/dataflow/generic/cursor.rs @@ -79,7 +79,7 @@ where /// effect, use `seek_after` or `seek_after_assume_call_returns`. pub fn seek_before(&mut self, target: Location) { assert!(target <= self.body.terminator_loc(target.block)); - self._seek(target, false); + self.seek_(target, false); } /// Advances the cursor to hold the full effect of all statements (and possibly closing @@ -98,7 +98,7 @@ where self.seek_to_block_start(target.block); } - self._seek(target, true); + self.seek_(target, true); } /// Advances the cursor to hold all effects up to and including of the statement (or @@ -110,7 +110,7 @@ where let terminator_loc = self.body.terminator_loc(target.block); assert!(target.statement_index <= terminator_loc.statement_index); - self._seek(target, true); + self.seek_(target, true); if target != terminator_loc { return; @@ -134,7 +134,7 @@ where } } - fn _seek(&mut self, target: Location, apply_after_effect_at_target: bool) { + fn seek_(&mut self, target: Location, apply_after_effect_at_target: bool) { use CursorPosition::*; match self.pos { From 49d8aebbf36a254f1d527b90c72f07b4d23b2687 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 11:58:28 +0900 Subject: [PATCH 0389/1253] Fix issue number of `repr128` --- src/doc/unstable-book/src/language-features/repr128.md | 4 ++-- src/librustc_feature/active.rs | 2 +- src/test/ui/error-codes/E0658.stderr | 2 +- src/test/ui/feature-gates/feature-gate-repr128.stderr | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/repr128.md b/src/doc/unstable-book/src/language-features/repr128.md index 0858988952c10..146f50ee67b50 100644 --- a/src/doc/unstable-book/src/language-features/repr128.md +++ b/src/doc/unstable-book/src/language-features/repr128.md @@ -1,8 +1,8 @@ # `repr128` -The tracking issue for this feature is: [#35118] +The tracking issue for this feature is: [#56071] -[#35118]: https://github.com/rust-lang/rust/issues/35118 +[#56071]: https://github.com/rust-lang/rust/issues/56071 ------------------------ diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 0d1d1f8254439..4c8c47a567113 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -333,7 +333,7 @@ declare_features! ( (active, abi_ptx, "1.15.0", Some(38788), None), /// Allows the `#[repr(i128)]` attribute for enums. - (active, repr128, "1.16.0", Some(35118), None), + (active, repr128, "1.16.0", Some(56071), None), /// Allows `#[link(kind="static-nobundle"...)]`. (active, static_nobundle, "1.16.0", Some(37403), None), diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index 071dbccd80ba0..1cb81c8d778ec 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -6,7 +6,7 @@ LL | | Bar(u64), LL | | } | |_^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/35118 + = note: for more information, see https://github.com/rust-lang/rust/issues/56071 = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-repr128.stderr b/src/test/ui/feature-gates/feature-gate-repr128.stderr index 2139a5da600df..e108d74e9c6cc 100644 --- a/src/test/ui/feature-gates/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gates/feature-gate-repr128.stderr @@ -6,7 +6,7 @@ LL | | A(u64) LL | | } | |_^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/35118 + = note: for more information, see https://github.com/rust-lang/rust/issues/56071 = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error From 91c6a5aaeebacf444aba8d99cba0da945c0ce732 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 11:59:04 +0900 Subject: [PATCH 0390/1253] Fix issue number of `infer_static_outlives_requirements` --- .../language-features/infer-static-outlives-requirements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md index 6187f395b0498..53e01091f754e 100644 --- a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md +++ b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md @@ -1,8 +1,8 @@ # `infer_static_outlives_requirements` -The tracking issue for this feature is: [#44493] +The tracking issue for this feature is: [#54185] -[#44493]: https://github.com/rust-lang/rust/issues/44493 +[#54185]: https://github.com/rust-lang/rust/issues/54185 ------------------------ The `infer_static_outlives_requirements` feature indicates that certain From c4d91aae5a72733479bab8df1aee78bb049b9735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 16 Jan 2020 08:27:41 +0100 Subject: [PATCH 0391/1253] remove dead code The condition if obligation.recursion_depth >= 0 is always true since recursion_depth is usize. The else branch is dead code and can be removed. Found by Clippy. Fixes #68251 --- src/librustc/traits/select.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e96697cc7e09d..fb1c46834d3a0 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3767,16 +3767,12 @@ impl<'tcx> TraitObligation<'tcx> { // NOTE(flaper87): As of now, it keeps track of the whole error // chain. Ideally, we should have a way to configure this either // by using -Z verbose or just a CLI argument. - if obligation.recursion_depth >= 0 { - let derived_cause = DerivedObligationCause { - parent_trait_ref: obligation.predicate.to_poly_trait_ref(), - parent_code: Rc::new(obligation.cause.code.clone()), - }; - let derived_code = variant(derived_cause); - ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) - } else { - obligation.cause.clone() - } + let derived_cause = DerivedObligationCause { + parent_trait_ref: obligation.predicate.to_poly_trait_ref(), + parent_code: Rc::new(obligation.cause.code.clone()), + }; + let derived_code = variant(derived_cause); + ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) } } From a1a0aea9e3830f4351f45f3a56c1adbca49be481 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:36:54 +0100 Subject: [PATCH 0392/1253] clean up E0195 explanation --- src/librustc_error_codes/error_codes/E0195.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0195.md b/src/librustc_error_codes/error_codes/E0195.md index 3606521020a11..b8c313d412eba 100644 --- a/src/librustc_error_codes/error_codes/E0195.md +++ b/src/librustc_error_codes/error_codes/E0195.md @@ -1,4 +1,5 @@ -Your method's lifetime parameters do not match the trait declaration. +The lifetime parameters of the method do not match the trait declaration. + Erroneous code example: ```compile_fail,E0195 @@ -16,7 +17,7 @@ impl Trait for Foo { } ``` -The lifetime constraint `'b` for bar() implementation does not match the +The lifetime constraint `'b` for `bar()` implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: From 6f1bdb47f2a3bb24f60f8f27683991ddd2058b03 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:37:01 +0100 Subject: [PATCH 0393/1253] clean up E0197 explanation --- src/librustc_error_codes/error_codes/E0197.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0197.md b/src/librustc_error_codes/error_codes/E0197.md index 0d91157e572cc..c142b8f3664c5 100644 --- a/src/librustc_error_codes/error_codes/E0197.md +++ b/src/librustc_error_codes/error_codes/E0197.md @@ -1,13 +1,20 @@ +An inherent implementation was marked unsafe. + +Erroneous code example: + +```compile_fail,E0197 +struct Foo; + +unsafe impl Foo { } // error! +``` + Inherent implementations (one that do not implement a trait but provide methods associated with a type) are always safe because they are not implementing an unsafe trait. Removing the `unsafe` keyword from the inherent implementation will resolve this error. -```compile_fail,E0197 +``` struct Foo; -// this will cause this error -unsafe impl Foo { } -// converting it to this will fix it -impl Foo { } +impl Foo { } // ok! ``` From 0e6a941820dcb39f5abab156e423cf3e28970c9f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:19:37 +0100 Subject: [PATCH 0394/1253] Don't keep link title either, text is generated outside of the link tag --- src/librustdoc/html/markdown.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b2f5c8e81ff7e..c87964af0200c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -381,8 +381,7 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, _ => {} } match event { - Event::Start(Tag::Link(_, _, text)) => self.buf.push_back(Event::Text(text)), - Event::End(Tag::Link(..)) => {} + Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {} event => self.buf.push_back(event), } } From 5022dd3b854792dd72d396e1586aa5b5c09975b2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:26:43 +0100 Subject: [PATCH 0395/1253] Extend url in titles test --- src/test/rustdoc/remove-url-from-headings.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs index 7fbcdbafa7486..50e45a7f53a1e 100644 --- a/src/test/rustdoc/remove-url-from-headings.rs +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -3,10 +3,15 @@ // @has foo/fn.foo.html // !@has - '//a[@href="http://a.a"]' // @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere' +// @has - '//a[@href="#another-one-urg"]' 'Another one urg' /// fooo /// /// # Implementing [stuff](http://a.a) somewhere /// /// hello +/// +/// # Another [one][two] urg +/// +/// [two]: http://a.a pub fn foo() {} From 25f1bf9a66c60eaced6eca70507f36cbc4ac6b44 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 16 Jan 2020 16:07:54 +0100 Subject: [PATCH 0396/1253] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 920cdb59e1edf..a8d90f6a57925 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 920cdb59e1edf2c4cb2f266fa521f12c1b97a499 +Subproject commit a8d90f6a57925d204efb21b3f6d9726d6674f9bd From eed0d33a65bd3f315bdf2d26511676f61e95120e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 16 Jan 2020 16:18:08 +0100 Subject: [PATCH 0397/1253] Array repeat expression lengths must be monomorphic at MIR building time --- src/librustc_mir_build/hair/cx/expr.rs | 27 ++++++++++--------- .../ui/consts/associated_const_generic.rs | 25 +++++++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/consts/associated_const_generic.rs diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index 97e718118292d..d6786ea247973 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -411,18 +411,21 @@ fn make_mirror_unadjusted<'a, 'tcx>( let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let span = cx.tcx.def_span(def_id); - let count = - match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, None, Some(span)) { - Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), - Err(ErrorHandled::Reported) => 0, - Err(ErrorHandled::TooGeneric) => { - let span = cx.tcx.def_span(def_id); - cx.tcx - .sess - .span_err(span, "array lengths can't depend on generic parameters"); - 0 - } - }; + let count = match cx.tcx.const_eval_resolve( + ty::ParamEnv::reveal_all(), + def_id, + substs, + None, + Some(span), + ) { + Ok(cv) => cv.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()), + Err(ErrorHandled::Reported) => 0, + Err(ErrorHandled::TooGeneric) => { + let span = cx.tcx.def_span(def_id); + cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); + 0 + } + }; ExprKind::Repeat { value: v.to_ref(), count } } diff --git a/src/test/ui/consts/associated_const_generic.rs b/src/test/ui/consts/associated_const_generic.rs new file mode 100644 index 0000000000000..dee376cc17b40 --- /dev/null +++ b/src/test/ui/consts/associated_const_generic.rs @@ -0,0 +1,25 @@ +// check-pass + +trait TraitA { + const VALUE: usize; +} + +struct A; +impl TraitA for A { + const VALUE: usize = 1; +} + +trait TraitB { + type MyA: TraitA; + const VALUE: usize = Self::MyA::VALUE; +} + +struct B; +impl TraitB for B { + type MyA = A; +} + +fn main() { + let _ = [0; A::VALUE]; + let _ = [0; B::VALUE]; // Indirectly refers to `A::VALUE` +} From 6fd564112f1ec00f6f8a56e8a3577dd255639131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 13:13:12 -0800 Subject: [PATCH 0398/1253] Specific error for unsized `dyn Trait` return type Suggest `impl Trait` when possible, and `Box` otherwise. --- src/librustc/traits/error_reporting.rs | 201 +++++++++++++++++- src/librustc/traits/mod.rs | 11 + src/librustc_error_codes/error_codes.rs | 1 + src/test/ui/error-codes/E0746.rs | 17 ++ src/test/ui/error-codes/E0746.stderr | 62 ++++++ .../dyn-trait-return-should-be-impl-trait.rs | 36 ++++ ...n-trait-return-should-be-impl-trait.stderr | 186 ++++++++++++++++ 7 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/error-codes/E0746.rs create mode 100644 src/test/ui/error-codes/E0746.stderr create mode 100644 src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs create mode 100644 src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7f151af7abe50..8f771658e4098 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength use super::{ ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, @@ -22,9 +23,12 @@ use crate::ty::TypeckTables; use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style}; +use rustc_errors::{ + error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, +}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym}; @@ -758,7 +762,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )), Some( "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" + conversion on the error value using the `From` trait" .to_owned(), ), ) @@ -835,6 +839,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.suggest_remove_reference(&obligation, &mut err, &trait_ref); self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); self.note_version_mismatch(&mut err, &trait_ref); + if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { + err.emit(); + return; + } // Try to report a help message if !trait_ref.has_infer_types() @@ -1696,6 +1704,195 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn suggest_impl_trait( + &self, + err: &mut DiagnosticBuilder<'tcx>, + span: Span, + obligation: &PredicateObligation<'tcx>, + trait_ref: &ty::Binder>, + ) -> bool { + if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { + } else { + return false; + } + + let hir = self.tcx.hir(); + let parent_node = hir.get_parent_node(obligation.cause.body_id); + let node = hir.find(parent_node); + if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(sig, _, body_id), .. + })) = node + { + let body = hir.body(*body_id); + let trait_ref = self.resolve_vars_if_possible(trait_ref); + let ty = trait_ref.skip_binder().self_ty(); + if let ty::Dynamic(..) = ty.kind { + } else { + // We only want to suggest `impl Trait` to `dyn Trait`s. + // For example, `fn foo() -> str` needs to be filtered out. + return false; + } + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for + // cases like `fn foo() -> (dyn Trait, i32) {}`. + // Recursively look for `TraitObject` types and if there's only one, use that span to + // suggest `impl Trait`. + + struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + + impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } + } + + // Visit to make sure there's a single `return` type to suggest `impl Trait`, + // otherwise suggest using `Box` or an enum. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + + if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { + for predicate in predicates.iter() { + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; + } + last_ty = Some(returned_ty); + + let param_env = ty::ParamEnv::empty(); + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obligation = + Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= + self.predicate_may_hold(&obligation); + } + } + } + } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; + } + last_ty = Some(returned_ty); + } + } + } + + if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + ret_ty.span.overlaps(span), + &ret_ty.kind, + self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + all_returns_conform_to_trait, + last_ty, + ) { + err.code = Some(error_code!(E0746)); + err.set_primary_message( + "return type cannot have a bare trait because it must be `Sized`", + ); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + err.span_suggestion( + ret_ty.span, + &format!( + "you can use the `impl Trait` feature \ + in the return type because all the return paths are of type \ + `{}`, which implements `dyn {}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MaybeIncorrect, + ); + err.note(impl_trait_msg); + } else { + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx + .sess + .source_map() + .span_to_snippet(expr.span) + .unwrap() + ), + ) + }) + .collect::>(); + suggestions.push(( + ret_ty.span, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "if the performance implications are acceptable, you can return a \ + trait object", + suggestions, + Applicability::MaybeIncorrect, + ); + err.span_help( + visitor.0.iter().map(|expr| expr.span).collect::>(), + &format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + ), + ); + err.help( + "alternatively, you can always create a new `enum` with a variant \ + for each returned type", + ); + err.note(impl_trait_msg); + err.note(trait_obj_msg); + } + return true; + } + } + } + false + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 31de5409fc8be..f68711c06205b 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1171,6 +1171,17 @@ impl<'tcx> ObligationCause<'tcx> { } } +impl<'tcx> ObligationCauseCode<'tcx> { + pub fn peel_derives(&self) -> &Self { + match self { + BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) => { + cause.parent_code.peel_derives() + } + _ => self, + } + } +} + impl<'tcx, N> Vtable<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 272147e28a419..c17cb7dd9f161 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -608,4 +608,5 @@ E0745: include_str!("./error_codes/E0745.md"), E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0739, // invalid track_caller application/syntax + E0746, // `dyn Trait` return type } diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs new file mode 100644 index 0000000000000..ad257b01e1b40 --- /dev/null +++ b/src/test/ui/error-codes/E0746.rs @@ -0,0 +1,17 @@ +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn foo() -> dyn Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 + +fn bar() -> dyn Trait { //~ ERROR E0746 + if true { + return 0; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr new file mode 100644 index 0000000000000..baafcd27c29d4 --- /dev/null +++ b/src/test/ui/error-codes/E0746.stderr @@ -0,0 +1,62 @@ +error[E0308]: mismatched types + --> $DIR/E0746.rs:6:25 + | +LL | fn foo() -> dyn Trait { Struct } + | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/E0746.rs:6:13 + | +LL | fn foo() -> dyn Trait { Struct } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn foo() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/E0746.rs:10:13 + | +LL | fn bar() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` + | +LL | fn bar() -> impl Trait { + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/E0746.rs:12:16 + | +LL | fn bar() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return 0; + | ^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/E0746.rs:14:5 + | +LL | fn bar() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs new file mode 100644 index 0000000000000..80168ca825774 --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -0,0 +1,36 @@ +#![allow(bare_trait_objects)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn fuz() -> (usize, Trait) { (42, Struct) } +//~^ ERROR E0277 +//~| ERROR E0308 +fn bar() -> (usize, dyn Trait) { (42, Struct) } +//~^ ERROR E0277 +//~| ERROR E0308 +fn bap() -> Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 +fn ban() -> dyn Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 +fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0277 +// Suggest using `Box` +fn bal() -> dyn Trait { //~ ERROR E0746 + if true { + return Struct; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +// Suggest using `impl Trait` +fn bat() -> dyn Trait { //~ ERROR E0746 + if true { + return 0; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr new file mode 100644 index 0000000000000..ce4c141a0af9d --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -0,0 +1,186 @@ +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35 + | +LL | fn fuz() -> (usize, Trait) { (42, Struct) } + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13 + | +LL | fn fuz() -> (usize, Trait) { (42, Struct) } + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39 + | +LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13 + | +LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:21 + | +LL | fn bap() -> Trait { Struct } + | ----- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 + | +LL | fn bap() -> Trait { Struct } + | ^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn bap() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:25 + | +LL | fn ban() -> dyn Trait { Struct } + | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:13 + | +LL | fn ban() -> dyn Trait { Struct } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn ban() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 + | +LL | fn bak() -> dyn Trait { unimplemented!() } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:16 + | +LL | fn bal() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return Struct; + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13 + | +LL | fn bal() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | +help: if all the returned values were of the same type you could use `impl Trait` as the return type + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + | +LL | return Struct; + | ^^^^^^ +LL | } +LL | 42 + | ^^ + = help: alternatively, you can always create a new `enum` with a variant for each returned type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see +help: if the performance implications are acceptable, you can return a trait object + | +LL | fn bal() -> Box { +LL | if true { +LL | return Box::new(Struct); +LL | } +LL | Box::new(42) + | + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + | +LL | fn bal() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:13 + | +LL | fn bat() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` + | +LL | fn bat() -> impl Trait { + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:31:16 + | +LL | fn bat() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return 0; + | ^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:5 + | +LL | fn bat() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From 75eabb17aec390fd91b5bf11539012e4fc7307b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 13:14:11 -0800 Subject: [PATCH 0399/1253] Account for diverging types in return `impl Trait` --- src/librustc_typeck/check/coercion.rs | 28 +++++++++++++++++ src/test/ui/impl-trait/equality.stderr | 5 ++++ ...type-err-cause-on-impl-trait-return.stderr | 30 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 1afb703ca1506..698fdfa3897b1 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1348,6 +1348,34 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { "...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected), )); + err.note( + "`impl Trait` as a return type requires that all the returned values must have \ + the same type", + ); + let snippet = fcx + .tcx + .sess + .source_map() + .span_to_snippet(return_sp) + .unwrap_or_else(|_| "dyn Trait".to_string()); + let mut snippet_iter = snippet.split_whitespace(); + let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + if has_impl { + err.help(&format!( + "you can instead return a trait object using `Box`", + &snippet[5..] + )); + } + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + err.note(impl_trait_msg); + if has_impl { + err.note(trait_obj_msg); + } } err } diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index e53524e58d663..215b6d52918ab 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -9,6 +9,11 @@ LL | return 1_i32; LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 27b86007451d8..9db5250e4d876 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -9,6 +9,11 @@ LL | return 0i32; LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 @@ -21,6 +26,11 @@ LL | return 0i32; LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9 @@ -33,6 +43,11 @@ LL | return 0i32; LL | } else { LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 @@ -57,6 +72,11 @@ LL | 0 => return 0i32, | ---- ...is found to be `i32` here LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5 @@ -71,6 +91,11 @@ LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13 @@ -83,6 +108,11 @@ LL | return 0i32; ... LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error: aborting due to 7 previous errors From ea7e885204e1ed6b18406e84708abef748925ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 16:12:44 -0800 Subject: [PATCH 0400/1253] Elide E0308 errors in favor of E0746 When a type error involves a `dyn Trait` as the return type, do not emit the type error, as the "return type is not `Sized`" error will provide enough information to the user. --- src/librustc_typeck/check/coercion.rs | 19 ++++- src/librustc_typeck/check/mod.rs | 12 +++ src/test/ui/error-codes/E0746.rs | 5 +- src/test/ui/error-codes/E0746.stderr | 40 +-------- .../dyn-trait-return-should-be-impl-trait.rs | 10 +-- ...n-trait-return-should-be-impl-trait.stderr | 82 ++----------------- 6 files changed, 44 insertions(+), 124 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 698fdfa3897b1..77f16fb79141d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1222,6 +1222,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }; let mut err; + let mut unsized_return = false; match cause.code { ObligationCauseCode::ReturnNoExpression => { err = struct_span_err!( @@ -1243,6 +1244,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { parent_id, expression.map(|expr| (expr, blk_id)), ); + if !fcx.tcx.features().unsized_locals { + unsized_return = fcx.is_unsized_return(blk_id); + } } ObligationCauseCode::ReturnValue(id) => { err = self.report_return_mismatched_types( @@ -1254,6 +1258,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { id, None, ); + if !fcx.tcx.features().unsized_locals { + let id = fcx.tcx.hir().get_parent_node(id); + unsized_return = fcx.is_unsized_return(id); + } } _ => { err = fcx.report_mismatched_types(cause, expected, found, coercion_error); @@ -1282,7 +1290,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) .is_some(); - err.emit_unless(assign_to_bool); + if unsized_return { + fcx.tcx.sess.delay_span_bug( + cause.span, + &format!( + "elided E0308 in favor of more detailed E0277 or E0746: {:?}", + cause.code + ), + ); + } + err.emit_unless(assign_to_bool || unsized_return); self.final_ty = Some(fcx.tcx.types.err); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index baf9ae1ac2911..8f531ea6199e1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4964,6 +4964,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn is_unsized_return(&self, blk_id: hir::HirId) -> bool { + if let Some((fn_decl, _)) = self.get_fn_decl(blk_id) { + if let hir::FunctionRetTy::Return(ty) = fn_decl.output { + let ty = AstConv::ast_ty_to_ty(self, ty); + if let ty::Dynamic(..) = ty.kind { + return true; + } + } + } + false + } + /// A possible error is to forget to add a return type that is needed: /// /// ``` diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index ad257b01e1b40..c9ab455a4c5b4 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -5,13 +5,12 @@ impl Trait for u32 {} fn foo() -> dyn Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn bar() -> dyn Trait { //~ ERROR E0746 if true { - return 0; //~ ERROR E0308 + return 0; } - 42 //~ ERROR E0308 + 42 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index baafcd27c29d4..44bd0d7ed7d37 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,14 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/E0746.rs:6:25 - | -LL | fn foo() -> dyn Trait { Struct } - | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` --> $DIR/E0746.rs:6:13 | @@ -22,7 +11,7 @@ LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:10:13 + --> $DIR/E0746.rs:9:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time @@ -33,30 +22,5 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bar() -> impl Trait { | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/E0746.rs:12:16 - | -LL | fn bar() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return 0; - | ^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/E0746.rs:14:5 - | -LL | fn bar() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index 80168ca825774..b70a51dc82511 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -12,25 +12,23 @@ fn bar() -> (usize, dyn Trait) { (42, Struct) } //~| ERROR E0308 fn bap() -> Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn ban() -> dyn Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0277 // Suggest using `Box` fn bal() -> dyn Trait { //~ ERROR E0746 if true { - return Struct; //~ ERROR E0308 + return Struct; } - 42 //~ ERROR E0308 + 42 } // Suggest using `impl Trait` fn bat() -> dyn Trait { //~ ERROR E0746 if true { - return 0; //~ ERROR E0308 + return 0; } - 42 //~ ERROR E0308 + 42 } fn main() {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ce4c141a0af9d..a09ce2bb29863 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -38,17 +38,6 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:21 - | -LL | fn bap() -> Trait { Struct } - | ----- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 | @@ -61,19 +50,8 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bap() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:25 - | -LL | fn ban() -> dyn Trait { Struct } - | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13 | LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -85,7 +63,7 @@ LL | fn ban() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13 | LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -94,26 +72,14 @@ LL | fn bak() -> dyn Trait { unimplemented!() } = note: to learn more, visit = note: the return type of a function must have a statically known size -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:16 - | -LL | fn bal() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return Struct; - | ^^^^^^ expected trait `Trait`, found struct `Struct` - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 | LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | help: if all the returned values were of the same type you could use `impl Trait` as the return type - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:5 | LL | return Struct; | ^^^^^^ @@ -132,20 +98,8 @@ LL | } LL | Box::new(42) | -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 - | -LL | fn bal() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time @@ -156,31 +110,7 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bat() -> impl Trait { | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:31:16 - | -LL | fn bat() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return 0; - | ^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:5 - | -LL | fn bat() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error: aborting due to 15 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. From b4bbe784a9dc1f97f07e2543c6f726cb1eb4cc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 16:13:51 -0800 Subject: [PATCH 0401/1253] Make `impl Trait` suggestion in E0746 `MachineApplicable` --- src/librustc/traits/error_reporting.rs | 2 +- src/test/ui/error-codes/E0746.fixed | 18 ++++++++++++++++++ src/test/ui/error-codes/E0746.rs | 2 ++ src/test/ui/error-codes/E0746.stderr | 4 ++-- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/error-codes/E0746.fixed diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8f771658e4098..8d0923f571851 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1840,7 +1840,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { last_ty, trait_obj, ), format!("impl {}", trait_obj), - Applicability::MaybeIncorrect, + Applicability::MachineApplicable, ); err.note(impl_trait_msg); } else { diff --git a/src/test/ui/error-codes/E0746.fixed b/src/test/ui/error-codes/E0746.fixed new file mode 100644 index 0000000000000..ca8319aa020dc --- /dev/null +++ b/src/test/ui/error-codes/E0746.fixed @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(dead_code)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn foo() -> impl Trait { Struct } +//~^ ERROR E0746 + +fn bar() -> impl Trait { //~ ERROR E0746 + if true { + return 0; + } + 42 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index c9ab455a4c5b4..bf5ba8fff562a 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(dead_code)] struct Struct; trait Trait {} impl Trait for Struct {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 44bd0d7ed7d37..0cffd108226d8 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,5 +1,5 @@ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:6:13 + --> $DIR/E0746.rs:8:13 | LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -11,7 +11,7 @@ LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:9:13 + --> $DIR/E0746.rs:11:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time From e1dd8a909531cd66080ca89227fb8828a01d7e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:19:52 -0800 Subject: [PATCH 0402/1253] When trait bounds are missing for return values, point at them --- src/librustc/traits/error_reporting.rs | 122 +++++++++++------- .../issue-64130-4-async-move.stderr | 13 +- .../alloc-traits-no-impls-length-33.stderr | 15 +++ .../into-iter-no-impls-length-33.stderr | 21 +++ .../impl_bounds.stderr | 2 +- ...n-trait-return-should-be-impl-trait.stderr | 8 +- src/test/ui/issues/issue-58344.stderr | 6 + src/test/ui/issues/issue-5883.stderr | 3 + .../lifetime-elision-return-type-trait.stderr | 3 + .../feature-gate-never_type_fallback.stderr | 4 + .../generic_underconstrained2.stderr | 4 + 11 files changed, 147 insertions(+), 54 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8d0923f571851..d5af1a9a42dd7 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1130,6 +1130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; self.note_obligation_cause(&mut err, obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); err.emit(); } @@ -1737,35 +1738,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Recursively look for `TraitObject` types and if there's only one, use that span to // suggest `impl Trait`. - struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); - - impl<'v> Visitor<'v> for ReturnsVisitor<'v> { - type Map = rustc::hir::map::Map<'v>; - - fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { - hir::intravisit::NestedVisitorMap::None - } - - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} - } - hir::intravisit::walk_expr(self, ex); - } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - if body.generator_kind().is_none() { - if let hir::ExprKind::Block(block, None) = body.value.kind { - if let Some(expr) = block.expr { - self.0.push(expr); - } - } - } - hir::intravisit::walk_body(self, body); - } - } - // Visit to make sure there's a single `return` type to suggest `impl Trait`, // otherwise suggest using `Box` or an enum. let mut visitor = ReturnsVisitor(vec![]); @@ -1893,6 +1865,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { false } + fn point_at_returns_when_relevant( + &self, + err: &mut DiagnosticBuilder<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) { + if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { + } else { + return; + } + + let hir = self.tcx.hir(); + let parent_node = hir.get_parent_node(obligation.cause.body_id); + let node = hir.find(parent_node); + if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) = + node + { + let body = hir.body(*body_id); + // Point at all the `return`s in the function as they have failed trait bounds. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + err.span_label( + expr.span, + &format!("this returned value is of type `{}`", returned_ty), + ); + } + } + } + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to @@ -2911,19 +2915,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expressions) => { err.note( - "the `Copy` trait is required because the \ - repeated element will be copied", + "the `Copy` trait is required because the repeated element will be copied", ); if suggest_const_in_array_repeat_expressions { err.note( "this array initializer can be evaluated at compile-time, for more \ - information, see issue \ - https://github.com/rust-lang/rust/issues/49147", + information, see issue \ + https://github.com/rust-lang/rust/issues/49147", ); if tcx.sess.opts.unstable_features.is_nightly_build() { err.help( "add `#![feature(const_in_array_repeat_expressions)]` to the \ - crate attributes to enable", + crate attributes to enable", ); } } @@ -2941,16 +2944,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } ObligationCauseCode::SizedReturnType => { - err.note( - "the return type of a function must have a \ - statically known size", - ); + err.note("the return type of a function must have a statically known size"); } ObligationCauseCode::SizedYieldType => { - err.note( - "the yield type of a generator must have a \ - statically known size", - ); + err.note("the yield type of a generator must have a statically known size"); } ObligationCauseCode::AssignmentLhsSized => { err.note("the left-hand-side of an assignment must have a statically known size"); @@ -2966,12 +2963,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if last { err.note( "the last field of a packed struct may only have a \ - dynamically sized type if it does not need drop to be run", + dynamically sized type if it does not need drop to be run", ); } else { err.note( - "only the last field of a struct may have a dynamically \ - sized type", + "only the last field of a struct may have a dynamically sized type", ); } } @@ -3025,13 +3021,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::CompareImplMethodObligation { .. } => { err.note(&format!( "the requirement `{}` appears on the impl method \ - but not on the corresponding trait method", + but not on the corresponding trait method", predicate )); } ObligationCauseCode::CompareImplTypeObligation { .. } => { err.note(&format!( - "the requirement `{}` appears on the associated impl type\ + "the requirement `{}` appears on the associated impl type \ but not on the corresponding associated trait type", predicate )); @@ -3043,8 +3039,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { err.help( - "add `#![feature(trivial_bounds)]` to the \ - crate attributes to enable", + "add `#![feature(trivial_bounds)]` to the crate attributes to enable", ); } } @@ -3186,3 +3181,32 @@ pub fn suggest_constraining_type_param( } false } + +struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + +impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } +} diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index 77d0885c38d58..f59dbc2638400 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -1,8 +1,17 @@ error: future cannot be sent between threads safely --> $DIR/issue-64130-4-async-move.rs:15:17 | -LL | pub fn foo() -> impl Future + Send { - | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` +LL | pub fn foo() -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` +... +LL | / async move { +LL | | match client.status() { +LL | | 200 => { +LL | | let _x = get().await; +... | +LL | | } +LL | | } + | |_____- this returned value is of type `impl std::future::Future` | = help: the trait `std::marker::Sync` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr index 5c37468130c64..6e5afcdb8bb68 100644 --- a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr @@ -3,6 +3,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vec_partial_eq_array() -> impl PartialEq<[B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | Vec::::new() + | --------------- this returned value is of type `std::vec::Vec` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec` = note: the return type of a function must have a statically known size @@ -12,6 +15,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | Vec::::new() + | --------------- this returned value is of type `std::vec::Vec` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec` = note: the return type of a function must have a statically known size @@ -21,6 +27,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size @@ -30,6 +39,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size @@ -39,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr index bfdff8e3bbe61..e615e10bd5f5f 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr @@ -11,6 +11,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_iterator() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -28,6 +31,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_double_ended_iterator() -> impl DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::DoubleEndedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -45,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_exact_size_iterator() -> impl ExactSizeIterator { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::ExactSizeIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -62,6 +71,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_fused_iterator() -> impl FusedIterator { | ^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::FusedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -79,6 +91,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_trusted_len() -> impl TrustedLen { | ^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::TrustedLen` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -96,6 +111,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_clone() -> impl Clone { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -113,6 +131,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_debug() -> impl Debug { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::array::IntoIter` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr index 017990076931b..ca2350ff7577f 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.stderr +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -38,7 +38,7 @@ LL | type C where Self: Copy = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` | = note: required because of the requirements on the impl of `std::marker::Copy` for `Fooy` - = note: the requirement `Fooy: std::marker::Copy` appears on the associated impl typebut not on the corresponding associated trait type + = note: the requirement `Fooy: std::marker::Copy` appears on the associated impl type but not on the corresponding associated trait type error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index a09ce2bb29863..d51cd6aeae6ec 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -11,7 +11,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13 | LL | fn fuz() -> (usize, Trait) { (42, Struct) } - | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))` + | | + | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` = note: to learn more, visit @@ -31,7 +33,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13 | LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } - | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))` + | | + | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-58344.stderr b/src/test/ui/issues/issue-58344.stderr index 427d03b679d5f..9b07dbd7ab69c 100644 --- a/src/test/ui/issues/issue-58344.stderr +++ b/src/test/ui/issues/issue-58344.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `impl Trait<::Output>: Trait | LL | ) -> Either>::Output>, impl Trait<>::Output>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Trait<::Output>` +... +LL | add_generic(value, 1u32) + | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` | = note: the return type of a function must have a statically known size @@ -11,6 +14,9 @@ error[E0277]: the trait bound `impl Trait<::Output>: Trait | LL | ) -> Either>::Output>, impl Trait<>::Output>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Trait<::Output>` +... +LL | add_generic(value, 1u32) + | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/issues/issue-5883.stderr b/src/test/ui/issues/issue-5883.stderr index c2de1d095505a..d886ecc11d17b 100644 --- a/src/test/ui/issues/issue-5883.stderr +++ b/src/test/ui/issues/issue-5883.stderr @@ -14,6 +14,9 @@ error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at | LL | -> Struct { | ^^^^^^ doesn't have a size known at compile-time +LL | +LL | Struct { r: r } + | --------------- this returned value is of type `Struct` | = help: within `Struct`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)` = note: to learn more, visit diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 228582d0001da..49fa11c35aef8 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `std::result::Result<(), _>: Future` is not satisf | LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>` +LL | +LL | Ok(()) + | ------ this returned value is of type `std::result::Result<_, _>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 837e90d6ceb9b..88bfed2b54742 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -3,8 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- this returned value is of type `_` | = note: the return type of a function must have a statically known size + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index d4c7c7c74529e..9e8414f9c15fe 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -18,6 +18,8 @@ LL | type Underconstrained = impl 'static; ... LL | fn underconstrained(_: U) -> Underconstrained { | - help: consider restricting this bound: `U: std::fmt::Debug` +LL | 5u32 + | ---- this returned value is of type `u32` | = help: the trait `std::fmt::Debug` is not implemented for `U` = note: the return type of a function must have a statically known size @@ -30,6 +32,8 @@ LL | type Underconstrained2 = impl 'static; ... LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | - help: consider restricting this bound: `V: std::fmt::Debug` +LL | 5u32 + | ---- this returned value is of type `u32` | = help: the trait `std::fmt::Debug` is not implemented for `V` = note: the return type of a function must have a statically known size From 93293c56e85a2afdde8664bc08303d5f5853ba29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:20:28 -0800 Subject: [PATCH 0403/1253] fmt --- src/librustc/traits/error_reporting.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d5af1a9a42dd7..77a73aba45484 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -3038,9 +3038,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { - err.help( - "add `#![feature(trivial_bounds)]` to the crate attributes to enable", - ); + err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable"); } } ObligationCauseCode::AssocTypeBound(ref data) => { From 4c13d2555c4535516eb00dd0221c9d158b91e31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:21:31 -0800 Subject: [PATCH 0404/1253] Add E0746 explanation to the index --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0746.md | 137 ++++++++++++++++++ src/test/ui/error-codes/E0746.stderr | 1 + ...n-trait-return-should-be-impl-trait.stderr | 2 +- 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0746.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index c17cb7dd9f161..180ccb15977dd 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -414,6 +414,7 @@ E0742: include_str!("./error_codes/E0742.md"), E0743: include_str!("./error_codes/E0743.md"), E0744: include_str!("./error_codes/E0744.md"), E0745: include_str!("./error_codes/E0745.md"), +E0746: include_str!("./error_codes/E0746.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard @@ -608,5 +609,4 @@ E0745: include_str!("./error_codes/E0745.md"), E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0739, // invalid track_caller application/syntax - E0746, // `dyn Trait` return type } diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md new file mode 100644 index 0000000000000..538c9d720d71b --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -0,0 +1,137 @@ +Return types cannot be `dyn Trait`s as they must be `Sized`. + +Erroneous code example: + +```compile_fail,E0746 +trait T { + fn bar(&self); +} +struct S(usize); +impl T for S { + fn bar(&self) {} +} + +// Having the trait `T` as return type is invalid because bare traits do not +have a statically known size: +fn foo() -> dyn T { + S(42) +} +``` + +To avoid the error there are a couple of options. + +If there is a single type involved, you can use [`impl Trait`]: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +// The compiler will select `S(usize)` as the materialized return type of this +// function, but callers will only be able to access associated items from `T`. +fn foo() -> impl T { + S(42) +} +``` + +If there are multiple types involved, the only way you care to interact with +them is through the trait's interface and having to rely on dynamic dispatch is +acceptable, then you can use [trait objects] with `Box`, or other container +types like `Rc` or `Arc`: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +struct O(&'static str); +impl T for O { + fn bar(&self) {} +} + +// This now returns a "trait object" and callers are only be able to access +// associated items from `T`. +fn foo(x: bool) -> Box { + if x { + Box::new(S(42)) + } else { + Box::new(O("val")) + } +} +``` + +Finally, if you wish to still be able to access the original type, you can +create a new `enum` with a variant for each type: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +enum E { + S(S), + O(O), +} + +// The caller can access the original types directly, but it needs to match on +// the returned `enum E`. +fn foo(x: bool) -> E { + if x { + E::S(S(42)) + } else { + E::O(O("val")) + } +} +``` + +You can even implement the `trait` on the returned `enum` so the callers +*don't* have to match on the returned value to invoke the associated items: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +# enum E { +# S(S), +# O(O), +# } +impl T for E { + fn bar(&self) { + match self { + E::S(s) => s.bar(), + E::O(o) => o.bar(), + } + } +} +``` + +If you decide to use trait objects, be aware that these rely on +[dynamic dispatch], which has performance implications, as the compiler needs +to emit code that will figure out which method to call *at runtime* instead of +during compilation. Using trait objects we are trading flexibility for +performance. + +[`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits +[trait objects]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types +[dynamic dispatch]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 0cffd108226d8..1c88ce64749ae 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -24,3 +24,4 @@ LL | fn bar() -> impl Trait { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0746`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index d51cd6aeae6ec..ff7438e9affc1 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -116,5 +116,5 @@ LL | fn bat() -> impl Trait { error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0308. +Some errors have detailed explanations: E0277, E0308, E0746. For more information about an error, try `rustc --explain E0277`. From 9dee5d582f538e1d12f278e23ee47cb7c201c9b7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jan 2020 13:31:56 +0100 Subject: [PATCH 0405/1253] fix rustfmt fallout --- src/librustc/mir/interpret/error.rs | 5 +++-- src/librustc/mir/interpret/mod.rs | 4 ++-- src/librustc_mir/interpret/cast.rs | 20 +++++++++++--------- src/librustc_mir/interpret/eval_context.rs | 12 +++++++++--- src/librustc_mir/interpret/memory.rs | 4 ++-- src/librustc_mir/interpret/operand.rs | 22 +++++++++++----------- src/librustc_mir/interpret/place.rs | 11 +++++------ src/librustc_mir/interpret/validity.rs | 10 +++++----- 8 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 8643bd63d8cba..29b3b045ca5fe 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -33,7 +33,7 @@ impl ErrorHandled { ErrorHandled::Reported => {} ErrorHandled::TooGeneric => bug!( "MIR interpretation failed without reporting an error \ - even though it was fully monomorphized" + even though it was fully monomorphized" ), } } @@ -137,7 +137,8 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { let must_error = match self.error { InterpError::MachineStop(_) => bug!("CTFE does not stop"), - err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::Unknown(_))) + | err_inval!(TooGeneric) => { return Err(ErrorHandled::TooGeneric); } err_inval!(TypeckError) => return Err(ErrorHandled::Reported), diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 47f067590b9d5..e554b280ef78c 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -403,8 +403,8 @@ impl<'tcx> AllocMap<'tcx> { let next = self.next_id; self.next_id.0 = self.next_id.0.checked_add(1).expect( "You overflowed a u64 by incrementing by 1... \ - You've just earned yourself a free drink if we ever meet. \ - Seriously, how did you do that?!", + You've just earned yourself a free drink if we ever meet. \ + Seriously, how did you do that?!", ); next } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 9461a06690212..6d0b6bf70ad8c 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -118,15 +118,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that // are represented as integers. - _ => assert!( - src.layout.ty.is_bool() - || src.layout.ty.is_char() - || src.layout.ty.is_enum() - || src.layout.ty.is_integral() - || src.layout.ty.is_any_ptr(), - "Unexpected cast from type {:?}", - src.layout.ty - ), + _ => { + assert!( + src.layout.ty.is_bool() + || src.layout.ty.is_char() + || src.layout.ty.is_enum() + || src.layout.ty.is_integral() + || src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", + src.layout.ty + ) + } } // Handle cast from a univariant (ZST) enum. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 206d3d156735e..3d590fb820359 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -152,10 +152,16 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => throw_unsup!(DeadLocal), - LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), + LocalValue::Dead => { + throw_unsup!(DeadLocal) + } + LocalValue::Live(Operand::Indirect(mplace)) => { + Ok(Err(mplace)) + } ref mut local @ LocalValue::Live(Operand::Immediate(_)) - | ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)), + | ref mut local @ LocalValue::Uninitialized => { + Ok(Ok(local)) + } } } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index cb676821fd438..3386254c93b75 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -581,9 +581,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok((layout.size, layout.align.abi)) } Some(GlobalAlloc::Memory(alloc)) => - // Need to duplicate the logic here, because the global allocations have - // different associated types than the interpreter-local ones. { + // Need to duplicate the logic here, because the global allocations have + // different associated types than the interpreter-local ones. Ok((alloc.size, alloc.align)) } Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b37eff3f40626..34a32daaab65f 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -543,7 +543,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::ConstKind::Placeholder(..) => { bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) } - ty::ConstKind::Value(val_val) => val_val, + ty::ConstKind::Value(val_val) => { + val_val + } }; // Other cases need layout. let layout = from_known_layout(layout, || self.layout_of(val.ty))?; @@ -684,16 +686,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variant_index = variants_start .checked_add(variant_index_relative) .expect("oveflow computing absolute variant idx"); - assert!( - (variant_index as usize) - < rval - .layout - .ty - .ty_adt_def() - .expect("tagged layout for non adt") - .variants - .len() - ); + let variants_len = rval + .layout + .ty + .ty_adt_def() + .expect("tagged layout for non adt") + .variants + .len(); + assert!((variant_index as usize) < variants_len); (u128::from(variant_index), VariantIdx::from_u32(variant_index)) } else { (u128::from(dataful_variant.as_u32()), dataful_variant) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 8888e3fd4632a..4f96cb698915d 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -432,12 +432,11 @@ where // happens at run-time so that's okay. let align = match self.size_and_align_of(base.meta, field_layout)? { Some((_, align)) => align, - None if offset == Size::ZERO => - // An extern type at offset 0, we fall back to its static alignment. - // FIXME: Once we have made decisions for how to handle size and alignment - // of `extern type`, this should be adapted. It is just a temporary hack - // to get some code to work that probably ought to work. - { + None if offset == Size::ZERO => { + // An extern type at offset 0, we fall back to its static alignment. + // FIXME: Once we have made decisions for how to handle size and alignment + // of `extern type`, this should be adapted. It is just a temporary hack + // to get some code to work that probably ought to work. field_layout.align.abi } None => bug!("Cannot compute offset for extern type field at non-0 offset"), diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 2f0fb81fffd13..d0fef08bb60c7 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -115,11 +115,11 @@ fn write_path(out: &mut String, path: &Vec) { TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), Deref => - // This does not match Rust syntax, but it is more readable for long paths -- and - // some of the other items here also are not Rust syntax. Actually we can't - // even use the usual syntax because we are just showing the projections, - // not the root. { + // This does not match Rust syntax, but it is more readable for long paths -- and + // some of the other items here also are not Rust syntax. Actually we can't + // even use the usual syntax because we are just showing the projections, + // not the root. write!(out, ".") } Tag => write!(out, "."), @@ -207,8 +207,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M // we might be projecting *to* a variant, or to a field *in*a variant. match layout.variants { layout::Variants::Single { index } => - // Inside a variant { + // Inside a variant PathElem::Field(def.variants[index].fields[field].ident.name) } _ => bug!(), From 00c82726122d550c586e11bf85501a93ce0fbf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 18:27:42 -0800 Subject: [PATCH 0406/1253] Split `librustc/traits/error_reporting.rs` --- src/librustc/traits/error_reporting/mod.rs | 1442 +++++++++++++++ .../error_reporting/on_unimplemented.rs | 199 +++ .../suggestions.rs} | 1557 +---------------- 3 files changed, 1667 insertions(+), 1531 deletions(-) create mode 100644 src/librustc/traits/error_reporting/mod.rs create mode 100644 src/librustc/traits/error_reporting/on_unimplemented.rs rename src/librustc/traits/{error_reporting.rs => error_reporting/suggestions.rs} (52%) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs new file mode 100644 index 0000000000000..f8329124851b0 --- /dev/null +++ b/src/librustc/traits/error_reporting/mod.rs @@ -0,0 +1,1442 @@ +pub mod on_unimplemented; +pub mod suggestions; + +use super::{ + ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, + MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, + ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, + OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, + TraitNotObjectSafe, +}; + +use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{self, InferCtxt}; +use crate::mir::interpret::ErrorHandled; +use crate::session::DiagnosticMessageId; +use crate::traits::object_safety_violations; +use crate::ty::error::ExpectedFound; +use crate::ty::fast_reject; +use crate::ty::fold::TypeFolder; +use crate::ty::SubtypePredicate; +use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; + +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_hir as hir; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::intravisit::Visitor; +use rustc_span::source_map::SourceMap; +use rustc_span::{ExpnKind, Span, DUMMY_SP}; +use std::fmt; +use syntax::ast; + +use rustc_error_codes::*; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + pub fn report_fulfillment_errors( + &self, + errors: &[FulfillmentError<'tcx>], + body_id: Option, + fallback_has_occurred: bool, + ) { + #[derive(Debug)] + struct ErrorDescriptor<'tcx> { + predicate: ty::Predicate<'tcx>, + index: Option, // None if this is an old error + } + + let mut error_map: FxHashMap<_, Vec<_>> = self + .reported_trait_errors + .borrow() + .iter() + .map(|(&span, predicates)| { + ( + span, + predicates + .iter() + .map(|predicate| ErrorDescriptor { + predicate: predicate.clone(), + index: None, + }) + .collect(), + ) + }) + .collect(); + + for (index, error) in errors.iter().enumerate() { + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + + error_map.entry(span).or_default().push(ErrorDescriptor { + predicate: error.obligation.predicate.clone(), + index: Some(index), + }); + + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_default() + .push(error.obligation.predicate.clone()); + } + + // We do this in 2 passes because we want to display errors in order, though + // maybe it *is* better to sort errors by span or something. + let mut is_suppressed = vec![false; errors.len()]; + for (_, error_set) in error_map.iter() { + // We want to suppress "duplicate" errors with the same span. + for error in error_set { + if let Some(index) = error.index { + // Suppress errors that are either: + // 1) strictly implied by another error. + // 2) implied by an error with a smaller index. + for error2 in error_set { + if error2.index.map_or(false, |index2| is_suppressed[index2]) { + // Avoid errors being suppressed by already-suppressed + // errors, to prevent all errors from being suppressed + // at once. + continue; + } + + if self.error_implies(&error2.predicate, &error.predicate) + && !(error2.index >= error.index + && self.error_implies(&error.predicate, &error2.predicate)) + { + info!("skipping {:?} (implied by {:?})", error, error2); + is_suppressed[index] = true; + break; + } + } + } + } + } + + for (error, suppressed) in errors.iter().zip(is_suppressed) { + if !suppressed { + self.report_fulfillment_error(error, body_id, fallback_has_occurred); + } + } + } + + // returns if `cond` not occurring implies that `error` does not occur - i.e., that + // `error` occurring implies that `cond` occurs. + fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool { + if cond == error { + return true; + } + + let (cond, error) = match (cond, error) { + (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), + _ => { + // FIXME: make this work in other cases too. + return false; + } + }; + + for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { + if let ty::Predicate::Trait(implication) = implication { + let error = error.to_poly_trait_ref(); + let implication = implication.to_poly_trait_ref(); + // FIXME: I'm just not taking associated types at all here. + // Eventually I'll need to implement param-env-aware + // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. + let param_env = ty::ParamEnv::empty(); + if self.can_sub(param_env, error, implication).is_ok() { + debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); + return true; + } + } + } + + false + } + + fn report_fulfillment_error( + &self, + error: &FulfillmentError<'tcx>, + body_id: Option, + fallback_has_occurred: bool, + ) { + debug!("report_fulfillment_error({:?})", error); + match error.code { + FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { + self.report_selection_error( + &error.obligation, + selection_error, + fallback_has_occurred, + error.points_at_arg_span, + ); + } + FulfillmentErrorCode::CodeProjectionError(ref e) => { + self.report_projection_error(&error.obligation, e); + } + FulfillmentErrorCode::CodeAmbiguity => { + self.maybe_report_ambiguity(&error.obligation, body_id); + } + FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { + self.report_mismatched_types( + &error.obligation.cause, + expected_found.expected, + expected_found.found, + err.clone(), + ) + .emit(); + } + } + } + + fn report_projection_error( + &self, + obligation: &PredicateObligation<'tcx>, + error: &MismatchedProjectionTypes<'tcx>, + ) { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + + if predicate.references_error() { + return; + } + + self.probe(|_| { + let err_buf; + let mut err = &error.err; + let mut values = None; + + // try to find the mismatched types to report the error with. + // + // this can fail if the problem was higher-ranked, in which + // cause I have no idea for a good error message. + if let ty::Predicate::Projection(ref data) = predicate { + let mut selcx = SelectionContext::new(self); + let (data, _) = self.replace_bound_vars_with_fresh_vars( + obligation.cause.span, + infer::LateBoundRegionConversionTime::HigherRankedType, + data, + ); + let mut obligations = vec![]; + let normalized_ty = super::normalize_projection_type( + &mut selcx, + obligation.param_env, + data.projection_ty, + obligation.cause.clone(), + 0, + &mut obligations, + ); + + debug!( + "report_projection_error obligation.cause={:?} obligation.param_env={:?}", + obligation.cause, obligation.param_env + ); + + debug!( + "report_projection_error normalized_ty={:?} data.ty={:?}", + normalized_ty, data.ty + ); + + let is_normalized_ty_expected = match &obligation.cause.code { + ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::BindingObligation(_, _) + | ObligationCauseCode::ObjectCastObligation(_) => false, + _ => true, + }; + + if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ) { + values = Some(infer::ValuePairs::Types(ExpectedFound::new( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ))); + + err_buf = error; + err = &err_buf; + } + } + + let msg = format!("type mismatch resolving `{}`", predicate); + let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); + let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); + if fresh { + let mut diag = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0271, + "type mismatch resolving `{}`", + predicate + ); + self.note_type_err(&mut diag, &obligation.cause, None, values, err); + self.note_obligation_cause(&mut diag, obligation); + diag.emit(); + } + }); + } + + fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { + /// returns the fuzzy category of a given type, or None + /// if the type can be equated to any type. + fn type_category(t: Ty<'_>) -> Option { + match t.kind { + ty::Bool => Some(0), + ty::Char => Some(1), + ty::Str => Some(2), + ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3), + ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4), + ty::Ref(..) | ty::RawPtr(..) => Some(5), + ty::Array(..) | ty::Slice(..) => Some(6), + ty::FnDef(..) | ty::FnPtr(..) => Some(7), + ty::Dynamic(..) => Some(8), + ty::Closure(..) => Some(9), + ty::Tuple(..) => Some(10), + ty::Projection(..) => Some(11), + ty::Param(..) => Some(12), + ty::Opaque(..) => Some(13), + ty::Never => Some(14), + ty::Adt(adt, ..) => match adt.adt_kind() { + AdtKind::Struct => Some(15), + AdtKind::Union => Some(16), + AdtKind::Enum => Some(17), + }, + ty::Generator(..) => Some(18), + ty::Foreign(..) => Some(19), + ty::GeneratorWitness(..) => Some(20), + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + } + } + + match (type_category(a), type_category(b)) { + (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) { + (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b, + _ => cat_a == cat_b, + }, + // infer and error can be equated to all types + _ => true, + } + } + + fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> { + self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind { + hir::GeneratorKind::Gen => "a generator", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", + }) + } + + fn find_similar_impl_candidates( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + ) -> Vec> { + let simp = fast_reject::simplify_type(self.tcx, trait_ref.skip_binder().self_ty(), true); + let all_impls = self.tcx.all_impls(trait_ref.def_id()); + + match simp { + Some(simp) => all_impls + .iter() + .filter_map(|&def_id| { + let imp = self.tcx.impl_trait_ref(def_id).unwrap(); + let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); + if let Some(imp_simp) = imp_simp { + if simp != imp_simp { + return None; + } + } + + Some(imp) + }) + .collect(), + None => { + all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() + } + } + } + + fn report_similar_impl_candidates( + &self, + impl_candidates: Vec>, + err: &mut DiagnosticBuilder<'_>, + ) { + if impl_candidates.is_empty() { + return; + } + + let len = impl_candidates.len(); + let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 }; + + let normalize = |candidate| { + self.tcx.infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }) + }; + + // Sort impl candidates so that ordering is consistent for UI tests. + let mut normalized_impl_candidates = + impl_candidates.iter().map(normalize).collect::>(); + + // Sort before taking the `..end` range, + // because the ordering of `impl_candidates` may not be deterministic: + // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 + normalized_impl_candidates.sort(); + + err.help(&format!( + "the following implementations were found:{}{}", + normalized_impl_candidates[..end].join(""), + if len > 5 { format!("\nand {} others", len - 4) } else { String::new() } + )); + } + + /// Reports that an overflow has occurred and halts compilation. We + /// halt compilation unconditionally because it is important that + /// overflows never be masked -- they basically represent computations + /// whose result could not be truly determined and thus we can't say + /// if the program type checks or not -- and they are unusual + /// occurrences in any case. + pub fn report_overflow_error( + &self, + obligation: &Obligation<'tcx, T>, + suggest_increasing_limit: bool, + ) -> ! + where + T: fmt::Display + TypeFoldable<'tcx>, + { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + let mut err = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0275, + "overflow evaluating the requirement `{}`", + predicate + ); + + if suggest_increasing_limit { + self.suggest_new_overflow_limit(&mut err); + } + + self.note_obligation_cause_code( + &mut err, + &obligation.predicate, + &obligation.cause.code, + &mut vec![], + ); + + err.emit(); + self.tcx.sess.abort_if_errors(); + bug!(); + } + + /// Reports that a cycle was detected which led to overflow and halts + /// compilation. This is equivalent to `report_overflow_error` except + /// that we can give a more helpful error message (and, in particular, + /// we do not suggest increasing the overflow limit, which is not + /// going to help). + pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { + let cycle = self.resolve_vars_if_possible(&cycle.to_owned()); + assert!(cycle.len() > 0); + + debug!("report_overflow_error_cycle: cycle={:?}", cycle); + + self.report_overflow_error(&cycle[0], false); + } + + pub fn report_extra_impl_obligation( + &self, + error_span: Span, + item_name: ast::Name, + _impl_item_def_id: DefId, + trait_item_def_id: DefId, + requirement: &dyn fmt::Display, + ) -> DiagnosticBuilder<'tcx> { + let msg = "impl has stricter requirements than trait"; + let sp = self.tcx.sess.source_map().def_span(error_span); + + let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg); + + if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) { + let span = self.tcx.sess.source_map().def_span(trait_item_span); + err.span_label(span, format!("definition of `{}` from trait", item_name)); + } + + err.span_label(sp, format!("impl has extra requirement {}", requirement)); + + err + } + + /// Gets the parent trait chain start + fn get_parent_trait_ref( + &self, + code: &ObligationCauseCode<'tcx>, + ) -> Option<(String, Option)> { + match code { + &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { + let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); + match self.get_parent_trait_ref(&data.parent_code) { + Some(t) => Some(t), + None => { + let ty = parent_trait_ref.skip_binder().self_ty(); + let span = + TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id)); + Some((ty.to_string(), span)) + } + } + } + _ => None, + } + } + + pub fn report_selection_error( + &self, + obligation: &PredicateObligation<'tcx>, + error: &SelectionError<'tcx>, + fallback_has_occurred: bool, + points_at_arg: bool, + ) { + let tcx = self.tcx; + let span = obligation.cause.span; + + let mut err = match *error { + SelectionError::Unimplemented => { + if let ObligationCauseCode::CompareImplMethodObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } + | ObligationCauseCode::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } = obligation.cause.code + { + self.report_extra_impl_obligation( + span, + item_name, + impl_item_def_id, + trait_item_def_id, + &format!("`{}`", obligation.predicate), + ) + .emit(); + return; + } + match obligation.predicate { + ty::Predicate::Trait(ref trait_predicate) => { + let trait_predicate = self.resolve_vars_if_possible(trait_predicate); + + if self.tcx.sess.has_errors() && trait_predicate.references_error() { + return; + } + let trait_ref = trait_predicate.to_poly_trait_ref(); + let (post_message, pre_message, type_def) = self + .get_parent_trait_ref(&obligation.cause.code) + .map(|(t, s)| { + ( + format!(" in `{}`", t), + format!("within `{}`, ", t), + s.map(|s| (format!("within this `{}`", t), s)), + ) + }) + .unwrap_or_default(); + + let OnUnimplementedNote { message, label, note, enclosing_scope } = + self.on_unimplemented_note(trait_ref, obligation); + let have_alt_message = message.is_some() || label.is_some(); + let is_try = self + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|s| &s == "?") + .unwrap_or(false); + let is_from = format!("{}", trait_ref.print_only_trait_path()) + .starts_with("std::convert::From<"); + let (message, note) = if is_try && is_from { + ( + Some(format!( + "`?` couldn't convert the error to `{}`", + trait_ref.self_ty(), + )), + Some( + "the question mark operation (`?`) implicitly performs a \ + conversion on the error value using the `From` trait" + .to_owned(), + ), + ) + } else { + (message, note) + }; + + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0277, + "{}", + message.unwrap_or_else(|| format!( + "the trait bound `{}` is not satisfied{}", + trait_ref.to_predicate(), + post_message, + )) + ); + + let explanation = + if obligation.cause.code == ObligationCauseCode::MainFunctionType { + "consider using `()`, or a `Result`".to_owned() + } else { + format!( + "{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref.print_only_trait_path(), + trait_ref.self_ty(), + ) + }; + + if self.suggest_add_reference_to_arg( + &obligation, + &mut err, + &trait_ref, + points_at_arg, + have_alt_message, + ) { + self.note_obligation_cause(&mut err, obligation); + err.emit(); + return; + } + if let Some(ref s) = label { + // If it has a custom `#[rustc_on_unimplemented]` + // error message, let's display it as the label! + err.span_label(span, s.as_str()); + err.help(&explanation); + } else { + err.span_label(span, explanation); + } + if let Some((msg, span)) = type_def { + err.span_label(span, &msg); + } + if let Some(ref s) = note { + // If it has a custom `#[rustc_on_unimplemented]` note, let's display it + err.note(s.as_str()); + } + if let Some(ref s) = enclosing_scope { + let enclosing_scope_span = tcx.def_span( + tcx.hir() + .opt_local_def_id(obligation.cause.body_id) + .unwrap_or_else(|| { + tcx.hir().body_owner_def_id(hir::BodyId { + hir_id: obligation.cause.body_id, + }) + }), + ); + + err.span_label(enclosing_scope_span, s.as_str()); + } + + self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); + self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg); + self.suggest_remove_reference(&obligation, &mut err, &trait_ref); + self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); + self.note_version_mismatch(&mut err, &trait_ref); + if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { + err.emit(); + return; + } + + // Try to report a help message + if !trait_ref.has_infer_types() + && self.predicate_can_apply(obligation.param_env, trait_ref) + { + // If a where-clause may be useful, remind the + // user that they can add it. + // + // don't display an on-unimplemented note, as + // these notes will often be of the form + // "the type `T` can't be frobnicated" + // which is somewhat confusing. + self.suggest_restricting_param_bound( + &mut err, + &trait_ref, + obligation.cause.body_id, + ); + } else { + if !have_alt_message { + // Can't show anything else useful, try to find similar impls. + let impl_candidates = self.find_similar_impl_candidates(trait_ref); + self.report_similar_impl_candidates(impl_candidates, &mut err); + } + self.suggest_change_mut( + &obligation, + &mut err, + &trait_ref, + points_at_arg, + ); + } + + // If this error is due to `!: Trait` not implemented but `(): Trait` is + // implemented, and fallback has occurred, then it could be due to a + // variable that used to fallback to `()` now falling back to `!`. Issue a + // note informing about the change in behaviour. + if trait_predicate.skip_binder().self_ty().is_never() + && fallback_has_occurred + { + let predicate = trait_predicate.map_bound(|mut trait_pred| { + trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( + self.tcx.mk_unit(), + &trait_pred.trait_ref.substs[1..], + ); + trait_pred + }); + let unit_obligation = Obligation { + predicate: ty::Predicate::Trait(predicate), + ..obligation.clone() + }; + if self.predicate_may_hold(&unit_obligation) { + err.note( + "the trait is implemented for `()`. \ + Possibly this error has been caused by changes to \ + Rust's type-inference algorithm \ + (see: https://github.com/rust-lang/rust/issues/48950 \ + for more info). Consider whether you meant to use the \ + type `()` here instead.", + ); + } + } + + err + } + + ty::Predicate::Subtype(ref predicate) => { + // Errors for Subtype predicates show up as + // `FulfillmentErrorCode::CodeSubtypeError`, + // not selection error. + span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate) + } + + ty::Predicate::RegionOutlives(ref predicate) => { + let predicate = self.resolve_vars_if_possible(predicate); + let err = self + .region_outlives_predicate(&obligation.cause, &predicate) + .err() + .unwrap(); + struct_span_err!( + self.tcx.sess, + span, + E0279, + "the requirement `{}` is not satisfied (`{}`)", + predicate, + err, + ) + } + + ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + struct_span_err!( + self.tcx.sess, + span, + E0280, + "the requirement `{}` is not satisfied", + predicate + ) + } + + ty::Predicate::ObjectSafe(trait_def_id) => { + let violations = object_safety_violations(self.tcx, trait_def_id); + report_object_safety_error(self.tcx, span, trait_def_id, violations) + } + + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); + let closure_span = self + .tcx + .sess + .source_map() + .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap()); + let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap(); + let mut err = struct_span_err!( + self.tcx.sess, + closure_span, + E0525, + "expected a closure that implements the `{}` trait, \ + but this closure only implements `{}`", + kind, + found_kind + ); + + err.span_label( + closure_span, + format!("this closure implements `{}`, not `{}`", found_kind, kind), + ); + err.span_label( + obligation.cause.span, + format!("the requirement to implement `{}` derives from here", kind), + ); + + // Additional context information explaining why the closure only implements + // a particular trait. + if let Some(tables) = self.in_progress_tables { + let tables = tables.borrow(); + match (found_kind, tables.closure_kind_origins().get(hir_id)) { + (ty::ClosureKind::FnOnce, Some((span, name))) => { + err.span_label( + *span, + format!( + "closure is `FnOnce` because it moves the \ + variable `{}` out of its environment", + name + ), + ); + } + (ty::ClosureKind::FnMut, Some((span, name))) => { + err.span_label( + *span, + format!( + "closure is `FnMut` because it mutates the \ + variable `{}` here", + name + ), + ); + } + _ => {} + } + } + + err.emit(); + return; + } + + ty::Predicate::WellFormed(ty) => { + if !self.tcx.sess.opts.debugging_opts.chalk { + // WF predicates cannot themselves make + // errors. They can only block due to + // ambiguity; otherwise, they always + // degenerate into other obligations + // (which may fail). + span_bug!(span, "WF predicate not satisfied for {:?}", ty); + } else { + // FIXME: we'll need a better message which takes into account + // which bounds actually failed to hold. + self.tcx.sess.struct_span_err( + span, + &format!("the type `{}` is not well-formed (chalk)", ty), + ) + } + } + + ty::Predicate::ConstEvaluatable(..) => { + // Errors for `ConstEvaluatable` predicates show up as + // `SelectionError::ConstEvalFailure`, + // not `Unimplemented`. + span_bug!( + span, + "const-evaluatable requirement gave wrong error: `{:?}`", + obligation + ) + } + } + } + + OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => { + let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref); + let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref); + + if expected_trait_ref.self_ty().references_error() { + return; + } + + let found_trait_ty = found_trait_ref.self_ty(); + + let found_did = match found_trait_ty.kind { + ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), + ty::Adt(def, _) => Some(def.did), + _ => None, + }; + + let found_span = found_did + .and_then(|did| self.tcx.hir().span_if_local(did)) + .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def + + if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { + // We check closures twice, with obligations flowing in different directions, + // but we want to complain about them only once. + return; + } + + self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); + + let found = match found_trait_ref.skip_binder().substs.type_at(1).kind { + ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], + _ => vec![ArgKind::empty()], + }; + + let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); + let expected = match expected_ty.kind { + ty::Tuple(ref tys) => tys + .iter() + .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))) + .collect(), + _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], + }; + + if found.len() == expected.len() { + self.report_closure_arg_mismatch( + span, + found_span, + found_trait_ref, + expected_trait_ref, + ) + } else { + let (closure_span, found) = found_did + .and_then(|did| self.tcx.hir().get_if_local(did)) + .map(|node| { + let (found_span, found) = self.get_fn_like_arguments(node); + (Some(found_span), found) + }) + .unwrap_or((found_span, found)); + + self.report_arg_count_mismatch( + span, + closure_span, + expected, + found, + found_trait_ty.is_closure(), + ) + } + } + + TraitNotObjectSafe(did) => { + let violations = object_safety_violations(self.tcx, did); + report_object_safety_error(self.tcx, span, did, violations) + } + + // already reported in the query + ConstEvalFailure(err) => { + if let ErrorHandled::TooGeneric = err { + // Silence this error, as it can be produced during intermediate steps + // when a constant is not yet able to be evaluated (but will be later). + return; + } + self.tcx.sess.delay_span_bug( + span, + &format!("constant in type had an ignored error: {:?}", err), + ); + return; + } + + Overflow => { + bug!("overflow should be handled before the `report_selection_error` path"); + } + }; + + self.note_obligation_cause(&mut err, obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); + + err.emit(); + } + + /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait + /// with the same path as `trait_ref`, a help message about + /// a probable version mismatch is added to `err` + fn note_version_mismatch( + &self, + err: &mut DiagnosticBuilder<'_>, + trait_ref: &ty::PolyTraitRef<'tcx>, + ) { + let get_trait_impl = |trait_def_id| { + let mut trait_impl = None; + self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| { + if trait_impl.is_none() { + trait_impl = Some(impl_def_id); + } + }); + trait_impl + }; + let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); + let all_traits = self.tcx.all_traits(LOCAL_CRATE); + let traits_with_same_path: std::collections::BTreeSet<_> = all_traits + .iter() + .filter(|trait_def_id| **trait_def_id != trait_ref.def_id()) + .filter(|trait_def_id| self.tcx.def_path_str(**trait_def_id) == required_trait_path) + .collect(); + for trait_with_same_path in traits_with_same_path { + if let Some(impl_def_id) = get_trait_impl(*trait_with_same_path) { + let impl_span = self.tcx.def_span(impl_def_id); + err.span_help(impl_span, "trait impl with same name found"); + let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); + let crate_msg = format!( + "perhaps two different versions of crate `{}` are being used?", + trait_crate + ); + err.note(&crate_msg); + } + } + } + + fn mk_obligation_for_def_id( + &self, + def_id: DefId, + output_ty: Ty<'tcx>, + cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> PredicateObligation<'tcx> { + let new_trait_ref = + ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; + Obligation::new(cause, param_env, new_trait_ref.to_predicate()) + } +} + +pub fn recursive_type_with_infinite_size_error( + tcx: TyCtxt<'tcx>, + type_def_id: DefId, +) -> DiagnosticBuilder<'tcx> { + assert!(type_def_id.is_local()); + let span = tcx.hir().span_if_local(type_def_id).unwrap(); + let span = tcx.sess.source_map().def_span(span); + let mut err = struct_span_err!( + tcx.sess, + span, + E0072, + "recursive type `{}` has infinite size", + tcx.def_path_str(type_def_id) + ); + err.span_label(span, "recursive type has infinite size"); + err.help(&format!( + "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ + at some point to make `{}` representable", + tcx.def_path_str(type_def_id) + )); + err +} + +pub fn report_object_safety_error( + tcx: TyCtxt<'tcx>, + span: Span, + trait_def_id: DefId, + violations: Vec, +) -> DiagnosticBuilder<'tcx> { + let trait_str = tcx.def_path_str(trait_def_id); + let span = tcx.sess.source_map().def_span(span); + let mut err = struct_span_err!( + tcx.sess, + span, + E0038, + "the trait `{}` cannot be made into an object", + trait_str + ); + err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); + + let mut reported_violations = FxHashSet::default(); + for violation in violations { + if reported_violations.insert(violation.clone()) { + match violation.span() { + Some(span) => err.span_label(span, violation.error_msg()), + None => err.note(&violation.error_msg()), + }; + } + } + + if tcx.sess.trait_methods_not_found.borrow().contains(&span) { + // Avoid emitting error caused by non-existing method (#58734) + err.cancel(); + } + + err +} + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + fn maybe_report_ambiguity( + &self, + obligation: &PredicateObligation<'tcx>, + body_id: Option, + ) { + // Unable to successfully determine, probably means + // insufficient type information, but could mean + // ambiguous impls. The latter *ought* to be a + // coherence violation, so we don't report it here. + + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + let span = obligation.cause.span; + + debug!( + "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", + predicate, obligation, body_id, obligation.cause.code, + ); + + // Ambiguity errors are often caused as fallout from earlier + // errors. So just ignore them if this infcx is tainted. + if self.is_tainted_by_errors() { + return; + } + + let mut err = match predicate { + ty::Predicate::Trait(ref data) => { + let trait_ref = data.to_poly_trait_ref(); + let self_ty = trait_ref.self_ty(); + debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); + + if predicate.references_error() { + return; + } + // Typically, this ambiguity should only happen if + // there are unresolved type inference variables + // (otherwise it would suggest a coherence + // failure). But given #21974 that is not necessarily + // the case -- we can have multiple where clauses that + // are only distinguished by a region, which results + // in an ambiguity even when all types are fully + // known, since we don't dispatch based on region + // relationships. + + // This is kind of a hack: it frequently happens that some earlier + // error prevents types from being fully inferred, and then we get + // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we + // could just skip over all checks where the self-ty is an + // inference variable, but I was afraid that there might be an + // inference variable created, registered as an obligation, and + // then never forced by writeback, and hence by skipping here we'd + // be ignoring the fact that we don't KNOW the type works + // out. Though even that would probably be harmless, given that + // we're only talking about builtin traits, which are known to be + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and dont add the obligations to + // begin with in those cases. + if self + .tcx + .lang_items() + .sized_trait() + .map_or(false, |sized_id| sized_id == trait_ref.def_id()) + { + self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); + return; + } + let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); + err.note(&format!("cannot resolve `{}`", predicate)); + if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { + self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); + } else if let ( + Ok(ref snippet), + ObligationCauseCode::BindingObligation(ref def_id, _), + ) = + (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) + { + let generics = self.tcx.generics_of(*def_id); + if !generics.params.is_empty() && !snippet.ends_with('>') { + // FIXME: To avoid spurious suggestions in functions where type arguments + // where already supplied, we check the snippet to make sure it doesn't + // end with a turbofish. Ideally we would have access to a `PathSegment` + // instead. Otherwise we would produce the following output: + // + // error[E0283]: type annotations needed + // --> $DIR/issue-54954.rs:3:24 + // | + // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); + // | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + // | | + // | cannot infer type + // | help: consider specifying the type argument + // | in the function call: + // | `Tt::const_val::<[i8; 123]>::` + // ... + // LL | const fn const_val() -> usize { + // | --------- - required by this bound in `Tt::const_val` + // | + // = note: cannot resolve `_: Tt` + + err.span_suggestion( + span, + &format!( + "consider specifying the type argument{} in the function call", + if generics.params.len() > 1 { "s" } else { "" }, + ), + format!( + "{}::<{}>", + snippet, + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") + ), + Applicability::HasPlaceholders, + ); + } + } + err + } + + ty::Predicate::WellFormed(ty) => { + // Same hacky approach as above to avoid deluging user + // with error messages. + if ty.references_error() || self.tcx.sess.has_errors() { + return; + } + self.need_type_info_err(body_id, span, ty, ErrorCode::E0282) + } + + ty::Predicate::Subtype(ref data) => { + if data.references_error() || self.tcx.sess.has_errors() { + // no need to overload user in such cases + return; + } + let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); + // both must be type variables, or the other would've been instantiated + assert!(a.is_ty_var() && b.is_ty_var()); + self.need_type_info_err(body_id, span, a, ErrorCode::E0282) + } + ty::Predicate::Projection(ref data) => { + let trait_ref = data.to_poly_trait_ref(self.tcx); + let self_ty = trait_ref.self_ty(); + if predicate.references_error() { + return; + } + let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284); + err.note(&format!("cannot resolve `{}`", predicate)); + err + } + + _ => { + if self.tcx.sess.has_errors() { + return; + } + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0284, + "type annotations needed: cannot resolve `{}`", + predicate, + ); + err.span_label(span, &format!("cannot resolve `{}`", predicate)); + err + } + }; + self.note_obligation_cause(&mut err, obligation); + err.emit(); + } + + /// Returns `true` if the trait predicate may apply for *some* assignment + /// to the type parameters. + fn predicate_can_apply( + &self, + param_env: ty::ParamEnv<'tcx>, + pred: ty::PolyTraitRef<'tcx>, + ) -> bool { + struct ParamToVarFolder<'a, 'tcx> { + infcx: &'a InferCtxt<'a, 'tcx>, + var_map: FxHashMap, Ty<'tcx>>, + } + + impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Param(ty::ParamTy { name, .. }) = ty.kind { + let infcx = self.infcx; + self.var_map.entry(ty).or_insert_with(|| { + infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), + span: DUMMY_SP, + }) + }) + } else { + ty.super_fold_with(self) + } + } + } + + self.probe(|_| { + let mut selcx = SelectionContext::new(self); + + let cleaned_pred = + pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); + + let cleaned_pred = super::project::normalize( + &mut selcx, + param_env, + ObligationCause::dummy(), + &cleaned_pred, + ) + .value; + + let obligation = + Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); + + self.predicate_may_hold(&obligation) + }) + } + + fn note_obligation_cause( + &self, + err: &mut DiagnosticBuilder<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + // First, attempt to add note to this error with an async-await-specific + // message, and fall back to regular note otherwise. + if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { + self.note_obligation_cause_code( + err, + &obligation.predicate, + &obligation.cause.code, + &mut vec![], + ); + } + } + + fn is_recursive_obligation( + &self, + obligated_types: &mut Vec<&ty::TyS<'tcx>>, + cause_code: &ObligationCauseCode<'tcx>, + ) -> bool { + if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code { + let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); + + if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) { + return true; + } + } + false + } +} + +/// Summarizes information +#[derive(Clone)] +pub enum ArgKind { + /// An argument of non-tuple type. Parameters are (name, ty) + Arg(String, String), + + /// An argument of tuple type. For a "found" argument, the span is + /// the locationo in the source of the pattern. For a "expected" + /// argument, it will be None. The vector is a list of (name, ty) + /// strings for the components of the tuple. + Tuple(Option, Vec<(String, String)>), +} + +impl ArgKind { + fn empty() -> ArgKind { + ArgKind::Arg("_".to_owned(), "_".to_owned()) + } + + /// Creates an `ArgKind` from the expected type of an + /// argument. It has no name (`_`) and an optional source span. + pub fn from_expected_ty(t: Ty<'_>, span: Option) -> ArgKind { + match t.kind { + ty::Tuple(ref tys) => ArgKind::Tuple( + span, + tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::>(), + ), + _ => ArgKind::Arg("_".to_owned(), t.to_string()), + } + } +} + +/// Suggest restricting a type param with a new bound. +pub fn suggest_constraining_type_param( + generics: &hir::Generics<'_>, + err: &mut DiagnosticBuilder<'_>, + param_name: &str, + constraint: &str, + source_map: &SourceMap, + span: Span, +) -> bool { + let restrict_msg = "consider further restricting this bound"; + if let Some(param) = + generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() + { + if param_name.starts_with("impl ") { + // `impl Trait` in argument: + // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` + err.span_suggestion( + param.span, + restrict_msg, + // `impl CurrentTrait + MissingTrait` + format!("{} + {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() { + // If there are no bounds whatsoever, suggest adding a constraint + // to the type parameter: + // `fn foo(t: T) {}` → `fn foo(t: T) {}` + err.span_suggestion( + param.span, + "consider restricting this bound", + format!("{}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else if !generics.where_clause.predicates.is_empty() { + // There is a `where` clause, so suggest expanding it: + // `fn foo(t: T) where T: Debug {}` → + // `fn foo(t: T) where T: Debug, T: Trait {}` + err.span_suggestion( + generics.where_clause.span().unwrap().shrink_to_hi(), + &format!("consider further restricting type parameter `{}`", param_name), + format!(", {}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else { + // If there is no `where` clause lean towards constraining to the + // type parameter: + // `fn foo(t: T, x: X) {}` → `fn foo(t: T) {}` + // `fn foo(t: T) {}` → `fn foo(t: T) {}` + let sp = param.span.with_hi(span.hi()); + let span = source_map.span_through_char(sp, ':'); + if sp != param.span && sp != span { + // Only suggest if we have high certainty that the span + // covers the colon in `foo`. + err.span_suggestion( + span, + restrict_msg, + format!("{}: {} + ", param_name, constraint), + Applicability::MachineApplicable, + ); + } else { + err.span_label( + param.span, + &format!("consider adding a `where {}: {}` bound", param_name, constraint), + ); + } + } + return true; + } + false +} + +struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + +impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } +} diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs new file mode 100644 index 0000000000000..9f3fc91548b21 --- /dev/null +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -0,0 +1,199 @@ +use super::{ + ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, PredicateObligation, +}; +use crate::infer::InferCtxt; +use crate::ty::subst::Subst; +use crate::ty::{self, GenericParamDefKind}; +use rustc_hir as hir; +use rustc_hir::def_id::DefId; +use rustc_span::symbol::sym; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + fn impl_similar_to( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> Option { + let tcx = self.tcx; + let param_env = obligation.param_env; + let trait_ref = tcx.erase_late_bound_regions(&trait_ref); + let trait_self_ty = trait_ref.self_ty(); + + let mut self_match_impls = vec![]; + let mut fuzzy_match_impls = vec![]; + + self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { + let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); + let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); + + let impl_self_ty = impl_trait_ref.self_ty(); + + if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { + self_match_impls.push(def_id); + + if trait_ref + .substs + .types() + .skip(1) + .zip(impl_trait_ref.substs.types().skip(1)) + .all(|(u, v)| self.fuzzy_match_tys(u, v)) + { + fuzzy_match_impls.push(def_id); + } + } + }); + + let impl_def_id = if self_match_impls.len() == 1 { + self_match_impls[0] + } else if fuzzy_match_impls.len() == 1 { + fuzzy_match_impls[0] + } else { + return None; + }; + + tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented).then_some(impl_def_id) + } + + /// Used to set on_unimplemented's `ItemContext` + /// to be the enclosing (async) block/function/closure + fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { + let hir = &self.tcx.hir(); + let node = hir.find(hir_id)?; + if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async function" + } else { + "a function" + }) + }) + } else if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| { + Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) + }) + } else if let hir::Node::Expr(hir::Expr { .. }) = &node { + let parent_hid = hir.get_parent_node(hir_id); + if parent_hid != hir_id { + return self.describe_enclosure(parent_hid); + } else { + None + } + } else { + None + } + } + + crate fn on_unimplemented_note( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> OnUnimplementedNote { + let def_id = + self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id()); + let trait_ref = *trait_ref.skip_binder(); + + let mut flags = vec![]; + flags.push(( + sym::item_context, + self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()), + )); + + match obligation.cause.code { + ObligationCauseCode::BuiltinDerivedObligation(..) + | ObligationCauseCode::ImplDerivedObligation(..) => {} + _ => { + // this is a "direct", user-specified, rather than derived, + // obligation. + flags.push((sym::direct, None)); + } + } + + if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { + // FIXME: maybe also have some way of handling methods + // from other traits? That would require name resolution, + // which we might want to be some sort of hygienic. + // + // Currently I'm leaving it for what I need for `try`. + if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { + let method = self.tcx.item_name(item); + flags.push((sym::from_method, None)); + flags.push((sym::from_method, Some(method.to_string()))); + } + } + if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { + flags.push((sym::parent_trait, Some(t))); + } + + if let Some(k) = obligation.cause.span.desugaring_kind() { + flags.push((sym::from_desugaring, None)); + flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); + } + let generics = self.tcx.generics_of(def_id); + let self_ty = trait_ref.self_ty(); + // This is also included through the generics list as `Self`, + // but the parser won't allow you to use it + flags.push((sym::_Self, Some(self_ty.to_string()))); + if let Some(def) = self_ty.ty_adt_def() { + // We also want to be able to select self's original + // signature with no type arguments resolved + flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); + } + + for param in generics.params.iter() { + let value = match param.kind { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + trait_ref.substs[param.index as usize].to_string() + } + GenericParamDefKind::Lifetime => continue, + }; + let name = param.name; + flags.push((name, Some(value))); + } + + if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { + flags.push((sym::crate_local, None)); + } + + // Allow targeting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push((sym::_Self, Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.kind { + flags.push((sym::_Self, Some("[]".to_owned()))); + flags.push((sym::_Self, Some(format!("[{}]", aty)))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the array's type's original + // signature with no type arguments resolved + flags.push(( + sym::_Self, + Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), + )); + let tcx = self.tcx; + if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) { + flags.push(( + sym::_Self, + Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), + )); + } else { + flags.push(( + sym::_Self, + Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), + )); + } + } + } + + if let Ok(Some(command)) = + OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) + { + command.evaluate(self.tcx, trait_ref, &flags[..]) + } else { + OnUnimplementedNote::default() + } + } +} diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting/suggestions.rs similarity index 52% rename from src/librustc/traits/error_reporting.rs rename to src/librustc/traits/error_reporting/suggestions.rs index 77a73aba45484..389edfa071794 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -1,1178 +1,28 @@ -// ignore-tidy-filelength use super::{ - ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, - MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, - ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, - OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, - TraitNotObjectSafe, + ArgKind, EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, + PredicateObligation, }; -use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::infer::{self, InferCtxt}; -use crate::mir::interpret::ErrorHandled; -use crate::session::DiagnosticMessageId; -use crate::traits::object_safety_violations; -use crate::ty::error::ExpectedFound; -use crate::ty::fast_reject; -use crate::ty::fold::TypeFolder; -use crate::ty::subst::Subst; -use crate::ty::GenericParamDefKind; -use crate::ty::SubtypePredicate; +use crate::infer::InferCtxt; use crate::ty::TypeckTables; -use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, }; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym}; -use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; +use rustc_span::{MultiSpan, Span, DUMMY_SP}; use std::fmt; -use syntax::ast; use rustc_error_codes::*; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub fn report_fulfillment_errors( - &self, - errors: &[FulfillmentError<'tcx>], - body_id: Option, - fallback_has_occurred: bool, - ) { - #[derive(Debug)] - struct ErrorDescriptor<'tcx> { - predicate: ty::Predicate<'tcx>, - index: Option, // None if this is an old error - } - - let mut error_map: FxHashMap<_, Vec<_>> = self - .reported_trait_errors - .borrow() - .iter() - .map(|(&span, predicates)| { - ( - span, - predicates - .iter() - .map(|predicate| ErrorDescriptor { - predicate: predicate.clone(), - index: None, - }) - .collect(), - ) - }) - .collect(); - - for (index, error) in errors.iter().enumerate() { - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } - - error_map.entry(span).or_default().push(ErrorDescriptor { - predicate: error.obligation.predicate.clone(), - index: Some(index), - }); - - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_default() - .push(error.obligation.predicate.clone()); - } - - // We do this in 2 passes because we want to display errors in order, though - // maybe it *is* better to sort errors by span or something. - let mut is_suppressed = vec![false; errors.len()]; - for (_, error_set) in error_map.iter() { - // We want to suppress "duplicate" errors with the same span. - for error in error_set { - if let Some(index) = error.index { - // Suppress errors that are either: - // 1) strictly implied by another error. - // 2) implied by an error with a smaller index. - for error2 in error_set { - if error2.index.map_or(false, |index2| is_suppressed[index2]) { - // Avoid errors being suppressed by already-suppressed - // errors, to prevent all errors from being suppressed - // at once. - continue; - } - - if self.error_implies(&error2.predicate, &error.predicate) - && !(error2.index >= error.index - && self.error_implies(&error.predicate, &error2.predicate)) - { - info!("skipping {:?} (implied by {:?})", error, error2); - is_suppressed[index] = true; - break; - } - } - } - } - } - - for (error, suppressed) in errors.iter().zip(is_suppressed) { - if !suppressed { - self.report_fulfillment_error(error, body_id, fallback_has_occurred); - } - } - } - - // returns if `cond` not occurring implies that `error` does not occur - i.e., that - // `error` occurring implies that `cond` occurs. - fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool { - if cond == error { - return true; - } - - let (cond, error) = match (cond, error) { - (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), - _ => { - // FIXME: make this work in other cases too. - return false; - } - }; - - for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { - if let ty::Predicate::Trait(implication) = implication { - let error = error.to_poly_trait_ref(); - let implication = implication.to_poly_trait_ref(); - // FIXME: I'm just not taking associated types at all here. - // Eventually I'll need to implement param-env-aware - // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. - let param_env = ty::ParamEnv::empty(); - if self.can_sub(param_env, error, implication).is_ok() { - debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); - return true; - } - } - } - - false - } - - fn report_fulfillment_error( - &self, - error: &FulfillmentError<'tcx>, - body_id: Option, - fallback_has_occurred: bool, - ) { - debug!("report_fulfillment_error({:?})", error); - match error.code { - FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { - self.report_selection_error( - &error.obligation, - selection_error, - fallback_has_occurred, - error.points_at_arg_span, - ); - } - FulfillmentErrorCode::CodeProjectionError(ref e) => { - self.report_projection_error(&error.obligation, e); - } - FulfillmentErrorCode::CodeAmbiguity => { - self.maybe_report_ambiguity(&error.obligation, body_id); - } - FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { - self.report_mismatched_types( - &error.obligation.cause, - expected_found.expected, - expected_found.found, - err.clone(), - ) - .emit(); - } - } - } - - fn report_projection_error( - &self, - obligation: &PredicateObligation<'tcx>, - error: &MismatchedProjectionTypes<'tcx>, - ) { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - - if predicate.references_error() { - return; - } - - self.probe(|_| { - let err_buf; - let mut err = &error.err; - let mut values = None; - - // try to find the mismatched types to report the error with. - // - // this can fail if the problem was higher-ranked, in which - // cause I have no idea for a good error message. - if let ty::Predicate::Projection(ref data) = predicate { - let mut selcx = SelectionContext::new(self); - let (data, _) = self.replace_bound_vars_with_fresh_vars( - obligation.cause.span, - infer::LateBoundRegionConversionTime::HigherRankedType, - data, - ); - let mut obligations = vec![]; - let normalized_ty = super::normalize_projection_type( - &mut selcx, - obligation.param_env, - data.projection_ty, - obligation.cause.clone(), - 0, - &mut obligations, - ); - - debug!( - "report_projection_error obligation.cause={:?} obligation.param_env={:?}", - obligation.cause, obligation.param_env - ); - - debug!( - "report_projection_error normalized_ty={:?} data.ty={:?}", - normalized_ty, data.ty - ); - - let is_normalized_ty_expected = match &obligation.cause.code { - ObligationCauseCode::ItemObligation(_) - | ObligationCauseCode::BindingObligation(_, _) - | ObligationCauseCode::ObjectCastObligation(_) => false, - _ => true, - }; - - if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( - is_normalized_ty_expected, - normalized_ty, - data.ty, - ) { - values = Some(infer::ValuePairs::Types(ExpectedFound::new( - is_normalized_ty_expected, - normalized_ty, - data.ty, - ))); - - err_buf = error; - err = &err_buf; - } - } - - let msg = format!("type mismatch resolving `{}`", predicate); - let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); - let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - let mut diag = struct_span_err!( - self.tcx.sess, - obligation.cause.span, - E0271, - "type mismatch resolving `{}`", - predicate - ); - self.note_type_err(&mut diag, &obligation.cause, None, values, err); - self.note_obligation_cause(&mut diag, obligation); - diag.emit(); - } - }); - } - - fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - /// returns the fuzzy category of a given type, or None - /// if the type can be equated to any type. - fn type_category(t: Ty<'_>) -> Option { - match t.kind { - ty::Bool => Some(0), - ty::Char => Some(1), - ty::Str => Some(2), - ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3), - ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4), - ty::Ref(..) | ty::RawPtr(..) => Some(5), - ty::Array(..) | ty::Slice(..) => Some(6), - ty::FnDef(..) | ty::FnPtr(..) => Some(7), - ty::Dynamic(..) => Some(8), - ty::Closure(..) => Some(9), - ty::Tuple(..) => Some(10), - ty::Projection(..) => Some(11), - ty::Param(..) => Some(12), - ty::Opaque(..) => Some(13), - ty::Never => Some(14), - ty::Adt(adt, ..) => match adt.adt_kind() { - AdtKind::Struct => Some(15), - AdtKind::Union => Some(16), - AdtKind::Enum => Some(17), - }, - ty::Generator(..) => Some(18), - ty::Foreign(..) => Some(19), - ty::GeneratorWitness(..) => Some(20), - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, - ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - } - } - - match (type_category(a), type_category(b)) { - (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) { - (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b, - _ => cat_a == cat_b, - }, - // infer and error can be equated to all types - _ => true, - } - } - - fn impl_similar_to( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>, - ) -> Option { - let tcx = self.tcx; - let param_env = obligation.param_env; - let trait_ref = tcx.erase_late_bound_regions(&trait_ref); - let trait_self_ty = trait_ref.self_ty(); - - let mut self_match_impls = vec![]; - let mut fuzzy_match_impls = vec![]; - - self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { - let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); - let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); - - let impl_self_ty = impl_trait_ref.self_ty(); - - if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { - self_match_impls.push(def_id); - - if trait_ref - .substs - .types() - .skip(1) - .zip(impl_trait_ref.substs.types().skip(1)) - .all(|(u, v)| self.fuzzy_match_tys(u, v)) - { - fuzzy_match_impls.push(def_id); - } - } - }); - - let impl_def_id = if self_match_impls.len() == 1 { - self_match_impls[0] - } else if fuzzy_match_impls.len() == 1 { - fuzzy_match_impls[0] - } else { - return None; - }; - - tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented).then_some(impl_def_id) - } - - fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> { - self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind { - hir::GeneratorKind::Gen => "a generator", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", - }) - } - - /// Used to set on_unimplemented's `ItemContext` - /// to be the enclosing (async) block/function/closure - fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { - let hir = &self.tcx.hir(); - let node = hir.find(hir_id)?; - if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { - self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async function" - } else { - "a function" - }) - }) - } else if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { - Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) - }) - } else if let hir::Node::Expr(hir::Expr { .. }) = &node { - let parent_hid = hir.get_parent_node(hir_id); - if parent_hid != hir_id { - return self.describe_enclosure(parent_hid); - } else { - None - } - } else { - None - } - } - - fn on_unimplemented_note( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>, - ) -> OnUnimplementedNote { - let def_id = - self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id()); - let trait_ref = *trait_ref.skip_binder(); - - let mut flags = vec![]; - flags.push(( - sym::item_context, - self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()), - )); - - match obligation.cause.code { - ObligationCauseCode::BuiltinDerivedObligation(..) - | ObligationCauseCode::ImplDerivedObligation(..) => {} - _ => { - // this is a "direct", user-specified, rather than derived, - // obligation. - flags.push((sym::direct, None)); - } - } - - if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { - // FIXME: maybe also have some way of handling methods - // from other traits? That would require name resolution, - // which we might want to be some sort of hygienic. - // - // Currently I'm leaving it for what I need for `try`. - if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { - let method = self.tcx.item_name(item); - flags.push((sym::from_method, None)); - flags.push((sym::from_method, Some(method.to_string()))); - } - } - if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { - flags.push((sym::parent_trait, Some(t))); - } - - if let Some(k) = obligation.cause.span.desugaring_kind() { - flags.push((sym::from_desugaring, None)); - flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); - } - let generics = self.tcx.generics_of(def_id); - let self_ty = trait_ref.self_ty(); - // This is also included through the generics list as `Self`, - // but the parser won't allow you to use it - flags.push((sym::_Self, Some(self_ty.to_string()))); - if let Some(def) = self_ty.ty_adt_def() { - // We also want to be able to select self's original - // signature with no type arguments resolved - flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); - } - - for param in generics.params.iter() { - let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { - trait_ref.substs[param.index as usize].to_string() - } - GenericParamDefKind::Lifetime => continue, - }; - let name = param.name; - flags.push((name, Some(value))); - } - - if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { - flags.push((sym::crate_local, None)); - } - - // Allow targeting all integers using `{integral}`, even if the exact type was resolved - if self_ty.is_integral() { - flags.push((sym::_Self, Some("{integral}".to_owned()))); - } - - if let ty::Array(aty, len) = self_ty.kind { - flags.push((sym::_Self, Some("[]".to_owned()))); - flags.push((sym::_Self, Some(format!("[{}]", aty)))); - if let Some(def) = aty.ty_adt_def() { - // We also want to be able to select the array's type's original - // signature with no type arguments resolved - flags.push(( - sym::_Self, - Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), - )); - let tcx = self.tcx; - if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) { - flags.push(( - sym::_Self, - Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), - )); - } else { - flags.push(( - sym::_Self, - Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), - )); - } - } - } - - if let Ok(Some(command)) = - OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) - { - command.evaluate(self.tcx, trait_ref, &flags[..]) - } else { - OnUnimplementedNote::default() - } - } - - fn find_similar_impl_candidates( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Vec> { - let simp = fast_reject::simplify_type(self.tcx, trait_ref.skip_binder().self_ty(), true); - let all_impls = self.tcx.all_impls(trait_ref.def_id()); - - match simp { - Some(simp) => all_impls - .iter() - .filter_map(|&def_id| { - let imp = self.tcx.impl_trait_ref(def_id).unwrap(); - let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); - if let Some(imp_simp) = imp_simp { - if simp != imp_simp { - return None; - } - } - - Some(imp) - }) - .collect(), - None => { - all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() - } - } - } - - fn report_similar_impl_candidates( - &self, - impl_candidates: Vec>, - err: &mut DiagnosticBuilder<'_>, - ) { - if impl_candidates.is_empty() { - return; - } - - let len = impl_candidates.len(); - let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 }; - - let normalize = |candidate| { - self.tcx.infer_ctxt().enter(|ref infcx| { - let normalized = infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(candidate) - .ok(); - match normalized { - Some(normalized) => format!("\n {:?}", normalized.value), - None => format!("\n {:?}", candidate), - } - }) - }; - - // Sort impl candidates so that ordering is consistent for UI tests. - let mut normalized_impl_candidates = - impl_candidates.iter().map(normalize).collect::>(); - - // Sort before taking the `..end` range, - // because the ordering of `impl_candidates` may not be deterministic: - // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 - normalized_impl_candidates.sort(); - - err.help(&format!( - "the following implementations were found:{}{}", - normalized_impl_candidates[..end].join(""), - if len > 5 { format!("\nand {} others", len - 4) } else { String::new() } - )); - } - - /// Reports that an overflow has occurred and halts compilation. We - /// halt compilation unconditionally because it is important that - /// overflows never be masked -- they basically represent computations - /// whose result could not be truly determined and thus we can't say - /// if the program type checks or not -- and they are unusual - /// occurrences in any case. - pub fn report_overflow_error( - &self, - obligation: &Obligation<'tcx, T>, - suggest_increasing_limit: bool, - ) -> ! - where - T: fmt::Display + TypeFoldable<'tcx>, - { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - let mut err = struct_span_err!( - self.tcx.sess, - obligation.cause.span, - E0275, - "overflow evaluating the requirement `{}`", - predicate - ); - - if suggest_increasing_limit { - self.suggest_new_overflow_limit(&mut err); - } - - self.note_obligation_cause_code( - &mut err, - &obligation.predicate, - &obligation.cause.code, - &mut vec![], - ); - - err.emit(); - self.tcx.sess.abort_if_errors(); - bug!(); - } - - /// Reports that a cycle was detected which led to overflow and halts - /// compilation. This is equivalent to `report_overflow_error` except - /// that we can give a more helpful error message (and, in particular, - /// we do not suggest increasing the overflow limit, which is not - /// going to help). - pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { - let cycle = self.resolve_vars_if_possible(&cycle.to_owned()); - assert!(cycle.len() > 0); - - debug!("report_overflow_error_cycle: cycle={:?}", cycle); - - self.report_overflow_error(&cycle[0], false); - } - - pub fn report_extra_impl_obligation( - &self, - error_span: Span, - item_name: ast::Name, - _impl_item_def_id: DefId, - trait_item_def_id: DefId, - requirement: &dyn fmt::Display, - ) -> DiagnosticBuilder<'tcx> { - let msg = "impl has stricter requirements than trait"; - let sp = self.tcx.sess.source_map().def_span(error_span); - - let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg); - - if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) { - let span = self.tcx.sess.source_map().def_span(trait_item_span); - err.span_label(span, format!("definition of `{}` from trait", item_name)); - } - - err.span_label(sp, format!("impl has extra requirement {}", requirement)); - - err - } - - /// Gets the parent trait chain start - fn get_parent_trait_ref( - &self, - code: &ObligationCauseCode<'tcx>, - ) -> Option<(String, Option)> { - match code { - &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { - let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); - match self.get_parent_trait_ref(&data.parent_code) { - Some(t) => Some(t), - None => { - let ty = parent_trait_ref.skip_binder().self_ty(); - let span = - TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id)); - Some((ty.to_string(), span)) - } - } - } - _ => None, - } - } - - pub fn report_selection_error( - &self, - obligation: &PredicateObligation<'tcx>, - error: &SelectionError<'tcx>, - fallback_has_occurred: bool, - points_at_arg: bool, - ) { - let tcx = self.tcx; - let span = obligation.cause.span; - - let mut err = match *error { - SelectionError::Unimplemented => { - if let ObligationCauseCode::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } - | ObligationCauseCode::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } = obligation.cause.code - { - self.report_extra_impl_obligation( - span, - item_name, - impl_item_def_id, - trait_item_def_id, - &format!("`{}`", obligation.predicate), - ) - .emit(); - return; - } - match obligation.predicate { - ty::Predicate::Trait(ref trait_predicate) => { - let trait_predicate = self.resolve_vars_if_possible(trait_predicate); - - if self.tcx.sess.has_errors() && trait_predicate.references_error() { - return; - } - let trait_ref = trait_predicate.to_poly_trait_ref(); - let (post_message, pre_message, type_def) = self - .get_parent_trait_ref(&obligation.cause.code) - .map(|(t, s)| { - ( - format!(" in `{}`", t), - format!("within `{}`, ", t), - s.map(|s| (format!("within this `{}`", t), s)), - ) - }) - .unwrap_or_default(); - - let OnUnimplementedNote { message, label, note, enclosing_scope } = - self.on_unimplemented_note(trait_ref, obligation); - let have_alt_message = message.is_some() || label.is_some(); - let is_try = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|s| &s == "?") - .unwrap_or(false); - let is_from = format!("{}", trait_ref.print_only_trait_path()) - .starts_with("std::convert::From<"); - let (message, note) = if is_try && is_from { - ( - Some(format!( - "`?` couldn't convert the error to `{}`", - trait_ref.self_ty(), - )), - Some( - "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" - .to_owned(), - ), - ) - } else { - (message, note) - }; - - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0277, - "{}", - message.unwrap_or_else(|| format!( - "the trait bound `{}` is not satisfied{}", - trait_ref.to_predicate(), - post_message, - )) - ); - - let explanation = - if obligation.cause.code == ObligationCauseCode::MainFunctionType { - "consider using `()`, or a `Result`".to_owned() - } else { - format!( - "{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref.print_only_trait_path(), - trait_ref.self_ty(), - ) - }; - - if self.suggest_add_reference_to_arg( - &obligation, - &mut err, - &trait_ref, - points_at_arg, - have_alt_message, - ) { - self.note_obligation_cause(&mut err, obligation); - err.emit(); - return; - } - if let Some(ref s) = label { - // If it has a custom `#[rustc_on_unimplemented]` - // error message, let's display it as the label! - err.span_label(span, s.as_str()); - err.help(&explanation); - } else { - err.span_label(span, explanation); - } - if let Some((msg, span)) = type_def { - err.span_label(span, &msg); - } - if let Some(ref s) = note { - // If it has a custom `#[rustc_on_unimplemented]` note, let's display it - err.note(s.as_str()); - } - if let Some(ref s) = enclosing_scope { - let enclosing_scope_span = tcx.def_span( - tcx.hir() - .opt_local_def_id(obligation.cause.body_id) - .unwrap_or_else(|| { - tcx.hir().body_owner_def_id(hir::BodyId { - hir_id: obligation.cause.body_id, - }) - }), - ); - - err.span_label(enclosing_scope_span, s.as_str()); - } - - self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); - self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg); - self.suggest_remove_reference(&obligation, &mut err, &trait_ref); - self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); - self.note_version_mismatch(&mut err, &trait_ref); - if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { - err.emit(); - return; - } - - // Try to report a help message - if !trait_ref.has_infer_types() - && self.predicate_can_apply(obligation.param_env, trait_ref) - { - // If a where-clause may be useful, remind the - // user that they can add it. - // - // don't display an on-unimplemented note, as - // these notes will often be of the form - // "the type `T` can't be frobnicated" - // which is somewhat confusing. - self.suggest_restricting_param_bound( - &mut err, - &trait_ref, - obligation.cause.body_id, - ); - } else { - if !have_alt_message { - // Can't show anything else useful, try to find similar impls. - let impl_candidates = self.find_similar_impl_candidates(trait_ref); - self.report_similar_impl_candidates(impl_candidates, &mut err); - } - self.suggest_change_mut( - &obligation, - &mut err, - &trait_ref, - points_at_arg, - ); - } - - // If this error is due to `!: Trait` not implemented but `(): Trait` is - // implemented, and fallback has occurred, then it could be due to a - // variable that used to fallback to `()` now falling back to `!`. Issue a - // note informing about the change in behaviour. - if trait_predicate.skip_binder().self_ty().is_never() - && fallback_has_occurred - { - let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( - self.tcx.mk_unit(), - &trait_pred.trait_ref.substs[1..], - ); - trait_pred - }); - let unit_obligation = Obligation { - predicate: ty::Predicate::Trait(predicate), - ..obligation.clone() - }; - if self.predicate_may_hold(&unit_obligation) { - err.note( - "the trait is implemented for `()`. \ - Possibly this error has been caused by changes to \ - Rust's type-inference algorithm \ - (see: https://github.com/rust-lang/rust/issues/48950 \ - for more info). Consider whether you meant to use the \ - type `()` here instead.", - ); - } - } - - err - } - - ty::Predicate::Subtype(ref predicate) => { - // Errors for Subtype predicates show up as - // `FulfillmentErrorCode::CodeSubtypeError`, - // not selection error. - span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate) - } - - ty::Predicate::RegionOutlives(ref predicate) => { - let predicate = self.resolve_vars_if_possible(predicate); - let err = self - .region_outlives_predicate(&obligation.cause, &predicate) - .err() - .unwrap(); - struct_span_err!( - self.tcx.sess, - span, - E0279, - "the requirement `{}` is not satisfied (`{}`)", - predicate, - err, - ) - } - - ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - struct_span_err!( - self.tcx.sess, - span, - E0280, - "the requirement `{}` is not satisfied", - predicate - ) - } - - ty::Predicate::ObjectSafe(trait_def_id) => { - let violations = object_safety_violations(self.tcx, trait_def_id); - report_object_safety_error(self.tcx, span, trait_def_id, violations) - } - - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); - let closure_span = self - .tcx - .sess - .source_map() - .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap()); - let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap(); - let mut err = struct_span_err!( - self.tcx.sess, - closure_span, - E0525, - "expected a closure that implements the `{}` trait, \ - but this closure only implements `{}`", - kind, - found_kind - ); - - err.span_label( - closure_span, - format!("this closure implements `{}`, not `{}`", found_kind, kind), - ); - err.span_label( - obligation.cause.span, - format!("the requirement to implement `{}` derives from here", kind), - ); - - // Additional context information explaining why the closure only implements - // a particular trait. - if let Some(tables) = self.in_progress_tables { - let tables = tables.borrow(); - match (found_kind, tables.closure_kind_origins().get(hir_id)) { - (ty::ClosureKind::FnOnce, Some((span, name))) => { - err.span_label( - *span, - format!( - "closure is `FnOnce` because it moves the \ - variable `{}` out of its environment", - name - ), - ); - } - (ty::ClosureKind::FnMut, Some((span, name))) => { - err.span_label( - *span, - format!( - "closure is `FnMut` because it mutates the \ - variable `{}` here", - name - ), - ); - } - _ => {} - } - } - - err.emit(); - return; - } - - ty::Predicate::WellFormed(ty) => { - if !self.tcx.sess.opts.debugging_opts.chalk { - // WF predicates cannot themselves make - // errors. They can only block due to - // ambiguity; otherwise, they always - // degenerate into other obligations - // (which may fail). - span_bug!(span, "WF predicate not satisfied for {:?}", ty); - } else { - // FIXME: we'll need a better message which takes into account - // which bounds actually failed to hold. - self.tcx.sess.struct_span_err( - span, - &format!("the type `{}` is not well-formed (chalk)", ty), - ) - } - } - - ty::Predicate::ConstEvaluatable(..) => { - // Errors for `ConstEvaluatable` predicates show up as - // `SelectionError::ConstEvalFailure`, - // not `Unimplemented`. - span_bug!( - span, - "const-evaluatable requirement gave wrong error: `{:?}`", - obligation - ) - } - } - } - - OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => { - let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref); - let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref); - - if expected_trait_ref.self_ty().references_error() { - return; - } - - let found_trait_ty = found_trait_ref.self_ty(); - - let found_did = match found_trait_ty.kind { - ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), - ty::Adt(def, _) => Some(def.did), - _ => None, - }; - - let found_span = found_did - .and_then(|did| self.tcx.hir().span_if_local(did)) - .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def - - if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { - // We check closures twice, with obligations flowing in different directions, - // but we want to complain about them only once. - return; - } - - self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); - - let found = match found_trait_ref.skip_binder().substs.type_at(1).kind { - ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], - _ => vec![ArgKind::empty()], - }; - - let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); - let expected = match expected_ty.kind { - ty::Tuple(ref tys) => tys - .iter() - .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))) - .collect(), - _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], - }; - - if found.len() == expected.len() { - self.report_closure_arg_mismatch( - span, - found_span, - found_trait_ref, - expected_trait_ref, - ) - } else { - let (closure_span, found) = found_did - .and_then(|did| self.tcx.hir().get_if_local(did)) - .map(|node| { - let (found_span, found) = self.get_fn_like_arguments(node); - (Some(found_span), found) - }) - .unwrap_or((found_span, found)); - - self.report_arg_count_mismatch( - span, - closure_span, - expected, - found, - found_trait_ty.is_closure(), - ) - } - } - - TraitNotObjectSafe(did) => { - let violations = object_safety_violations(self.tcx, did); - report_object_safety_error(self.tcx, span, did, violations) - } - - // already reported in the query - ConstEvalFailure(err) => { - if let ErrorHandled::TooGeneric = err { - // Silence this error, as it can be produced during intermediate steps - // when a constant is not yet able to be evaluated (but will be later). - return; - } - self.tcx.sess.delay_span_bug( - span, - &format!("constant in type had an ignored error: {:?}", err), - ); - return; - } - - Overflow => { - bug!("overflow should be handled before the `report_selection_error` path"); - } - }; - - self.note_obligation_cause(&mut err, obligation); - self.point_at_returns_when_relevant(&mut err, &obligation); - - err.emit(); - } - - /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait - /// with the same path as `trait_ref`, a help message about - /// a probable version mismatch is added to `err` - fn note_version_mismatch( - &self, - err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::PolyTraitRef<'tcx>, - ) { - let get_trait_impl = |trait_def_id| { - let mut trait_impl = None; - self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| { - if trait_impl.is_none() { - trait_impl = Some(impl_def_id); - } - }); - trait_impl - }; - let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); - let all_traits = self.tcx.all_traits(LOCAL_CRATE); - let traits_with_same_path: std::collections::BTreeSet<_> = all_traits - .iter() - .filter(|trait_def_id| **trait_def_id != trait_ref.def_id()) - .filter(|trait_def_id| self.tcx.def_path_str(**trait_def_id) == required_trait_path) - .collect(); - for trait_with_same_path in traits_with_same_path { - if let Some(impl_def_id) = get_trait_impl(*trait_with_same_path) { - let impl_span = self.tcx.def_span(impl_def_id); - err.span_help(impl_span, "trait impl with same name found"); - let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); - let crate_msg = format!( - "perhaps two different versions of crate `{}` are being used?", - trait_crate - ); - err.note(&crate_msg); - } - } - } - fn suggest_restricting_param_bound( + crate fn suggest_restricting_param_bound( &self, mut err: &mut DiagnosticBuilder<'_>, trait_ref: &ty::PolyTraitRef<'_>, @@ -1318,7 +168,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a /// suggestion to borrow the initializer in order to use have a slice instead. - fn suggest_borrow_on_unsized_slice( + crate fn suggest_borrow_on_unsized_slice( &self, code: &ObligationCauseCode<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1342,22 +192,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn mk_obligation_for_def_id( - &self, - def_id: DefId, - output_ty: Ty<'tcx>, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> PredicateObligation<'tcx> { - let new_trait_ref = - ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; - Obligation::new(cause, param_env, new_trait_ref.to_predicate()) - } - /// Given a closure's `DefId`, return the given name of the closure. /// /// This doesn't account for reassignments, but it's only used for suggestions. - fn get_closure_name( + crate fn get_closure_name( &self, def_id: DefId, err: &mut DiagnosticBuilder<'_>, @@ -1395,7 +233,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// We tried to apply the bound to an `fn` or closure. Check whether calling it would /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. - fn suggest_fn_call( + crate fn suggest_fn_call( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, @@ -1479,7 +317,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_add_reference_to_arg( + crate fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1548,7 +386,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`, /// suggest removing these references until we reach a type that implements the trait. - fn suggest_remove_reference( + crate fn suggest_remove_reference( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1608,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Check if the trait bound is implemented for a different mutability and note it in the /// final error. - fn suggest_change_mut( + crate fn suggest_change_mut( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1672,7 +510,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_semicolon_removal( + crate fn suggest_semicolon_removal( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1705,7 +543,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_impl_trait( + crate fn suggest_impl_trait( &self, err: &mut DiagnosticBuilder<'tcx>, span: Span, @@ -1865,7 +703,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { false } - fn point_at_returns_when_relevant( + crate fn point_at_returns_when_relevant( &self, err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>, @@ -2110,14 +948,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } - fn report_closure_arg_mismatch( + crate fn report_closure_arg_mismatch( &self, span: Span, found_span: Option, expected_ref: ty::PolyTraitRef<'tcx>, found: ty::PolyTraitRef<'tcx>, ) -> DiagnosticBuilder<'tcx> { - fn build_fn_sig_string<'tcx>(tcx: TyCtxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> String { + crate fn build_fn_sig_string<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: &ty::TraitRef<'tcx>, + ) -> String { let inputs = trait_ref.substs.type_at(1); let sig = if let ty::Tuple(inputs) = inputs.kind { tcx.mk_fn_sig( @@ -2165,238 +1006,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } -pub fn recursive_type_with_infinite_size_error( - tcx: TyCtxt<'tcx>, - type_def_id: DefId, -) -> DiagnosticBuilder<'tcx> { - assert!(type_def_id.is_local()); - let span = tcx.hir().span_if_local(type_def_id).unwrap(); - let span = tcx.sess.source_map().def_span(span); - let mut err = struct_span_err!( - tcx.sess, - span, - E0072, - "recursive type `{}` has infinite size", - tcx.def_path_str(type_def_id) - ); - err.span_label(span, "recursive type has infinite size"); - err.help(&format!( - "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ - at some point to make `{}` representable", - tcx.def_path_str(type_def_id) - )); - err -} - -pub fn report_object_safety_error( - tcx: TyCtxt<'tcx>, - span: Span, - trait_def_id: DefId, - violations: Vec, -) -> DiagnosticBuilder<'tcx> { - let trait_str = tcx.def_path_str(trait_def_id); - let span = tcx.sess.source_map().def_span(span); - let mut err = struct_span_err!( - tcx.sess, - span, - E0038, - "the trait `{}` cannot be made into an object", - trait_str - ); - err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); - - let mut reported_violations = FxHashSet::default(); - for violation in violations { - if reported_violations.insert(violation.clone()) { - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; - } - } - - if tcx.sess.trait_methods_not_found.borrow().contains(&span) { - // Avoid emitting error caused by non-existing method (#58734) - err.cancel(); - } - - err -} - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - fn maybe_report_ambiguity( - &self, - obligation: &PredicateObligation<'tcx>, - body_id: Option, - ) { - // Unable to successfully determine, probably means - // insufficient type information, but could mean - // ambiguous impls. The latter *ought* to be a - // coherence violation, so we don't report it here. - - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - let span = obligation.cause.span; - - debug!( - "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", - predicate, obligation, body_id, obligation.cause.code, - ); - - // Ambiguity errors are often caused as fallout from earlier - // errors. So just ignore them if this infcx is tainted. - if self.is_tainted_by_errors() { - return; - } - - let mut err = match predicate { - ty::Predicate::Trait(ref data) => { - let trait_ref = data.to_poly_trait_ref(); - let self_ty = trait_ref.self_ty(); - debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); - - if predicate.references_error() { - return; - } - // Typically, this ambiguity should only happen if - // there are unresolved type inference variables - // (otherwise it would suggest a coherence - // failure). But given #21974 that is not necessarily - // the case -- we can have multiple where clauses that - // are only distinguished by a region, which results - // in an ambiguity even when all types are fully - // known, since we don't dispatch based on region - // relationships. - - // This is kind of a hack: it frequently happens that some earlier - // error prevents types from being fully inferred, and then we get - // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we - // could just skip over all checks where the self-ty is an - // inference variable, but I was afraid that there might be an - // inference variable created, registered as an obligation, and - // then never forced by writeback, and hence by skipping here we'd - // be ignoring the fact that we don't KNOW the type works - // out. Though even that would probably be harmless, given that - // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to - // avoid inundating the user with unnecessary errors, but we now - // check upstream for type errors and dont add the obligations to - // begin with in those cases. - if self - .tcx - .lang_items() - .sized_trait() - .map_or(false, |sized_id| sized_id == trait_ref.def_id()) - { - self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); - return; - } - let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); - err.note(&format!("cannot resolve `{}`", predicate)); - if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { - self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } else if let ( - Ok(ref snippet), - ObligationCauseCode::BindingObligation(ref def_id, _), - ) = - (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) - { - let generics = self.tcx.generics_of(*def_id); - if !generics.params.is_empty() && !snippet.ends_with('>') { - // FIXME: To avoid spurious suggestions in functions where type arguments - // where already supplied, we check the snippet to make sure it doesn't - // end with a turbofish. Ideally we would have access to a `PathSegment` - // instead. Otherwise we would produce the following output: - // - // error[E0283]: type annotations needed - // --> $DIR/issue-54954.rs:3:24 - // | - // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - // | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - // | | - // | cannot infer type - // | help: consider specifying the type argument - // | in the function call: - // | `Tt::const_val::<[i8; 123]>::` - // ... - // LL | const fn const_val() -> usize { - // | --------- - required by this bound in `Tt::const_val` - // | - // = note: cannot resolve `_: Tt` - - err.span_suggestion( - span, - &format!( - "consider specifying the type argument{} in the function call", - if generics.params.len() > 1 { "s" } else { "" }, - ), - format!( - "{}::<{}>", - snippet, - generics - .params - .iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ") - ), - Applicability::HasPlaceholders, - ); - } - } - err - } - - ty::Predicate::WellFormed(ty) => { - // Same hacky approach as above to avoid deluging user - // with error messages. - if ty.references_error() || self.tcx.sess.has_errors() { - return; - } - self.need_type_info_err(body_id, span, ty, ErrorCode::E0282) - } - - ty::Predicate::Subtype(ref data) => { - if data.references_error() || self.tcx.sess.has_errors() { - // no need to overload user in such cases - return; - } - let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); - // both must be type variables, or the other would've been instantiated - assert!(a.is_ty_var() && b.is_ty_var()); - self.need_type_info_err(body_id, span, a, ErrorCode::E0282) - } - ty::Predicate::Projection(ref data) => { - let trait_ref = data.to_poly_trait_ref(self.tcx); - let self_ty = trait_ref.self_ty(); - if predicate.references_error() { - return; - } - let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284); - err.note(&format!("cannot resolve `{}`", predicate)); - err - } - - _ => { - if self.tcx.sess.has_errors() { - return; - } - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0284, - "type annotations needed: cannot resolve `{}`", - predicate, - ); - err.span_label(span, &format!("cannot resolve `{}`", predicate)); - err - } - }; - self.note_obligation_cause(&mut err, obligation); - err.emit(); - } - - fn suggest_fully_qualified_path( + crate fn suggest_fully_qualified_path( &self, err: &mut DiagnosticBuilder<'_>, def_id: DefId, @@ -2420,76 +1031,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - /// Returns `true` if the trait predicate may apply for *some* assignment - /// to the type parameters. - fn predicate_can_apply( - &self, - param_env: ty::ParamEnv<'tcx>, - pred: ty::PolyTraitRef<'tcx>, - ) -> bool { - struct ParamToVarFolder<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, - var_map: FxHashMap, Ty<'tcx>>, - } - - impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Param(ty::ParamTy { name, .. }) = ty.kind { - let infcx = self.infcx; - self.var_map.entry(ty).or_insert_with(|| { - infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), - span: DUMMY_SP, - }) - }) - } else { - ty.super_fold_with(self) - } - } - } - - self.probe(|_| { - let mut selcx = SelectionContext::new(self); - - let cleaned_pred = - pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); - - let cleaned_pred = super::project::normalize( - &mut selcx, - param_env, - ObligationCause::dummy(), - &cleaned_pred, - ) - .value; - - let obligation = - Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); - - self.predicate_may_hold(&obligation) - }) - } - - fn note_obligation_cause( - &self, - err: &mut DiagnosticBuilder<'_>, - obligation: &PredicateObligation<'tcx>, - ) { - // First, attempt to add note to this error with an async-await-specific - // message, and fall back to regular note otherwise. - if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { - self.note_obligation_cause_code( - err, - &obligation.predicate, - &obligation.cause.code, - &mut vec![], - ); - } - } - /// Adds an async-await specific note to the diagnostic when the future does not implement /// an auto trait because of a captured type. /// @@ -2532,7 +1073,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// ``` /// /// Returns `true` if an async-await specific note was added to the diagnostic. - fn maybe_note_obligation_cause_for_async_await( + crate fn maybe_note_obligation_cause_for_async_await( &self, err: &mut DiagnosticBuilder<'_>, obligation: &PredicateObligation<'tcx>, @@ -2712,7 +1253,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Unconditionally adds the diagnostic note described in /// `maybe_note_obligation_cause_for_async_await`'s documentation comment. - fn note_obligation_cause_for_async_await( + crate fn note_obligation_cause_for_async_await( &self, err: &mut DiagnosticBuilder<'_>, target_span: Span, @@ -2838,7 +1379,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } - fn note_obligation_cause_code( + crate fn note_obligation_cause_code( &self, err: &mut DiagnosticBuilder<'_>, predicate: &T, @@ -3053,7 +1594,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { + crate fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { let current_limit = self.tcx.sess.recursion_limit.get(); let suggested_limit = current_limit * 2; err.help(&format!( @@ -3061,52 +1602,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { suggested_limit )); } - - fn is_recursive_obligation( - &self, - obligated_types: &mut Vec<&ty::TyS<'tcx>>, - cause_code: &ObligationCauseCode<'tcx>, - ) -> bool { - if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code { - let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); - - if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) { - return true; - } - } - false - } -} - -/// Summarizes information -#[derive(Clone)] -pub enum ArgKind { - /// An argument of non-tuple type. Parameters are (name, ty) - Arg(String, String), - - /// An argument of tuple type. For a "found" argument, the span is - /// the locationo in the source of the pattern. For a "expected" - /// argument, it will be None. The vector is a list of (name, ty) - /// strings for the components of the tuple. - Tuple(Option, Vec<(String, String)>), -} - -impl ArgKind { - fn empty() -> ArgKind { - ArgKind::Arg("_".to_owned(), "_".to_owned()) - } - - /// Creates an `ArgKind` from the expected type of an - /// argument. It has no name (`_`) and an optional source span. - pub fn from_expected_ty(t: Ty<'_>, span: Option) -> ArgKind { - match t.kind { - ty::Tuple(ref tys) => ArgKind::Tuple( - span, - tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::>(), - ), - _ => ArgKind::Arg("_".to_owned(), t.to_string()), - } - } } /// Suggest restricting a type param with a new bound. From 4a75ef91f37dd0bd5267a852fa05ee0a5547a62b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 10:29:13 -0800 Subject: [PATCH 0407/1253] fix error code index comment --- src/librustc_error_codes/error_codes/E0746.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 538c9d720d71b..acf369d8e144f 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -12,7 +12,7 @@ impl T for S { } // Having the trait `T` as return type is invalid because bare traits do not -have a statically known size: +// have a statically known size: fn foo() -> dyn T { S(42) } From 5b36c187dcbb8a4b6555fe046194f2b6deb74230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 13:18:06 -0800 Subject: [PATCH 0408/1253] review comments --- src/librustc/traits/error_reporting/mod.rs | 2 + .../traits/error_reporting/suggestions.rs | 243 +++++++++--------- src/librustc/traits/mod.rs | 14 +- src/librustc/ty/error.rs | 4 +- src/librustc_typeck/check/coercion.rs | 31 +-- src/librustc_typeck/check/mod.rs | 12 - .../coerce-expect-unsized-ascribed.stderr | 14 +- .../into-iter-no-impls-length-33.stderr | 14 +- src/test/ui/destructure-trait-ref.rs | 2 - src/test/ui/destructure-trait-ref.stderr | 10 +- src/test/ui/dst/dst-bad-assign-3.rs | 2 +- src/test/ui/dst/dst-bad-assign-3.stderr | 2 +- src/test/ui/dst/dst-bad-assign.rs | 2 +- src/test/ui/dst/dst-bad-assign.stderr | 2 +- src/test/ui/error-codes/E0746.stderr | 8 +- ...n-trait-return-should-be-impl-trait.stderr | 38 +-- src/test/ui/impl-trait/equality.stderr | 2 +- src/test/ui/issues/issue-58344.stderr | 4 +- .../lifetime-elision-return-type-trait.stderr | 2 +- .../feature-gate-never_type_fallback.stderr | 2 +- ...type-err-cause-on-impl-trait-return.stderr | 12 +- ...e-57673-ice-on-deref-of-boxed-trait.stderr | 2 +- 22 files changed, 206 insertions(+), 218 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f8329124851b0..17d7b75a7f7d6 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1412,6 +1412,8 @@ pub fn suggest_constraining_type_param( false } +/// Collect all the returned expressions within the input expression. +/// Used to point at the return spans when we want to suggest some change to them. struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); impl<'v> Visitor<'v> for ReturnsVisitor<'v> { diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 389edfa071794..0a9747b631e87 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -4,6 +4,7 @@ use super::{ }; use crate::infer::InferCtxt; +use crate::traits::object_safety::object_safety_violations; use crate::ty::TypeckTables; use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; @@ -543,6 +544,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + /// If all conditions are met to identify a returned `dyn Trait`, suggest using `impl Trait` if + /// applicable and signal that the error has been expanded appropriately and needs to be + /// emitted. crate fn suggest_impl_trait( &self, err: &mut DiagnosticBuilder<'tcx>, @@ -550,9 +554,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, trait_ref: &ty::Binder>, ) -> bool { - if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { - } else { - return false; + match obligation.cause.code.peel_derives() { + // Only suggest `impl Trait` if the return type is unsized because it is `dyn Trait`. + ObligationCauseCode::SizedReturnType => {} + _ => return false, } let hir = self.tcx.hir(); @@ -565,12 +570,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let body = hir.body(*body_id); let trait_ref = self.resolve_vars_if_possible(trait_ref); let ty = trait_ref.skip_binder().self_ty(); - if let ty::Dynamic(..) = ty.kind { - } else { + let is_object_safe; + match ty.kind { + ty::Dynamic(predicates, _) => { + // The `dyn Trait` is not object safe, do not suggest `Box`. + is_object_safe = predicates.principal_def_id().map_or(true, |def_id| { + !object_safety_violations(self.tcx, def_id).is_empty() + }) + } // We only want to suggest `impl Trait` to `dyn Trait`s. // For example, `fn foo() -> str` needs to be filtered out. - return false; + _ => return false, } + + let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + ret_ty + } else { + return false; + }; + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for // cases like `fn foo() -> (dyn Trait, i32) {}`. // Recursively look for `TraitObject` types and if there's only one, use that span to @@ -583,122 +601,120 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for predicate in predicates.iter() { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } - last_ty = Some(returned_ty); - - let param_env = ty::ParamEnv::empty(); - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obligation = - Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= - self.predicate_may_hold(&obligation); - } - } - } - } - } else { - // We still want to verify whether all the return types conform to each other. + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { for expr in &visitor.0 { if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } + all_returns_have_same_type &= + Some(returned_ty) == last_ty || last_ty.is_none(); last_ty = Some(returned_ty); + for predicate in predicates.iter() { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= self.predicate_may_hold(&obl); + } + } + } + } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; } + last_ty = Some(returned_ty); } } + } + let (snippet, last_ty) = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + // Verify that we're dealing with a return `dyn Trait` ret_ty.span.overlaps(span), &ret_ty.kind, self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + // If any of the return types does not conform to the trait, then we can't + // suggest `impl Trait` nor trait objects, it is a type mismatch error. all_returns_conform_to_trait, last_ty, ) { - err.code = Some(error_code!(E0746)); - err.set_primary_message( - "return type cannot have a bare trait because it must be `Sized`", + (snippet, last_ty) + } else { + return false; + }; + err.code(error_code!(E0746)); + err.set_primary_message("return type cannot have an unboxed trait object"); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + // Suggest `-> impl Trait`. + err.span_suggestion( + ret_ty.span, + &format!( + "return `impl {1}` instead, as all return paths are of type `{}`, \ + which implements `{1}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MachineApplicable, + ); + err.note(impl_trait_msg); + } else { + if is_object_safe { + // Suggest `-> Box` and `Box::new(returned_value)`. + // Get all the return values and collect their span and suggestion. + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() + ), + ) + }) + .collect::>(); + // Add the suggestion for the return type. + suggestions.push(( + ret_ty.span, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "return a trait object instead", + suggestions, + Applicability::MaybeIncorrect, ); - err.children.clear(); - let impl_trait_msg = "for information on `impl Trait`, see \ - "; - let trait_obj_msg = "for information on trait objects, see \ - "; - let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); - let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if all_returns_have_same_type { - err.span_suggestion( - ret_ty.span, - &format!( - "you can use the `impl Trait` feature \ - in the return type because all the return paths are of type \ - `{}`, which implements `dyn {}`", - last_ty, trait_obj, - ), - format!("impl {}", trait_obj), - Applicability::MachineApplicable, - ); - err.note(impl_trait_msg); - } else { - let mut suggestions = visitor - .0 - .iter() - .map(|expr| { - ( - expr.span, - format!( - "Box::new({})", - self.tcx - .sess - .source_map() - .span_to_snippet(expr.span) - .unwrap() - ), - ) - }) - .collect::>(); - suggestions.push(( - ret_ty.span, - format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), - )); - err.multipart_suggestion( - "if the performance implications are acceptable, you can return a \ - trait object", - suggestions, - Applicability::MaybeIncorrect, - ); - err.span_help( - visitor.0.iter().map(|expr| expr.span).collect::>(), - &format!( - "if all the returned values were of the same type you could use \ - `impl {}` as the return type", - trait_obj, - ), - ); - err.help( - "alternatively, you can always create a new `enum` with a variant \ - for each returned type", - ); - err.note(impl_trait_msg); - err.note(trait_obj_msg); - } - return true; + } else { + err.note(&format!( + "if trait `{}` was object safe, you could return a trait object", + trait_obj, + )); } + err.note(&format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + )); + err.note(impl_trait_msg); + err.note(trait_obj_msg); + err.note("you can create a new `enum` with a variant for each returned type"); } + return true; } false } @@ -708,9 +724,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>, ) { - if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { - } else { - return; + match obligation.cause.code.peel_derives() { + ObligationCauseCode::SizedReturnType => {} + _ => return, } let hir = self.tcx.hir(); @@ -726,10 +742,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); for expr in &visitor.0 { if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - err.span_label( - expr.span, - &format!("this returned value is of type `{}`", returned_ty), - ); + let ty = self.resolve_vars_if_possible(&returned_ty); + err.span_label(expr.span, &format!("this returned value is of type `{}`", ty)); } } } @@ -1685,9 +1699,8 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} + if let hir::ExprKind::Ret(Some(ex)) = ex.kind { + self.0.push(ex); } hir::intravisit::walk_expr(self, ex); } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index f68711c06205b..b4998d4486f09 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -155,8 +155,8 @@ pub struct ObligationCause<'tcx> { pub code: ObligationCauseCode<'tcx>, } -impl<'tcx> ObligationCause<'tcx> { - pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span { +impl ObligationCause<'_> { + pub fn span(&self, tcx: TyCtxt<'_>) -> Span { match self.code { ObligationCauseCode::CompareImplMethodObligation { .. } | ObligationCauseCode::MainFunctionType @@ -1172,13 +1172,13 @@ impl<'tcx> ObligationCause<'tcx> { } impl<'tcx> ObligationCauseCode<'tcx> { + // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { - match self { - BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) => { - cause.parent_code.peel_derives() - } - _ => self, + let mut base_cause = self; + while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause { + base_cause = &cause.parent_code; } + base_cause } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index f7612874e05b6..217ca0ca3f6f5 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -244,9 +244,9 @@ impl<'tcx> ty::TyS<'tcx> { ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { if let Some(principal) = inner.principal() { - format!("trait `{}`", tcx.def_path_str(principal.def_id())).into() + format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into() } else { - "trait".into() + "trait object".into() } } ty::Closure(..) => "closure".into(), diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 77f16fb79141d..66499b1753fdd 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -50,6 +50,7 @@ //! sort of a minor point so I've opted to leave it for later -- after all, //! we may want to adjust precisely when coercions occur. +use crate::astconv::AstConv; use crate::check::{FnCtxt, Needs}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; @@ -1245,7 +1246,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expression.map(|expr| (expr, blk_id)), ); if !fcx.tcx.features().unsized_locals { - unsized_return = fcx.is_unsized_return(blk_id); + unsized_return = self.is_return_ty_unsized(fcx, blk_id); } } ObligationCauseCode::ReturnValue(id) => { @@ -1260,7 +1261,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); if !fcx.tcx.features().unsized_locals { let id = fcx.tcx.hir().get_parent_node(id); - unsized_return = fcx.is_unsized_return(id); + unsized_return = self.is_return_ty_unsized(fcx, id); } } _ => { @@ -1290,15 +1291,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) .is_some(); - if unsized_return { - fcx.tcx.sess.delay_span_bug( - cause.span, - &format!( - "elided E0308 in favor of more detailed E0277 or E0746: {:?}", - cause.code - ), - ); - } err.emit_unless(assign_to_bool || unsized_return); self.final_ty = Some(fcx.tcx.types.err); @@ -1365,10 +1357,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { "...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected), )); - err.note( - "`impl Trait` as a return type requires that all the returned values must have \ - the same type", - ); + err.note("to return `impl Trait`, all returned values must be of the same type"); let snippet = fcx .tcx .sess @@ -1397,6 +1386,18 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err } + fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { + if let Some((fn_decl, _)) = fcx.get_fn_decl(blk_id) { + if let hir::FunctionRetTy::Return(ty) = fn_decl.output { + let ty = AstConv::ast_ty_to_ty(fcx, ty); + if let ty::Dynamic(..) = ty.kind { + return true; + } + } + } + false + } + pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> { if let Some(final_ty) = self.final_ty { final_ty diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8f531ea6199e1..baf9ae1ac2911 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4964,18 +4964,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn is_unsized_return(&self, blk_id: hir::HirId) -> bool { - if let Some((fn_decl, _)) = self.get_fn_decl(blk_id) { - if let hir::FunctionRetTy::Return(ty) = fn_decl.output { - let ty = AstConv::ast_ty_to_ty(self, ty); - if let ty::Dynamic(..) = ty.kind { - return true; - } - } - } - false - } - /// A possible error is to forget to add a return type that is needed: /// /// ``` diff --git a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr index 303d83d342625..44e5c6a99f727 100644 --- a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr +++ b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr @@ -29,7 +29,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:13:13 | LL | let _ = box { |x| (x as u8) }: Box _>; - | ^^^^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected struct `std::boxed::Box u8>` found struct `std::boxed::Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:19: 13:32]>` @@ -38,7 +38,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:14:13 | LL | let _ = box if true { false } else { true }: Box; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `bool` | = note: expected struct `std::boxed::Box` found struct `std::boxed::Box` @@ -47,7 +47,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:15:13 | LL | let _ = box match true { true => 'a', false => 'b' }: Box; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `char` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `char` | = note: expected struct `std::boxed::Box` found struct `std::boxed::Box` @@ -83,7 +83,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:21:13 | LL | let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; - | ^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected reference `&dyn std::ops::Fn(i32) -> u8` found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:16: 21:29]` @@ -92,7 +92,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:22:13 | LL | let _ = &if true { false } else { true }: &dyn Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `bool` | = note: expected reference `&dyn std::fmt::Debug` found reference `&bool` @@ -101,7 +101,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:23:13 | LL | let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `char` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `char` | = note: expected reference `&dyn std::fmt::Debug` found reference `&char` @@ -119,7 +119,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:26:13 | LL | let _ = Box::new(|x| (x as u8)): Box _>; - | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected struct `std::boxed::Box _>` found struct `std::boxed::Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:22: 26:35]>` diff --git a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr index e615e10bd5f5f..4869f48363447 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr @@ -13,7 +13,7 @@ LL | pub fn no_iterator() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -33,7 +33,7 @@ LL | pub fn no_double_ended_iterator() -> impl DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::DoubleEndedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -53,7 +53,7 @@ LL | pub fn no_exact_size_iterator() -> impl ExactSizeIterator { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::ExactSizeIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -73,7 +73,7 @@ LL | pub fn no_fused_iterator() -> impl FusedIterator { | ^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::FusedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -93,7 +93,7 @@ LL | pub fn no_trusted_len() -> impl TrustedLen { | ^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::TrustedLen` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -113,7 +113,7 @@ LL | pub fn no_clone() -> impl Clone { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -133,7 +133,7 @@ LL | pub fn no_debug() -> impl Debug { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::array::IntoIter` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/destructure-trait-ref.rs b/src/test/ui/destructure-trait-ref.rs index fb92196b2bd56..34e7cad935aeb 100644 --- a/src/test/ui/destructure-trait-ref.rs +++ b/src/test/ui/destructure-trait-ref.rs @@ -33,12 +33,10 @@ fn main() { //~^ ERROR mismatched types //~| expected trait object `dyn T` //~| found reference `&_` - //~| expected trait `T`, found reference let &&&x = &(&1isize as &dyn T); //~^ ERROR mismatched types //~| expected trait object `dyn T` //~| found reference `&_` - //~| expected trait `T`, found reference let box box x = box 1isize as Box; //~^ ERROR mismatched types //~| expected trait object `dyn T` diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr index c78166f411d28..f99bf2ffdc9d4 100644 --- a/src/test/ui/destructure-trait-ref.stderr +++ b/src/test/ui/destructure-trait-ref.stderr @@ -22,31 +22,31 @@ error[E0308]: mismatched types LL | let &&x = &1isize as &dyn T; | ^^ | | - | expected trait `T`, found reference + | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` | = note: expected trait object `dyn T` found reference `&_` error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:37:11 + --> $DIR/destructure-trait-ref.rs:36:11 | LL | let &&&x = &(&1isize as &dyn T); | ^^ | | - | expected trait `T`, found reference + | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` | = note: expected trait object `dyn T` found reference `&_` error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:42:13 + --> $DIR/destructure-trait-ref.rs:40:13 | LL | let box box x = box 1isize as Box; | ^^^^^ ------------------------ this expression has type `std::boxed::Box` | | - | expected trait `T`, found struct `std::boxed::Box` + | expected trait object `dyn T`, found struct `std::boxed::Box` | = note: expected trait object `dyn T` found struct `std::boxed::Box<_>` diff --git a/src/test/ui/dst/dst-bad-assign-3.rs b/src/test/ui/dst/dst-bad-assign-3.rs index e3b621b909a0c..d05b3937c998c 100644 --- a/src/test/ui/dst/dst-bad-assign-3.rs +++ b/src/test/ui/dst/dst-bad-assign-3.rs @@ -32,7 +32,7 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.2 = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected trait `ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar`, found struct `Bar1` //~| expected trait object `dyn ToBar` //~| found struct `Bar1` //~| ERROR the size for values of type diff --git a/src/test/ui/dst/dst-bad-assign-3.stderr b/src/test/ui/dst/dst-bad-assign-3.stderr index dc03f38e10387..0b6f9df2d83ee 100644 --- a/src/test/ui/dst/dst-bad-assign-3.stderr +++ b/src/test/ui/dst/dst-bad-assign-3.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dst-bad-assign-3.rs:33:12 | LL | f5.2 = Bar1 {f: 36}; - | ^^^^^^^^^^^^ expected trait `ToBar`, found struct `Bar1` + | ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` | = note: expected trait object `dyn ToBar` found struct `Bar1` diff --git a/src/test/ui/dst/dst-bad-assign.rs b/src/test/ui/dst/dst-bad-assign.rs index ed94242f5bfd0..496e01ae00532 100644 --- a/src/test/ui/dst/dst-bad-assign.rs +++ b/src/test/ui/dst/dst-bad-assign.rs @@ -34,7 +34,7 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.ptr = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected trait `ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar`, found struct `Bar1` //~| expected trait object `dyn ToBar` //~| found struct `Bar1` //~| ERROR the size for values of type diff --git a/src/test/ui/dst/dst-bad-assign.stderr b/src/test/ui/dst/dst-bad-assign.stderr index 8031f162482e3..434c460759fb4 100644 --- a/src/test/ui/dst/dst-bad-assign.stderr +++ b/src/test/ui/dst/dst-bad-assign.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dst-bad-assign.rs:35:14 | LL | f5.ptr = Bar1 {f: 36}; - | ^^^^^^^^^^^^ expected trait `ToBar`, found struct `Bar1` + | ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` | = note: expected trait object `dyn ToBar` found struct `Bar1` diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 1c88ce64749ae..e7a8fd304cabe 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,23 +1,23 @@ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/E0746.rs:8:13 | LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/E0746.rs:11:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bar() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ff7438e9affc1..3d0707c091644 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35 | LL | fn fuz() -> (usize, Trait) { (42, Struct) } - | ^^^^^^ expected trait `Trait`, found struct `Struct` + | ^^^^^^ expected trait object `dyn Trait`, found struct `Struct` | = note: expected trait object `(dyn Trait + 'static)` found struct `Struct` @@ -24,7 +24,7 @@ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39 | LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } - | ^^^^^^ expected trait `Trait`, found struct `Struct` + | ^^^^^^ expected trait object `dyn Trait`, found struct `Struct` | = note: expected trait object `(dyn Trait + 'static)` found struct `Struct` @@ -42,26 +42,26 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 | LL | fn bap() -> Trait { Struct } | ^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn bap() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13 | LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn ban() -> impl Trait { Struct } | ^^^^^^^^^^ @@ -76,40 +76,26 @@ LL | fn bak() -> dyn Trait { unimplemented!() } = note: to learn more, visit = note: the return type of a function must have a statically known size -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 | LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: if all the returned values were of the same type you could use `impl Trait` as the return type - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:5 - | -LL | return Struct; - | ^^^^^^ -LL | } -LL | 42 - | ^^ - = help: alternatively, you can always create a new `enum` with a variant for each returned type + = note: if trait `Trait` was object safe, you could return a trait object + = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see = note: for information on trait objects, see -help: if the performance implications are acceptable, you can return a trait object - | -LL | fn bal() -> Box { -LL | if true { -LL | return Box::new(Struct); -LL | } -LL | Box::new(42) - | + = note: you can create a new `enum` with a variant for each returned type -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bat() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 215b6d52918ab..be8653d1689f8 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -10,7 +10,7 @@ LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/issues/issue-58344.stderr b/src/test/ui/issues/issue-58344.stderr index 9b07dbd7ab69c..e0c196e518ba3 100644 --- a/src/test/ui/issues/issue-58344.stderr +++ b/src/test/ui/issues/issue-58344.stderr @@ -5,7 +5,7 @@ LL | ) -> Either>::Output>, impl Trait<` is not implemented for `impl Trait<::Output>` ... LL | add_generic(value, 1u32) - | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` + | ------------------------ this returned value is of type `Either::Output>, impl Trait<::Output>>` | = note: the return type of a function must have a statically known size @@ -16,7 +16,7 @@ LL | ) -> Either>::Output>, impl Trait<` is not implemented for `impl Trait<::Output>` ... LL | add_generic(value, 1u32) - | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` + | ------------------------ this returned value is of type `Either::Output>, impl Trait<::Output>>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 49fa11c35aef8..e43fb6d0edfb9 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -5,7 +5,7 @@ LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>` LL | LL | Ok(()) - | ------ this returned value is of type `std::result::Result<_, _>` + | ------ this returned value is of type `std::result::Result<(), _>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 88bfed2b54742..77288f1badac5 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -5,7 +5,7 @@ LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` LL | LL | panic!() - | -------- this returned value is of type `_` + | -------- this returned value is of type `()` | = note: the return type of a function must have a statically known size = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 9db5250e4d876..2c0425e718abc 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -10,7 +10,7 @@ LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -27,7 +27,7 @@ LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -44,7 +44,7 @@ LL | } else { LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -73,7 +73,7 @@ LL | 0 => return 0i32, LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -92,7 +92,7 @@ LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -109,7 +109,7 @@ LL | return 0i32; LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr index 14c09ade7dde3..a656b20c23ec3 100644 --- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn ice(x: Box>) { | - possibly return type missing here? LL | *x - | ^^ expected `()`, found trait `std::iter::Iterator` + | ^^ expected `()`, found trait object `dyn std::iter::Iterator` | = note: expected unit type `()` found trait object `(dyn std::iter::Iterator + 'static)` From 509cb33dbcdb631625288f72c359a35dde6524b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 14:49:30 -0800 Subject: [PATCH 0409/1253] review comments --- src/librustc/traits/error_reporting/suggestions.rs | 9 +++------ src/librustc_typeck/check/coercion.rs | 1 + src/test/ui/impl-trait/equality.stderr | 1 + .../point-to-type-err-cause-on-impl-trait-return.stderr | 6 ++++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 0a9747b631e87..c2f562b4bc7b2 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -624,12 +624,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { // We still want to verify whether all the return types conform to each other. for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } - last_ty = Some(returned_ty); - } + let returned_ty = tables.node_type_opt(expr.hir_id); + all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); + last_ty = returned_ty; } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 66499b1753fdd..8aa2cb5034224 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1372,6 +1372,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { &snippet[5..] )); } + err.help("alternatively, create a new `enum` with a variant for each returned type"); let impl_trait_msg = "for information on `impl Trait`, see \ "; diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index be8653d1689f8..ceb32dd4cd33e 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,6 +12,7 @@ LL | 0_u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 2c0425e718abc..87daab5ca7a22 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -12,6 +12,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -29,6 +30,7 @@ LL | return 1u32; | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -46,6 +48,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -75,6 +78,7 @@ LL | _ => 1u32, | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -94,6 +98,7 @@ LL | | } | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -111,6 +116,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see From c305ac31c09fdd5078fa0e69e718b4da10d9e354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:55:56 -0800 Subject: [PATCH 0410/1253] Fix error index test --- src/librustc_error_codes/error_codes/E0746.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index acf369d8e144f..2df27bcf0bf09 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -2,7 +2,8 @@ Return types cannot be `dyn Trait`s as they must be `Sized`. Erroneous code example: -```compile_fail,E0746 +```compile_fail,E0277 +# // FIXME: after E0746 is in beta, change the above trait T { fn bar(&self); } From d7a62124018ce8438caeedca203d39997f130b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 11:14:05 -0800 Subject: [PATCH 0411/1253] review comments --- src/librustc/traits/error_reporting/mod.rs | 32 --- .../traits/error_reporting/suggestions.rs | 270 +++++++++--------- src/librustc/traits/mod.rs | 2 +- src/librustc_error_codes/error_codes/E0746.md | 10 +- src/librustc_typeck/check/coercion.rs | 67 +++-- ...n-trait-return-should-be-impl-trait.stderr | 11 +- src/test/ui/impl-trait/equality.stderr | 4 +- ...type-err-cause-on-impl-trait-return.stderr | 24 +- 8 files changed, 204 insertions(+), 216 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 17d7b75a7f7d6..db3173989ac60 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -25,7 +25,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_hir::intravisit::Visitor; use rustc_span::source_map::SourceMap; use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; @@ -1411,34 +1410,3 @@ pub fn suggest_constraining_type_param( } false } - -/// Collect all the returned expressions within the input expression. -/// Used to point at the return spans when we want to suggest some change to them. -struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); - -impl<'v> Visitor<'v> for ReturnsVisitor<'v> { - type Map = rustc::hir::map::Map<'v>; - - fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { - hir::intravisit::NestedVisitorMap::None - } - - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} - } - hir::intravisit::walk_expr(self, ex); - } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - if body.generator_kind().is_none() { - if let hir::ExprKind::Block(block, None) = body.value.kind { - if let Some(expr) = block.expr { - self.0.push(expr); - } - } - } - hir::intravisit::walk_body(self, body); - } -} diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c2f562b4bc7b2..7c1b1041c34c3 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -563,157 +563,159 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let hir = self.tcx.hir(); let parent_node = hir.get_parent_node(obligation.cause.body_id); let node = hir.find(parent_node); - if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(sig, _, body_id), .. + let (sig, body_id) = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(sig, _, body_id), + .. })) = node { - let body = hir.body(*body_id); - let trait_ref = self.resolve_vars_if_possible(trait_ref); - let ty = trait_ref.skip_binder().self_ty(); - let is_object_safe; - match ty.kind { - ty::Dynamic(predicates, _) => { - // The `dyn Trait` is not object safe, do not suggest `Box`. - is_object_safe = predicates.principal_def_id().map_or(true, |def_id| { - !object_safety_violations(self.tcx, def_id).is_empty() - }) - } - // We only want to suggest `impl Trait` to `dyn Trait`s. - // For example, `fn foo() -> str` needs to be filtered out. - _ => return false, + (sig, body_id) + } else { + return false; + }; + let body = hir.body(*body_id); + let trait_ref = self.resolve_vars_if_possible(trait_ref); + let ty = trait_ref.skip_binder().self_ty(); + let is_object_safe = match ty.kind { + ty::Dynamic(predicates, _) => { + // If the `dyn Trait` is not object safe, do not suggest `Box`. + predicates + .principal_def_id() + .map_or(true, |def_id| object_safety_violations(self.tcx, def_id).is_empty()) } + // We only want to suggest `impl Trait` to `dyn Trait`s. + // For example, `fn foo() -> str` needs to be filtered out. + _ => return false, + }; - let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { - ret_ty - } else { - return false; - }; - - // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for - // cases like `fn foo() -> (dyn Trait, i32) {}`. - // Recursively look for `TraitObject` types and if there's only one, use that span to - // suggest `impl Trait`. - - // Visit to make sure there's a single `return` type to suggest `impl Trait`, - // otherwise suggest using `Box` or an enum. - let mut visitor = ReturnsVisitor(vec![]); - visitor.visit_body(&body); - - let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + ret_ty + } else { + return false; + }; - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - let param_env = ty::ParamEnv::empty(); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - all_returns_have_same_type &= - Some(returned_ty) == last_ty || last_ty.is_none(); - last_ty = Some(returned_ty); - for predicate in predicates.iter() { - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= self.predicate_may_hold(&obl); - } + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for + // cases like `fn foo() -> (dyn Trait, i32) {}`. + // Recursively look for `TraitObject` types and if there's only one, use that span to + // suggest `impl Trait`. + + // Visit to make sure there's a single `return` type to suggest `impl Trait`, + // otherwise suggest using `Box` or an enum. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + all_returns_have_same_type &= + Some(returned_ty) == last_ty || last_ty.is_none(); + last_ty = Some(returned_ty); + for predicate in predicates.iter() { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= self.predicate_may_hold(&obl); } } } - } else { - // We still want to verify whether all the return types conform to each other. - for expr in &visitor.0 { - let returned_ty = tables.node_type_opt(expr.hir_id); - all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); - last_ty = returned_ty; - } } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + let returned_ty = tables.node_type_opt(expr.hir_id); + all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); + last_ty = returned_ty; + } + } - let (snippet, last_ty) = - if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( - // Verify that we're dealing with a return `dyn Trait` - ret_ty.span.overlaps(span), - &ret_ty.kind, - self.tcx.sess.source_map().span_to_snippet(ret_ty.span), - // If any of the return types does not conform to the trait, then we can't - // suggest `impl Trait` nor trait objects, it is a type mismatch error. - all_returns_conform_to_trait, - last_ty, - ) { - (snippet, last_ty) - } else { - return false; - }; - err.code(error_code!(E0746)); - err.set_primary_message("return type cannot have an unboxed trait object"); - err.children.clear(); - let impl_trait_msg = "for information on `impl Trait`, see \ - "; - let trait_obj_msg = "for information on trait objects, see \ - "; - let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); - let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if all_returns_have_same_type { - // Suggest `-> impl Trait`. - err.span_suggestion( + let (snippet, last_ty) = + if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + // Verify that we're dealing with a return `dyn Trait` + ret_ty.span.overlaps(span), + &ret_ty.kind, + self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + // If any of the return types does not conform to the trait, then we can't + // suggest `impl Trait` nor trait objects, it is a type mismatch error. + all_returns_conform_to_trait, + last_ty, + ) { + (snippet, last_ty) + } else { + return false; + }; + err.code(error_code!(E0746)); + err.set_primary_message("return type cannot have an unboxed trait object"); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + // Suggest `-> impl Trait`. + err.span_suggestion( + ret_ty.span, + &format!( + "return `impl {1}` instead, as all return paths are of type `{}`, \ + which implements `{1}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MachineApplicable, + ); + err.note(impl_trait_msg); + } else { + if is_object_safe { + // Suggest `-> Box` and `Box::new(returned_value)`. + // Get all the return values and collect their span and suggestion. + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() + ), + ) + }) + .collect::>(); + // Add the suggestion for the return type. + suggestions.push(( ret_ty.span, - &format!( - "return `impl {1}` instead, as all return paths are of type `{}`, \ - which implements `{1}`", - last_ty, trait_obj, - ), - format!("impl {}", trait_obj), - Applicability::MachineApplicable, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "return a trait object instead", + suggestions, + Applicability::MaybeIncorrect, ); - err.note(impl_trait_msg); } else { - if is_object_safe { - // Suggest `-> Box` and `Box::new(returned_value)`. - // Get all the return values and collect their span and suggestion. - let mut suggestions = visitor - .0 - .iter() - .map(|expr| { - ( - expr.span, - format!( - "Box::new({})", - self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() - ), - ) - }) - .collect::>(); - // Add the suggestion for the return type. - suggestions.push(( - ret_ty.span, - format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), - )); - err.multipart_suggestion( - "return a trait object instead", - suggestions, - Applicability::MaybeIncorrect, - ); - } else { - err.note(&format!( - "if trait `{}` was object safe, you could return a trait object", - trait_obj, - )); - } err.note(&format!( - "if all the returned values were of the same type you could use \ - `impl {}` as the return type", + "if trait `{}` was object safe, you could return a trait object", trait_obj, )); - err.note(impl_trait_msg); - err.note(trait_obj_msg); - err.note("you can create a new `enum` with a variant for each returned type"); } - return true; + err.note(trait_obj_msg); + err.note(&format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + )); + err.note(impl_trait_msg); + err.note("you can create a new `enum` with a variant for each returned type"); } - false + true } crate fn point_at_returns_when_relevant( @@ -1686,6 +1688,8 @@ pub fn suggest_constraining_type_param( false } +/// Collect all the returned expressions within the input expression. +/// Used to point at the return spans when we want to suggest some change to them. struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); impl<'v> Visitor<'v> for ReturnsVisitor<'v> { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b4998d4486f09..2e5da2b038254 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1171,7 +1171,7 @@ impl<'tcx> ObligationCause<'tcx> { } } -impl<'tcx> ObligationCauseCode<'tcx> { +impl ObligationCauseCode<'_> { // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { let mut base_cause = self; diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 2df27bcf0bf09..041061f3380c1 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -12,8 +12,8 @@ impl T for S { fn bar(&self) {} } -// Having the trait `T` as return type is invalid because bare traits do not -// have a statically known size: +// Having the trait `T` as return type is invalid because +// bare trait objects do not have a statically known size: fn foo() -> dyn T { S(42) } @@ -32,15 +32,15 @@ If there is a single type involved, you can use [`impl Trait`]: # fn bar(&self) {} # } // The compiler will select `S(usize)` as the materialized return type of this -// function, but callers will only be able to access associated items from `T`. +// function, but callers will only know that the return type implements `T`. fn foo() -> impl T { S(42) } ``` If there are multiple types involved, the only way you care to interact with -them is through the trait's interface and having to rely on dynamic dispatch is -acceptable, then you can use [trait objects] with `Box`, or other container +them is through the trait's interface, and having to rely on dynamic dispatch +is acceptable, then you can use [trait objects] with `Box`, or other container types like `Rc` or `Arc`: ``` diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8aa2cb5034224..768e532fa3b91 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -68,7 +68,7 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_span; +use rustc_span::{self, Span}; use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; @@ -1352,39 +1352,48 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) { - err.span_label(return_sp, "expected because this return type..."); - err.span_label( *sp, format!( - "...is found to be `{}` here", - fcx.resolve_vars_with_obligations(expected), - )); - err.note("to return `impl Trait`, all returned values must be of the same type"); - let snippet = fcx - .tcx - .sess - .source_map() - .span_to_snippet(return_sp) - .unwrap_or_else(|_| "dyn Trait".to_string()); - let mut snippet_iter = snippet.split_whitespace(); - let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); - if has_impl { - err.help(&format!( - "you can instead return a trait object using `Box`", - &snippet[5..] - )); - } - err.help("alternatively, create a new `enum` with a variant for each returned type"); - let impl_trait_msg = "for information on `impl Trait`, see \ + self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, return_sp); + } + err + } + + fn add_impl_trait_explanation<'a>( + &self, + err: &mut DiagnosticBuilder<'a>, + fcx: &FnCtxt<'a, 'tcx>, + expected: Ty<'tcx>, + sp: Span, + return_sp: Span, + ) { + err.span_label(return_sp, "expected because this return type..."); + err.span_label( + sp, + format!("...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected)), + ); + let impl_trait_msg = "for information on `impl Trait`, see \ "; - let trait_obj_msg = "for information on trait objects, see \ + let trait_obj_msg = "for information on trait objects, see \ "; - err.note(impl_trait_msg); - if has_impl { - err.note(trait_obj_msg); - } + err.note("to return `impl Trait`, all returned values must be of the same type"); + err.note(impl_trait_msg); + let snippet = fcx + .tcx + .sess + .source_map() + .span_to_snippet(return_sp) + .unwrap_or_else(|_| "dyn Trait".to_string()); + let mut snippet_iter = snippet.split_whitespace(); + let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + if has_impl { + err.help(&format!( + "you can instead return a trait object using `Box`", + &snippet[5..] + )); + err.note(trait_obj_msg); } - err + err.help("alternatively, create a new `enum` with a variant for each returned type"); } fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 3d0707c091644..ac101f8f3ce36 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -82,11 +82,18 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = note: if trait `Trait` was object safe, you could return a trait object + = note: for information on trait objects, see = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see - = note: for information on trait objects, see = note: you can create a new `enum` with a variant for each returned type +help: return a trait object instead + | +LL | fn bal() -> Box { +LL | if true { +LL | return Box::new(Struct); +LL | } +LL | Box::new(42) + | error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index ceb32dd4cd33e..a399fadbc5db5 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -11,10 +11,10 @@ LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 87daab5ca7a22..9859c73b7b18b 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -11,10 +11,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 @@ -29,10 +29,10 @@ LL | return 1u32; | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9 @@ -47,10 +47,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 @@ -77,10 +77,10 @@ LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5 @@ -97,10 +97,10 @@ LL | | } | |_____^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13 @@ -115,10 +115,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error: aborting due to 7 previous errors From 00e262689599a6a753bbf7ce8786e07ed100d238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 15:49:54 -0800 Subject: [PATCH 0412/1253] Account for object safety when suggesting `Box` --- .../traits/error_reporting/suggestions.rs | 4 +- src/librustc_hir/hir.rs | 7 +++ src/librustc_typeck/check/coercion.rs | 53 +++++++++++++++---- ...n-trait-return-should-be-impl-trait.stderr | 2 +- src/test/ui/impl-trait/equality.stderr | 2 +- ...safe-trait-in-return-position-dyn-trait.rs | 35 ++++++++++++ ...-trait-in-return-position-dyn-trait.stderr | 21 ++++++++ ...afe-trait-in-return-position-impl-trait.rs | 46 ++++++++++++++++ ...trait-in-return-position-impl-trait.stderr | 39 ++++++++++++++ ...type-err-cause-on-impl-trait-return.stderr | 12 ++--- 10 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 7c1b1041c34c3..c3af063d518f0 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -696,11 +696,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), )); err.multipart_suggestion( - "return a trait object instead", + "return a boxed trait object instead", suggestions, Applicability::MaybeIncorrect, ); } else { + // This is currently not possible to trigger because E0038 takes precedence, but + // leave it in for completeness in case anything changes in an earlier stage. err.note(&format!( "if trait `{}` was object safe, you could return a trait object", trait_obj, diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 550e3654d0800..5c1d600c837c4 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -377,6 +377,13 @@ pub enum GenericBound<'hir> { } impl GenericBound<'_> { + pub fn trait_def_id(&self) -> Option { + match self { + GenericBound::Trait(data, _) => Some(data.trait_ref.trait_def_id()), + _ => None, + } + } + pub fn span(&self) -> Span { match self { &GenericBound::Trait(ref t, ..) => t.span, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 768e532fa3b91..a32fbff7bfe2d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -55,6 +55,7 @@ use crate::check::{FnCtxt, Needs}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; use rustc::session::parse::feature_err; +use rustc::traits::object_safety_violations; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -68,8 +69,8 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_span::{self, Span}; use rustc_span::symbol::sym; +use rustc_span::{self, Span}; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; @@ -1311,7 +1312,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err); let mut pointing_at_return_type = false; - let mut return_sp = None; + let mut fn_output = None; // Verify that this is a tail expression of a function, otherwise the // label pointing out the cause for the type coercion will be wrong @@ -1348,11 +1349,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); } if !pointing_at_return_type { - return_sp = Some(fn_decl.output.span()); // `impl Trait` return type + fn_output = Some(&fn_decl.output); // `impl Trait` return type } } - if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) { - self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, return_sp); + if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) { + self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, fn_output); } err } @@ -1363,8 +1364,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx: &FnCtxt<'a, 'tcx>, expected: Ty<'tcx>, sp: Span, - return_sp: Span, + fn_output: &hir::FunctionRetTy<'_>, ) { + let return_sp = fn_output.span(); err.span_label(return_sp, "expected because this return type..."); err.span_label( sp, @@ -1386,11 +1388,42 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .unwrap_or_else(|_| "dyn Trait".to_string()); let mut snippet_iter = snippet.split_whitespace(); let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + // Only suggest `Box` if `Trait` in `impl Trait` is object safe. + let mut is_object_safe = false; + if let hir::FunctionRetTy::Return(ty) = fn_output { + // Get the return type. + if let hir::TyKind::Def(..) = ty.kind { + let ty = AstConv::ast_ty_to_ty(fcx, ty); + // Get the `impl Trait`'s `DefId`. + if let ty::Opaque(def_id, _) = ty.kind { + let hir_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap(); + // Get the `impl Trait`'s `Item` so that we can get its trait bounds and + // get the `Trait`'s `DefId`. + if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = + fcx.tcx.hir().expect_item(hir_id).kind + { + // Are of this `impl Trait`'s traits object safe? + is_object_safe = bounds.iter().all(|bound| { + bound.trait_def_id().map_or(false, |def_id| { + object_safety_violations(fcx.tcx, def_id).is_empty() + }) + }) + } + } + } + }; if has_impl { - err.help(&format!( - "you can instead return a trait object using `Box`", - &snippet[5..] - )); + if is_object_safe { + err.help(&format!( + "you can instead return a boxed trait object using `Box`", + &snippet[5..] + )); + } else { + err.help(&format!( + "if the trait `{}` were object safe, you could return a boxed trait object", + &snippet[5..] + )); + } err.note(trait_obj_msg); } err.help("alternatively, create a new `enum` with a variant for each returned type"); diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ac101f8f3ce36..977a7ef0e0244 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -86,7 +86,7 @@ LL | fn bal() -> dyn Trait { = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see = note: you can create a new `enum` with a variant for each returned type -help: return a trait object instead +help: return a boxed trait object instead | LL | fn bal() -> Box { LL | if true { diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index a399fadbc5db5..9178358b60a9c 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,7 +12,7 @@ LL | 0_u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: if the trait `Foo` were object safe, you could return a boxed trait object = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs new file mode 100644 index 0000000000000..ab3086c78b3a1 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs @@ -0,0 +1,35 @@ +#![allow(bare_trait_objects)] +trait NotObjectSafe { + fn foo() -> Self; +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be made into an object + if true { + return A; + } + B +} + +fn cat() -> Box { //~ ERROR the trait `NotObjectSafe` cannot be made into an + if true { + return Box::new(A); + } + Box::new(B) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr new file mode 100644 index 0000000000000..0c8d267c13434 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:1 + | +LL | fn foo() -> Self; + | --- associated function `foo` has no `self` parameter +... +LL | fn car() -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:1 + | +LL | fn foo() -> Self; + | --- associated function `foo` has no `self` parameter +... +LL | fn cat() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs new file mode 100644 index 0000000000000..503515013b9ab --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs @@ -0,0 +1,46 @@ +trait NotObjectSafe { + fn foo() -> Self; +} + +trait ObjectSafe { + fn bar(&self); +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +impl ObjectSafe for A { + fn bar(&self) {} +} + +impl ObjectSafe for B { + fn bar(&self) {} +} + +fn can() -> impl NotObjectSafe { + if true { + return A; + } + B //~ ERROR mismatched types +} + +fn cat() -> impl ObjectSafe { + if true { + return A; + } + B //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr new file mode 100644 index 0000000000000..dd4260fbe4f91 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 + | +LL | fn can() -> impl NotObjectSafe { + | ------------------ expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } +LL | B + | ^ expected struct `A`, found struct `B` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: if the trait `NotObjectSafe` were object safe, you could return a boxed trait object + = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type + +error[E0308]: mismatched types + --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 + | +LL | fn cat() -> impl ObjectSafe { + | --------------- expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } +LL | B + | ^ expected struct `A`, found struct `B` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: you can instead return a boxed trait object using `Box` + = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 9859c73b7b18b..b663cccbeef0f 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -12,7 +12,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -30,7 +30,7 @@ LL | return 1u32; | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -48,7 +48,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -78,7 +78,7 @@ LL | _ => 1u32, | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -98,7 +98,7 @@ LL | | } | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -116,7 +116,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type From 3fd1af5fdb59a49e9eb5e05ff15fef6b8514ae31 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jan 2020 13:33:28 +0100 Subject: [PATCH 0413/1253] let rustfmt undo most of my edits :( --- src/librustc/mir/interpret/error.rs | 3 +-- src/librustc_mir/interpret/cast.rs | 20 +++++++++----------- src/librustc_mir/interpret/eval_context.rs | 12 +++--------- src/librustc_mir/interpret/memory.rs | 3 +-- src/librustc_mir/interpret/operand.rs | 4 +--- src/librustc_mir/interpret/validity.rs | 6 ++---- 6 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 29b3b045ca5fe..42d896af8014d 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,8 +137,7 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { let must_error = match self.error { InterpError::MachineStop(_) => bug!("CTFE does not stop"), - err_inval!(Layout(LayoutError::Unknown(_))) - | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { return Err(ErrorHandled::TooGeneric); } err_inval!(TypeckError) => return Err(ErrorHandled::Reported), diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 6d0b6bf70ad8c..9461a06690212 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -118,17 +118,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that // are represented as integers. - _ => { - assert!( - src.layout.ty.is_bool() - || src.layout.ty.is_char() - || src.layout.ty.is_enum() - || src.layout.ty.is_integral() - || src.layout.ty.is_any_ptr(), - "Unexpected cast from type {:?}", - src.layout.ty - ) - } + _ => assert!( + src.layout.ty.is_bool() + || src.layout.ty.is_char() + || src.layout.ty.is_enum() + || src.layout.ty.is_integral() + || src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", + src.layout.ty + ), } // Handle cast from a univariant (ZST) enum. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 3d590fb820359..206d3d156735e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -152,16 +152,10 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => { - throw_unsup!(DeadLocal) - } - LocalValue::Live(Operand::Indirect(mplace)) => { - Ok(Err(mplace)) - } + LocalValue::Dead => throw_unsup!(DeadLocal), + LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) - | ref mut local @ LocalValue::Uninitialized => { - Ok(Ok(local)) - } + | ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)), } } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3386254c93b75..0bcdf9ae3c1f2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -580,8 +580,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); Ok((layout.size, layout.align.abi)) } - Some(GlobalAlloc::Memory(alloc)) => - { + Some(GlobalAlloc::Memory(alloc)) => { // Need to duplicate the logic here, because the global allocations have // different associated types than the interpreter-local ones. Ok((alloc.size, alloc.align)) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 34a32daaab65f..d1c08da6cbee5 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -543,9 +543,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::ConstKind::Placeholder(..) => { bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) } - ty::ConstKind::Value(val_val) => { - val_val - } + ty::ConstKind::Value(val_val) => val_val, }; // Other cases need layout. let layout = from_known_layout(layout, || self.layout_of(val.ty))?; diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index d0fef08bb60c7..9f713dfd5e607 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -114,8 +114,7 @@ fn write_path(out: &mut String, path: &Vec) { ClosureVar(name) => write!(out, ".", name), TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), - Deref => - { + Deref => { // This does not match Rust syntax, but it is more readable for long paths -- and // some of the other items here also are not Rust syntax. Actually we can't // even use the usual syntax because we are just showing the projections, @@ -206,8 +205,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M ty::Adt(def, ..) if def.is_enum() => { // we might be projecting *to* a variant, or to a field *in*a variant. match layout.variants { - layout::Variants::Single { index } => - { + layout::Variants::Single { index } => { // Inside a variant PathElem::Field(def.variants[index].fields[field].ident.name) } From c781d15da32bf82977311af6f056ee2fc3506bda Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 6 Jan 2020 11:35:55 +0100 Subject: [PATCH 0414/1253] adjust Deref comment --- src/librustc_mir/interpret/validity.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 9f713dfd5e607..ec9ac52a87c3a 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -114,13 +114,11 @@ fn write_path(out: &mut String, path: &Vec) { ClosureVar(name) => write!(out, ".", name), TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), - Deref => { - // This does not match Rust syntax, but it is more readable for long paths -- and - // some of the other items here also are not Rust syntax. Actually we can't - // even use the usual syntax because we are just showing the projections, - // not the root. - write!(out, ".") - } + // `.` does not match Rust syntax, but it is more readable for long paths -- and + // some of the other items here also are not Rust syntax. Actually we can't + // even use the usual syntax because we are just showing the projections, + // not the root. + Deref => write!(out, "."), Tag => write!(out, "."), DynDowncast => write!(out, "."), } From 0f70daa9b06882d7fb684a60160e4949d2861136 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 13:29:00 +0300 Subject: [PATCH 0415/1253] resolve: Move privacy error reporting into a separate method Give named fields to `struct PrivacyError` Move `fn report_ambiguity_error` to `diagnostics.rs` --- src/librustc_resolve/diagnostics.rs | 153 +++++++++++++++++++++++++- src/librustc_resolve/imports.rs | 6 +- src/librustc_resolve/lib.rs | 162 ++-------------------------- 3 files changed, 166 insertions(+), 155 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 9742067975499..f83daa1636752 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; -use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; +use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::SourceMap; @@ -20,8 +20,9 @@ use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; use crate::path_names_to_string; -use crate::VisResolutionError; +use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; +use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment}; use rustc_error_codes::*; @@ -802,6 +803,154 @@ impl<'a> Resolver<'a> { } false } + + fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String { + let res = b.res(); + if b.span.is_dummy() { + let add_built_in = match b.res() { + // These already contain the "built-in" prefix or look bad with it. + Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod => false, + _ => true, + }; + let (built_in, from) = if from_prelude { + ("", " from prelude") + } else if b.is_extern_crate() + && !b.is_import() + && self.session.opts.externs.get(&ident.as_str()).is_some() + { + ("", " passed with `--extern`") + } else if add_built_in { + (" built-in", "") + } else { + ("", "") + }; + + let article = if built_in.is_empty() { res.article() } else { "a" }; + format!( + "{a}{built_in} {thing}{from}", + a = article, + thing = res.descr(), + built_in = built_in, + from = from + ) + } else { + let introduced = if b.is_import() { "imported" } else { "defined" }; + format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) + } + } + + crate fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError<'_>) { + let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error; + let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { + // We have to print the span-less alternative first, otherwise formatting looks bad. + (b2, b1, misc2, misc1, true) + } else { + (b1, b2, misc1, misc2, false) + }; + + let mut err = struct_span_err!( + self.session, + ident.span, + E0659, + "`{ident}` is ambiguous ({why})", + ident = ident, + why = kind.descr() + ); + err.span_label(ident.span, "ambiguous name"); + + let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { + let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); + let note_msg = format!( + "`{ident}` could{also} refer to {what}", + ident = ident, + also = also, + what = what + ); + + let thing = b.res().descr(); + let mut help_msgs = Vec::new(); + if b.is_glob_import() + && (kind == AmbiguityKind::GlobVsGlob + || kind == AmbiguityKind::GlobVsExpanded + || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) + { + help_msgs.push(format!( + "consider adding an explicit import of \ + `{ident}` to disambiguate", + ident = ident + )) + } + if b.is_extern_crate() && ident.span.rust_2018() { + help_msgs.push(format!( + "use `::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } + if misc == AmbiguityErrorMisc::SuggestCrate { + help_msgs.push(format!( + "use `crate::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } else if misc == AmbiguityErrorMisc::SuggestSelf { + help_msgs.push(format!( + "use `self::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } + + err.span_note(b.span, ¬e_msg); + for (i, help_msg) in help_msgs.iter().enumerate() { + let or = if i == 0 { "" } else { "or " }; + err.help(&format!("{}{}", or, help_msg)); + } + }; + + could_refer_to(b1, misc1, ""); + could_refer_to(b2, misc2, " also"); + err.emit(); + } + + crate fn report_privacy_error(&self, privacy_error: &PrivacyError<'_>) { + let PrivacyError { ident, binding, .. } = *privacy_error; + let session = &self.session; + let mk_struct_span_error = |is_constructor| { + struct_span_err!( + session, + ident.span, + E0603, + "{}{} `{}` is private", + binding.res().descr(), + if is_constructor { " constructor" } else { "" }, + ident.name, + ) + }; + + let mut err = if let NameBindingKind::Res( + Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), + _, + ) = binding.kind + { + let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); + if let Some(fields) = self.field_names.get(&def_id) { + let mut err = mk_struct_span_error(true); + let first_field = fields.first().expect("empty field list in the map"); + err.span_label( + fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), + "a constructor is private if any of the fields is private", + ); + err + } else { + mk_struct_span_error(false) + } + } else { + mk_struct_span_error(false) + }; + + err.emit(); + } } impl<'a, 'b> ImportResolver<'a, 'b> { diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 5bd10303162b2..9f459834175c1 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -319,7 +319,11 @@ impl<'a> Resolver<'a> { // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE` !(self.last_import_segment && binding.is_extern_crate()) { - self.privacy_errors.push(PrivacyError(path_span, ident, binding)); + self.privacy_errors.push(PrivacyError { + ident, + binding, + dedup_span: path_span, + }); } Ok(binding) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8d5afb194a175..60a0049f5da37 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2,12 +2,9 @@ //! //! Module structure of the crate is built here. //! Paths in macros, imports, expressions, types, patterns are resolved here. -//! Label names are resolved here as well. +//! Label and lifetime names are resolved here as well. //! //! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`. -//! Lifetime names are resolved in `librustc/middle/resolve_lifetime.rs`. - -// ignore-tidy-filelength #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] @@ -33,7 +30,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_expand::base::SyntaxExtension; use rustc_hir::def::Namespace::*; -use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; +use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::{GlobMap, TraitMap}; @@ -604,7 +601,11 @@ impl<'a> NameBindingKind<'a> { } } -struct PrivacyError<'a>(Span, Ident, &'a NameBinding<'a>); +struct PrivacyError<'a> { + ident: Ident, + binding: &'a NameBinding<'a>, + dedup_span: Span, +} struct UseError<'a> { err: DiagnosticBuilder<'a>, @@ -2446,115 +2447,6 @@ impl<'a> Resolver<'a> { } } - fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String { - let res = b.res(); - if b.span.is_dummy() { - let add_built_in = match b.res() { - // These already contain the "built-in" prefix or look bad with it. - Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod => false, - _ => true, - }; - let (built_in, from) = if from_prelude { - ("", " from prelude") - } else if b.is_extern_crate() - && !b.is_import() - && self.session.opts.externs.get(&ident.as_str()).is_some() - { - ("", " passed with `--extern`") - } else if add_built_in { - (" built-in", "") - } else { - ("", "") - }; - - let article = if built_in.is_empty() { res.article() } else { "a" }; - format!( - "{a}{built_in} {thing}{from}", - a = article, - thing = res.descr(), - built_in = built_in, - from = from - ) - } else { - let introduced = if b.is_import() { "imported" } else { "defined" }; - format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) - } - } - - fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError<'_>) { - let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error; - let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { - // We have to print the span-less alternative first, otherwise formatting looks bad. - (b2, b1, misc2, misc1, true) - } else { - (b1, b2, misc1, misc2, false) - }; - - let mut err = struct_span_err!( - self.session, - ident.span, - E0659, - "`{ident}` is ambiguous ({why})", - ident = ident, - why = kind.descr() - ); - err.span_label(ident.span, "ambiguous name"); - - let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { - let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); - let note_msg = format!( - "`{ident}` could{also} refer to {what}", - ident = ident, - also = also, - what = what - ); - - let thing = b.res().descr(); - let mut help_msgs = Vec::new(); - if b.is_glob_import() - && (kind == AmbiguityKind::GlobVsGlob - || kind == AmbiguityKind::GlobVsExpanded - || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) - { - help_msgs.push(format!( - "consider adding an explicit import of \ - `{ident}` to disambiguate", - ident = ident - )) - } - if b.is_extern_crate() && ident.span.rust_2018() { - help_msgs.push(format!( - "use `::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } - if misc == AmbiguityErrorMisc::SuggestCrate { - help_msgs.push(format!( - "use `crate::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } else if misc == AmbiguityErrorMisc::SuggestSelf { - help_msgs.push(format!( - "use `self::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } - - err.span_note(b.span, ¬e_msg); - for (i, help_msg) in help_msgs.iter().enumerate() { - let or = if i == 0 { "" } else { "or " }; - err.help(&format!("{}{}", or, help_msg)); - } - }; - - could_refer_to(b1, misc1, ""); - could_refer_to(b2, misc2, " also"); - err.emit(); - } - fn report_errors(&mut self, krate: &Crate) { self.report_with_use_injections(krate); @@ -2575,43 +2467,9 @@ impl<'a> Resolver<'a> { } let mut reported_spans = FxHashSet::default(); - for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors { - if reported_spans.insert(dedup_span) { - let session = &self.session; - let mk_struct_span_error = |is_constructor| { - struct_span_err!( - session, - ident.span, - E0603, - "{}{} `{}` is private", - binding.res().descr(), - if is_constructor { " constructor" } else { "" }, - ident.name, - ) - }; - - let mut err = if let NameBindingKind::Res( - Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), - _, - ) = binding.kind - { - let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); - if let Some(fields) = self.field_names.get(&def_id) { - let mut err = mk_struct_span_error(true); - let first_field = fields.first().expect("empty field list in the map"); - err.span_label( - fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), - "a constructor is private if any of the fields is private", - ); - err - } else { - mk_struct_span_error(false) - } - } else { - mk_struct_span_error(false) - }; - - err.emit(); + for error in &self.privacy_errors { + if reported_spans.insert(error.dedup_span) { + self.report_privacy_error(error); } } } From 28c3f6eb409596be9c0c0a59dc1c26e216d9e57a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 16:04:03 +0300 Subject: [PATCH 0416/1253] resolve: Point at the private item definitions in privacy errors --- src/librustc_resolve/diagnostics.rs | 24 +- src/test/ui/error-codes/E0603.stderr | 8 +- src/test/ui/error-festival.stderr | 8 +- src/test/ui/export-import.stderr | 8 +- src/test/ui/export-tag-variant.stderr | 8 +- src/test/ui/export.stderr | 8 +- .../ui/extern/extern-crate-visibility.stderr | 16 +- src/test/ui/hygiene/privacy.stderr | 8 +- src/test/ui/import.stderr | 8 +- src/test/ui/imports/issue-55884-2.stderr | 8 +- src/test/ui/imports/reexports.stderr | 16 +- .../ui/imports/unresolved-imports-used.stderr | 8 +- src/test/ui/issues/issue-10545.stderr | 8 +- src/test/ui/issues/issue-11593.stderr | 8 +- src/test/ui/issues/issue-11680.stderr | 16 +- src/test/ui/issues/issue-13407.stderr | 8 +- src/test/ui/issues/issue-13641.stderr | 16 +- src/test/ui/issues/issue-16725.stderr | 8 +- .../issues/issue-17718-const-privacy.stderr | 16 +- src/test/ui/issues/issue-28388-2.stderr | 8 +- src/test/ui/issues/issue-29161.stderr | 8 +- src/test/ui/issues/issue-38857.stderr | 8 +- src/test/ui/issues/issue-3993.stderr | 8 +- .../macros/macro-local-data-key-priv.stderr | 9 +- .../ui/parser/macro/pub-item-macro.stderr | 11 +- src/test/ui/privacy/decl-macro.stderr | 8 +- src/test/ui/privacy/privacy-in-paths.stderr | 24 +- src/test/ui/privacy/privacy-ns2.stderr | 24 +- src/test/ui/privacy/privacy-ufcs.stderr | 8 +- src/test/ui/privacy/privacy1.stderr | 104 ++++- src/test/ui/privacy/privacy2.stderr | 8 +- src/test/ui/privacy/privacy4.stderr | 8 +- src/test/ui/privacy/privacy5.stderr | 384 +++++++++++++++--- .../ui/privacy/private-item-simple.stderr | 8 +- src/test/ui/privacy/restricted/test.stderr | 16 +- .../proc-macro/disappearing-resolution.stderr | 8 +- .../ui/reachable/unreachable-variant.stderr | 8 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 32 +- .../ui/resolve/privacy-struct-ctor.stderr | 48 ++- .../ui/rfc-2008-non-exhaustive/struct.stderr | 16 +- .../ui/rfc-2008-non-exhaustive/variant.stderr | 40 +- .../shadowed/shadowed-use-visibility.stderr | 16 +- .../ui/stability-in-private-module.stderr | 8 +- .../ui/static/static-priv-by-default2.stderr | 16 +- .../structs/struct-variant-privacy-xc.stderr | 16 +- .../ui/structs/struct-variant-privacy.stderr | 16 +- src/test/ui/use/use-from-trait-xc.stderr | 16 +- src/test/ui/use/use-mod/use-mod-3.stderr | 16 +- .../xcrate/xcrate-private-by-default.stderr | 80 +++- 49 files changed, 1034 insertions(+), 154 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index f83daa1636752..20c8f78b1cf0e 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -917,15 +917,21 @@ impl<'a> Resolver<'a> { let PrivacyError { ident, binding, .. } = *privacy_error; let session = &self.session; let mk_struct_span_error = |is_constructor| { - struct_span_err!( - session, - ident.span, - E0603, - "{}{} `{}` is private", - binding.res().descr(), - if is_constructor { " constructor" } else { "" }, - ident.name, - ) + let mut descr = binding.res().descr().to_string(); + if is_constructor { + descr += " constructor"; + } + + let mut err = + struct_span_err!(session, ident.span, E0603, "{} `{}` is private", descr, ident); + + err.span_label(ident.span, &format!("this {} is private", descr)); + err.span_note( + session.source_map().def_span(binding.span), + &format!("the {} `{}` is defined here", descr, ident), + ); + + err }; let mut err = if let NameBindingKind::Res( diff --git a/src/test/ui/error-codes/E0603.stderr b/src/test/ui/error-codes/E0603.stderr index 444005e086f1b..724d04954a3c7 100644 --- a/src/test/ui/error-codes/E0603.stderr +++ b/src/test/ui/error-codes/E0603.stderr @@ -2,7 +2,13 @@ error[E0603]: constant `PRIVATE` is private --> $DIR/E0603.rs:6:17 | LL | SomeModule::PRIVATE; - | ^^^^^^^ + | ^^^^^^^ this constant is private + | +note: the constant `PRIVATE` is defined here + --> $DIR/E0603.rs:2:5 + | +LL | const PRIVATE: u32 = 0x_a_bad_1dea_u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 6b80d99b3afe9..9b69b3733642b 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -8,7 +8,13 @@ error[E0603]: constant `FOO` is private --> $DIR/error-festival.rs:22:10 | LL | foo::FOO; - | ^^^ + | ^^^ this constant is private + | +note: the constant `FOO` is defined here + --> $DIR/error-festival.rs:7:5 + | +LL | const FOO: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^ error[E0368]: binary assignment operation `+=` cannot be applied to type `&str` --> $DIR/error-festival.rs:12:5 diff --git a/src/test/ui/export-import.stderr b/src/test/ui/export-import.stderr index e02952e0fe092..8160775ab589e 100644 --- a/src/test/ui/export-import.stderr +++ b/src/test/ui/export-import.stderr @@ -2,7 +2,13 @@ error[E0603]: function `unexported` is private --> $DIR/export-import.rs:1:8 | LL | use m::unexported; - | ^^^^^^^^^^ + | ^^^^^^^^^^ this function is private + | +note: the function `unexported` is defined here + --> $DIR/export-import.rs:7:5 + | +LL | fn unexported() { } + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/export-tag-variant.stderr b/src/test/ui/export-tag-variant.stderr index b5a2c12c436d0..f4537a2fb6fae 100644 --- a/src/test/ui/export-tag-variant.stderr +++ b/src/test/ui/export-tag-variant.stderr @@ -2,7 +2,13 @@ error[E0603]: enum `Y` is private --> $DIR/export-tag-variant.rs:7:26 | LL | fn main() { let z = foo::Y::Y1; } - | ^ + | ^ this enum is private + | +note: the enum `Y` is defined here + --> $DIR/export-tag-variant.rs:4:5 + | +LL | enum Y { Y1 } + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/export.stderr b/src/test/ui/export.stderr index a3668a502cdd4..107f531c09a3a 100644 --- a/src/test/ui/export.stderr +++ b/src/test/ui/export.stderr @@ -26,7 +26,13 @@ error[E0603]: function `z` is private --> $DIR/export.rs:10:18 | LL | fn main() { foo::z(10); } - | ^ + | ^ this function is private + | +note: the function `z` is defined here + --> $DIR/export.rs:5:5 + | +LL | fn z(y: isize) { log(debug, y); } + | ^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/extern/extern-crate-visibility.stderr b/src/test/ui/extern/extern-crate-visibility.stderr index 38c791ab83237..6d38b4d8d66d6 100644 --- a/src/test/ui/extern/extern-crate-visibility.stderr +++ b/src/test/ui/extern/extern-crate-visibility.stderr @@ -2,13 +2,25 @@ error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:6:10 | LL | use foo::core::cell; - | ^^^^ + | ^^^^ this crate is private + | +note: the crate `core` is defined here + --> $DIR/extern-crate-visibility.rs:2:5 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:9:10 | LL | foo::core::cell::Cell::new(0); - | ^^^^ + | ^^^^ this crate is private + | +note: the crate `core` is defined here + --> $DIR/extern-crate-visibility.rs:2:5 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/hygiene/privacy.stderr b/src/test/ui/hygiene/privacy.stderr index 80fb4dd0f314a..0649dc0ec5836 100644 --- a/src/test/ui/hygiene/privacy.stderr +++ b/src/test/ui/hygiene/privacy.stderr @@ -2,7 +2,13 @@ error[E0603]: function `f` is private --> $DIR/privacy.rs:16:14 | LL | foo::f() - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/privacy.rs:4:5 + | +LL | fn f() {} + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/import.stderr b/src/test/ui/import.stderr index 6b320b198a0b1..c66a4fa7151dc 100644 --- a/src/test/ui/import.stderr +++ b/src/test/ui/import.stderr @@ -17,7 +17,13 @@ error[E0603]: unresolved item `foo` is private --> $DIR/import.rs:15:10 | LL | zed::foo(); - | ^^^ + | ^^^ this unresolved item is private + | +note: the unresolved item `foo` is defined here + --> $DIR/import.rs:10:9 + | +LL | use foo; + | ^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/imports/issue-55884-2.stderr b/src/test/ui/imports/issue-55884-2.stderr index d3b43783ee9c8..9e77283cd5946 100644 --- a/src/test/ui/imports/issue-55884-2.stderr +++ b/src/test/ui/imports/issue-55884-2.stderr @@ -2,7 +2,13 @@ error[E0603]: struct `ParseOptions` is private --> $DIR/issue-55884-2.rs:12:17 | LL | pub use parser::ParseOptions; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this struct is private + | +note: the struct `ParseOptions` is defined here + --> $DIR/issue-55884-2.rs:9:9 + | +LL | use ParseOptions; + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/imports/reexports.stderr b/src/test/ui/imports/reexports.stderr index 4388e2c276b8e..67c12e0c8d3ca 100644 --- a/src/test/ui/imports/reexports.stderr +++ b/src/test/ui/imports/reexports.stderr @@ -14,13 +14,25 @@ error[E0603]: module `foo` is private --> $DIR/reexports.rs:33:15 | LL | use b::a::foo::S; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/reexports.rs:21:17 + | +LL | pub use super::foo; // This is OK since the value `foo` is visible enough. + | ^^^^^^^^^^ error[E0603]: module `foo` is private --> $DIR/reexports.rs:34:15 | LL | use b::b::foo::S as T; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/reexports.rs:26:17 + | +LL | pub use super::*; // This is also OK since the value `foo` is visible enough. + | ^^^^^^^^ warning: glob import doesn't reexport anything because no candidate is public enough --> $DIR/reexports.rs:9:17 diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr index b341e8e059288..d7280d2583a76 100644 --- a/src/test/ui/imports/unresolved-imports-used.stderr +++ b/src/test/ui/imports/unresolved-imports-used.stderr @@ -38,7 +38,13 @@ error[E0603]: function `quz` is private --> $DIR/unresolved-imports-used.rs:9:10 | LL | use qux::quz; - | ^^^ + | ^^^ this function is private + | +note: the function `quz` is defined here + --> $DIR/unresolved-imports-used.rs:5:4 + | +LL | fn quz() {} + | ^^^^^^^^ error: unused import: `qux::quy` --> $DIR/unresolved-imports-used.rs:16:5 diff --git a/src/test/ui/issues/issue-10545.stderr b/src/test/ui/issues/issue-10545.stderr index 59d4fedcd2b40..4ed7028c0a06b 100644 --- a/src/test/ui/issues/issue-10545.stderr +++ b/src/test/ui/issues/issue-10545.stderr @@ -2,7 +2,13 @@ error[E0603]: struct `S` is private --> $DIR/issue-10545.rs:6:14 | LL | fn foo(_: a::S) { - | ^ + | ^ this struct is private + | +note: the struct `S` is defined here + --> $DIR/issue-10545.rs:2:5 + | +LL | struct S; + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11593.stderr b/src/test/ui/issues/issue-11593.stderr index c3e4412b042d7..bfb4d31323b13 100644 --- a/src/test/ui/issues/issue-11593.stderr +++ b/src/test/ui/issues/issue-11593.stderr @@ -2,7 +2,13 @@ error[E0603]: trait `Foo` is private --> $DIR/issue-11593.rs:7:24 | LL | impl private_trait_xc::Foo for Bar {} - | ^^^ + | ^^^ this trait is private + | +note: the trait `Foo` is defined here + --> $DIR/auxiliary/private-trait-xc.rs:1:1 + | +LL | trait Foo {} + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11680.stderr b/src/test/ui/issues/issue-11680.stderr index 35cb2476992ac..898ac10f7d9a9 100644 --- a/src/test/ui/issues/issue-11680.stderr +++ b/src/test/ui/issues/issue-11680.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Foo` is private --> $DIR/issue-11680.rs:6:21 | LL | let _b = other::Foo::Bar(1); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/issue-11680.rs:1:1 + | +LL | enum Foo { + | ^^^^^^^^ error[E0603]: enum `Foo` is private --> $DIR/issue-11680.rs:9:27 | LL | let _b = other::test::Foo::Bar(1); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/issue-11680.rs:6:5 + | +LL | enum Foo { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-13407.stderr b/src/test/ui/issues/issue-13407.stderr index b280de3158fed..f211d623ab12b 100644 --- a/src/test/ui/issues/issue-13407.stderr +++ b/src/test/ui/issues/issue-13407.stderr @@ -2,7 +2,13 @@ error[E0603]: unit struct `C` is private --> $DIR/issue-13407.rs:6:8 | LL | A::C = 1; - | ^ + | ^ this unit struct is private + | +note: the unit struct `C` is defined here + --> $DIR/issue-13407.rs:2:5 + | +LL | struct C; + | ^^^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-13407.rs:6:12 diff --git a/src/test/ui/issues/issue-13641.stderr b/src/test/ui/issues/issue-13641.stderr index 8e5001e3b694d..f90cb18b6fc9d 100644 --- a/src/test/ui/issues/issue-13641.stderr +++ b/src/test/ui/issues/issue-13641.stderr @@ -2,13 +2,25 @@ error[E0603]: struct `Foo` is private --> $DIR/issue-13641.rs:9:8 | LL | a::Foo::new(); - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/issue-13641.rs:2:5 + | +LL | struct Foo; + | ^^^^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/issue-13641.rs:11:8 | LL | a::Bar::new(); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/issue-13641.rs:4:5 + | +LL | enum Bar {} + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-16725.stderr b/src/test/ui/issues/issue-16725.stderr index 562ad940423c2..e0a1ca8a5ac31 100644 --- a/src/test/ui/issues/issue-16725.stderr +++ b/src/test/ui/issues/issue-16725.stderr @@ -2,7 +2,13 @@ error[E0603]: function `bar` is private --> $DIR/issue-16725.rs:6:19 | LL | unsafe { foo::bar(); } - | ^^^ + | ^^^ this function is private + | +note: the function `bar` is defined here + --> $DIR/auxiliary/issue-16725.rs:2:5 + | +LL | fn bar(); + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17718-const-privacy.stderr b/src/test/ui/issues/issue-17718-const-privacy.stderr index 0b0de8a52590b..07d825ba9cb3b 100644 --- a/src/test/ui/issues/issue-17718-const-privacy.stderr +++ b/src/test/ui/issues/issue-17718-const-privacy.stderr @@ -2,13 +2,25 @@ error[E0603]: constant `B` is private --> $DIR/issue-17718-const-privacy.rs:5:8 | LL | use a::B; - | ^ + | ^ this constant is private + | +note: the constant `B` is defined here + --> $DIR/issue-17718-const-privacy.rs:13:5 + | +LL | const B: usize = 3; + | ^^^^^^^^^^^^^^^^^^^ error[E0603]: constant `BAR` is private --> $DIR/issue-17718-const-privacy.rs:8:5 | LL | BAR, - | ^^^ + | ^^^ this constant is private + | +note: the constant `BAR` is defined here + --> $DIR/auxiliary/issue-17718-const-privacy.rs:4:1 + | +LL | const BAR: usize = 3; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-28388-2.stderr b/src/test/ui/issues/issue-28388-2.stderr index 7bbe0bc5ff154..58bd775f295fc 100644 --- a/src/test/ui/issues/issue-28388-2.stderr +++ b/src/test/ui/issues/issue-28388-2.stderr @@ -2,7 +2,13 @@ error[E0603]: module `n` is private --> $DIR/issue-28388-2.rs:7:8 | LL | use m::n::{}; - | ^ + | ^ this module is private + | +note: the module `n` is defined here + --> $DIR/issue-28388-2.rs:4:5 + | +LL | mod n {} + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29161.stderr b/src/test/ui/issues/issue-29161.stderr index d30fd28a4a351..1bfa211ef7962 100644 --- a/src/test/ui/issues/issue-29161.stderr +++ b/src/test/ui/issues/issue-29161.stderr @@ -8,7 +8,13 @@ error[E0603]: struct `A` is private --> $DIR/issue-29161.rs:13:8 | LL | a::A::default(); - | ^ + | ^ this struct is private + | +note: the struct `A` is defined here + --> $DIR/issue-29161.rs:2:5 + | +LL | struct A; + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr index 5762e3d6ac00a..dd7970e014fdb 100644 --- a/src/test/ui/issues/issue-38857.stderr +++ b/src/test/ui/issues/issue-38857.stderr @@ -8,7 +8,13 @@ error[E0603]: module `sys` is private --> $DIR/issue-38857.rs:2:18 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; - | ^^^ + | ^^^ this module is private + | +note: the module `sys` is defined here + --> $SRC_DIR/libstd/lib.rs:LL:COL + | +LL | mod sys; + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-3993.stderr b/src/test/ui/issues/issue-3993.stderr index ce594a3f9bb27..3fa8ed4af28fa 100644 --- a/src/test/ui/issues/issue-3993.stderr +++ b/src/test/ui/issues/issue-3993.stderr @@ -2,7 +2,13 @@ error[E0603]: function `fly` is private --> $DIR/issue-3993.rs:1:10 | LL | use zoo::fly; - | ^^^ + | ^^^ this function is private + | +note: the function `fly` is defined here + --> $DIR/issue-3993.rs:4:5 + | +LL | fn fly() {} + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/macros/macro-local-data-key-priv.stderr b/src/test/ui/macros/macro-local-data-key-priv.stderr index 9b44421808e88..72994d1652cd0 100644 --- a/src/test/ui/macros/macro-local-data-key-priv.stderr +++ b/src/test/ui/macros/macro-local-data-key-priv.stderr @@ -2,7 +2,14 @@ error[E0603]: constant `baz` is private --> $DIR/macro-local-data-key-priv.rs:8:10 | LL | bar::baz.with(|_| ()); - | ^^^ + | ^^^ this constant is private + | +note: the constant `baz` is defined here + --> $DIR/macro-local-data-key-priv.rs:4:5 + | +LL | thread_local!(static baz: f64 = 0.0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/macro/pub-item-macro.stderr b/src/test/ui/parser/macro/pub-item-macro.stderr index fa25161ab50b2..ae981ac4cbee3 100644 --- a/src/test/ui/parser/macro/pub-item-macro.stderr +++ b/src/test/ui/parser/macro/pub-item-macro.stderr @@ -13,7 +13,16 @@ error[E0603]: static `x` is private --> $DIR/pub-item-macro.rs:17:23 | LL | let y: u32 = foo::x; - | ^ + | ^ this static is private + | +note: the static `x` is defined here + --> $DIR/pub-item-macro.rs:4:5 + | +LL | static x: u32 = 0; + | ^^^^^^^^^^^^^^^^^^ +... +LL | pub_x!(); + | --------- in this macro invocation error: aborting due to 2 previous errors diff --git a/src/test/ui/privacy/decl-macro.stderr b/src/test/ui/privacy/decl-macro.stderr index 230cf95de6206..ae2e1b4b644a3 100644 --- a/src/test/ui/privacy/decl-macro.stderr +++ b/src/test/ui/privacy/decl-macro.stderr @@ -2,7 +2,13 @@ error[E0603]: macro `mac` is private --> $DIR/decl-macro.rs:8:8 | LL | m::mac!(); - | ^^^ + | ^^^ this macro is private + | +note: the macro `mac` is defined here + --> $DIR/decl-macro.rs:4:5 + | +LL | macro mac() {} + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy-in-paths.stderr b/src/test/ui/privacy/privacy-in-paths.stderr index 4b9faca045709..8860d8f15f748 100644 --- a/src/test/ui/privacy/privacy-in-paths.stderr +++ b/src/test/ui/privacy/privacy-in-paths.stderr @@ -2,19 +2,37 @@ error[E0603]: module `bar` is private --> $DIR/privacy-in-paths.rs:24:16 | LL | ::foo::bar::baz::f(); - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/privacy-in-paths.rs:3:5 + | +LL | mod bar { + | ^^^^^^^ error[E0603]: module `bar` is private --> $DIR/privacy-in-paths.rs:25:16 | LL | ::foo::bar::S::f(); - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/privacy-in-paths.rs:3:5 + | +LL | mod bar { + | ^^^^^^^ error[E0603]: trait `T` is private --> $DIR/privacy-in-paths.rs:26:23 | LL | <() as ::foo::T>::Assoc::f(); - | ^ + | ^ this trait is private + | +note: the trait `T` is defined here + --> $DIR/privacy-in-paths.rs:8:5 + | +LL | trait T { + | ^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr index 2871573130a60..8b12109b37307 100644 --- a/src/test/ui/privacy/privacy-ns2.stderr +++ b/src/test/ui/privacy/privacy-ns2.stderr @@ -58,19 +58,37 @@ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:63:15 | LL | use foo3::Bar; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:67:15 | LL | use foo3::Bar; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:74:16 | LL | use foo3::{Bar,Baz}; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0107]: wrong number of const arguments: expected 0, found 1 --> $DIR/privacy-ns2.rs:41:18 diff --git a/src/test/ui/privacy/privacy-ufcs.stderr b/src/test/ui/privacy/privacy-ufcs.stderr index 6be14df89d20a..08640b802a244 100644 --- a/src/test/ui/privacy/privacy-ufcs.stderr +++ b/src/test/ui/privacy/privacy-ufcs.stderr @@ -2,7 +2,13 @@ error[E0603]: trait `Bar` is private --> $DIR/privacy-ufcs.rs:12:20 | LL | ::baz(); - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ufcs.rs:4:5 + | +LL | trait Bar { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy1.stderr b/src/test/ui/privacy/privacy1.stderr index 29f53cd0e3545..215df0dc75441 100644 --- a/src/test/ui/privacy/privacy1.stderr +++ b/src/test/ui/privacy/privacy1.stderr @@ -2,79 +2,157 @@ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:132:18 | LL | use bar::baz::{foo, bar}; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:132:18 | LL | use bar::baz::{foo, bar}; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:141:18 | LL | use bar::baz; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `i` is private --> $DIR/privacy1.rs:165:20 | LL | use self::foo::i::A; - | ^ + | ^ this module is private + | +note: the module `i` is defined here + --> $DIR/privacy1.rs:170:9 + | +LL | mod i { + | ^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:104:16 | LL | ::bar::baz::A::foo(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:105:16 | LL | ::bar::baz::A::bar(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:107:16 | LL | ::bar::baz::A.foo2(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:108:16 | LL | ::bar::baz::A.bar2(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: trait `B` is private --> $DIR/privacy1.rs:112:16 | LL | ::bar::B::foo(); - | ^ + | ^ this trait is private + | +note: the trait `B` is defined here + --> $DIR/privacy1.rs:40:5 + | +LL | trait B { + | ^^^^^^^ error[E0603]: function `epriv` is private --> $DIR/privacy1.rs:118:20 | LL | ::bar::epriv(); - | ^^^^^ + | ^^^^^ this function is private + | +note: the function `epriv` is defined here + --> $DIR/privacy1.rs:65:9 + | +LL | fn epriv(); + | ^^^^^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:127:16 | LL | ::bar::baz::foo(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:128:16 | LL | ::bar::baz::bar(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: trait `B` is private --> $DIR/privacy1.rs:157:17 | LL | impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } - | ^ + | ^ this trait is private + | +note: the trait `B` is defined here + --> $DIR/privacy1.rs:40:5 + | +LL | trait B { + | ^^^^^^^ error[E0624]: method `bar` is private --> $DIR/privacy1.rs:77:9 diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr index 9f2359657bd7c..d9f003ddae7ac 100644 --- a/src/test/ui/privacy/privacy2.stderr +++ b/src/test/ui/privacy/privacy2.stderr @@ -8,7 +8,13 @@ error[E0603]: function `foo` is private --> $DIR/privacy2.rs:23:20 | LL | use bar::glob::foo; - | ^^^ + | ^^^ this function is private + | +note: the function `foo` is defined here + --> $DIR/privacy2.rs:10:13 + | +LL | use foo; + | ^^^ error: requires `sized` lang_item diff --git a/src/test/ui/privacy/privacy4.stderr b/src/test/ui/privacy/privacy4.stderr index e4a20f920a062..e34b2d5049b9e 100644 --- a/src/test/ui/privacy/privacy4.stderr +++ b/src/test/ui/privacy/privacy4.stderr @@ -2,7 +2,13 @@ error[E0603]: module `glob` is private --> $DIR/privacy4.rs:21:14 | LL | use bar::glob::gpriv; - | ^^^^ + | ^^^^ this module is private + | +note: the module `glob` is defined here + --> $DIR/privacy4.rs:13:5 + | +LL | mod glob { + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy5.stderr b/src/test/ui/privacy/privacy5.stderr index 2ee83149b695f..197a857cc3dc4 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -5,7 +5,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a = a::A(()); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:52:16 @@ -14,7 +20,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let b = a::B(2); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:53:16 @@ -23,7 +35,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let c = a::C(2, 3); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:56:12 @@ -32,7 +50,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a::A(()) = a; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:57:12 @@ -41,7 +65,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a::A(_) = a; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:58:18 @@ -50,7 +80,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | match a { a::A(()) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:59:18 @@ -59,7 +95,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | match a { a::A(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:61:12 @@ -68,7 +110,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let a::B(_) = b; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:62:12 @@ -77,7 +125,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let a::B(_b) = b; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:63:18 @@ -86,7 +140,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:64:18 @@ -95,7 +155,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:18 @@ -104,7 +170,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:32 @@ -113,7 +185,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:68:12 @@ -122,7 +200,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:69:12 @@ -131,7 +215,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:70:12 @@ -140,7 +230,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _b) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:71:12 @@ -149,7 +245,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _b) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:72:18 @@ -158,7 +260,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:73:18 @@ -167,7 +275,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:74:18 @@ -176,7 +290,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:75:18 @@ -185,7 +305,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:83:17 @@ -194,7 +320,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a2 = a::A; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:84:17 @@ -203,7 +335,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let b2 = a::B; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:85:17 @@ -212,271 +350,421 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let c2 = a::C; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:90:20 | LL | let a = other::A(()); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:91:20 | LL | let b = other::B(2); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:92:20 | LL | let c = other::C(2, 3); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:95:16 | LL | let other::A(()) = a; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:96:16 | LL | let other::A(_) = a; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:97:22 | LL | match a { other::A(()) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:98:22 | LL | match a { other::A(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:100:16 | LL | let other::B(_) = b; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:101:16 | LL | let other::B(_b) = b; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:102:22 | LL | match b { other::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:103:22 | LL | match b { other::B(_b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:104:22 | LL | match b { other::B(1) => {} - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:105:16 | LL | other::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:107:16 | LL | let other::C(_, _) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:108:16 | LL | let other::C(_a, _) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:109:16 | LL | let other::C(_, _b) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:110:16 | LL | let other::C(_a, _b) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:111:22 | LL | match c { other::C(_, _) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:112:22 | LL | match c { other::C(_a, _) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:113:22 | LL | match c { other::C(_, _b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:114:22 | LL | match c { other::C(_a, _b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:122:21 | LL | let a2 = other::A; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:123:21 | LL | let b2 = other::B; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:124:21 | LL | let c2 = other::C; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 48 previous errors diff --git a/src/test/ui/privacy/private-item-simple.stderr b/src/test/ui/privacy/private-item-simple.stderr index 0d5435e1c504b..f51b74f6cb53b 100644 --- a/src/test/ui/privacy/private-item-simple.stderr +++ b/src/test/ui/privacy/private-item-simple.stderr @@ -2,7 +2,13 @@ error[E0603]: function `f` is private --> $DIR/private-item-simple.rs:6:8 | LL | a::f(); - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/private-item-simple.rs:2:5 + | +LL | fn f() {} + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr index e6a61fbefb0d8..aac444b8e3c98 100644 --- a/src/test/ui/privacy/restricted/test.stderr +++ b/src/test/ui/privacy/restricted/test.stderr @@ -26,13 +26,25 @@ error[E0603]: struct `Crate` is private --> $DIR/test.rs:38:25 | LL | use pub_restricted::Crate; - | ^^^^^ + | ^^^^^ this struct is private + | +note: the struct `Crate` is defined here + --> $DIR/auxiliary/pub_restricted.rs:3:1 + | +LL | pub(crate) struct Crate; + | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: function `f` is private --> $DIR/test.rs:30:19 | LL | use foo::bar::f; - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/test.rs:8:9 + | +LL | pub(super) fn f() {} + | ^^^^^^^^^^^^^^^^^ error[E0616]: field `x` of struct `foo::bar::S` is private --> $DIR/test.rs:31:5 diff --git a/src/test/ui/proc-macro/disappearing-resolution.stderr b/src/test/ui/proc-macro/disappearing-resolution.stderr index a3377ef515f91..d81ab5ebf9bc6 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.stderr +++ b/src/test/ui/proc-macro/disappearing-resolution.stderr @@ -8,7 +8,13 @@ error[E0603]: derive macro `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 | LL | use m::Empty; - | ^^^^^ + | ^^^^^ this derive macro is private + | +note: the derive macro `Empty` is defined here + --> $DIR/disappearing-resolution.rs:9:9 + | +LL | use test_macros::Empty; + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/unreachable-variant.stderr b/src/test/ui/reachable/unreachable-variant.stderr index 276c77f9b4249..c2e1d774e28ac 100644 --- a/src/test/ui/reachable/unreachable-variant.stderr +++ b/src/test/ui/reachable/unreachable-variant.stderr @@ -2,7 +2,13 @@ error[E0603]: module `super_sekrit` is private --> $DIR/unreachable-variant.rs:6:21 | LL | let _x = other::super_sekrit::sooper_sekrit::baz; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this module is private + | +note: the module `super_sekrit` is defined here + --> $DIR/auxiliary/unreachable_variant.rs:1:1 + | +LL | mod super_sekrit { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 688720e8cd388..08a1d790197a6 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -253,25 +253,49 @@ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:57:22 | LL | let _: Z = m::n::Z; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:61:22 | LL | let _: Z = m::n::Z::Fn; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:64:22 | LL | let _: Z = m::n::Z::Struct; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:68:22 | LL | let _: Z = m::n::Z::Unit {}; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/privacy-enum-ctor.rs:27:20 diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index f1a1de4d9c0fd..1673ec46ba488 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -45,7 +45,13 @@ LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private ... LL | n::Z; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/privacy-struct-ctor.rs:12:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 @@ -54,7 +60,13 @@ LL | pub struct S(u8); | -- a constructor is private if any of the fields is private ... LL | m::S; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/privacy-struct-ctor.rs:6:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 @@ -63,7 +75,13 @@ LL | pub struct S(u8); | -- a constructor is private if any of the fields is private ... LL | let _: S = m::S(2); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/privacy-struct-ctor.rs:6:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 @@ -72,29 +90,47 @@ LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private ... LL | m::n::Z; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/privacy-struct-ctor.rs:12:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 | LL | xcrate::m::S; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy-struct-ctor.rs:2:18 | LL | pub struct S(u8); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/auxiliary/privacy-struct-ctor.rs:2:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:45:19 | LL | xcrate::m::n::Z; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy-struct-ctor.rs:5:28 | LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/auxiliary/privacy-struct-ctor.rs:5:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 10 previous errors diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr index 944965a15e3d0..f992988c93fcc 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -14,18 +14,30 @@ error[E0603]: tuple struct constructor `TupleStruct` is private --> $DIR/struct.rs:23:32 | LL | let ts_explicit = structs::TupleStruct(640, 480); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this tuple struct constructor is private | ::: $DIR/auxiliary/structs.rs:11:24 | LL | pub struct TupleStruct(pub u16, pub u16); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `TupleStruct` is defined here + --> $DIR/auxiliary/structs.rs:11:1 + | +LL | pub struct TupleStruct(pub u16, pub u16); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: unit struct `UnitStruct` is private --> $DIR/struct.rs:32:32 | LL | let us_explicit = structs::UnitStruct; - | ^^^^^^^^^^ + | ^^^^^^^^^^ this unit struct is private + | +note: the unit struct `UnitStruct` is defined here + --> $DIR/auxiliary/structs.rs:8:1 + | +LL | pub struct UnitStruct; + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0639]: cannot create non-exhaustive struct using struct expression --> $DIR/struct.rs:7:14 diff --git a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr index d9d6ea21b8bd4..2a438753a2c70 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr @@ -2,31 +2,61 @@ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:11:48 | LL | let variant_tuple = NonExhaustiveVariants::Tuple(640); - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:14:47 | LL | let variant_unit = NonExhaustiveVariants::Unit; - | ^^^^ + | ^^^^ this unit variant is private + | +note: the unit variant `Unit` is defined here + --> $DIR/auxiliary/variants.rs:4:23 + | +LL | #[non_exhaustive] Unit, + | ^^^^ error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:18:32 | LL | NonExhaustiveVariants::Unit => "", - | ^^^^ + | ^^^^ this unit variant is private + | +note: the unit variant `Unit` is defined here + --> $DIR/auxiliary/variants.rs:4:23 + | +LL | #[non_exhaustive] Unit, + | ^^^^ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:20:32 | LL | NonExhaustiveVariants::Tuple(fe_tpl) => "", - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:26:35 | LL | if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct { - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0639]: cannot create non-exhaustive variant using struct expression --> $DIR/variant.rs:8:26 diff --git a/src/test/ui/shadowed/shadowed-use-visibility.stderr b/src/test/ui/shadowed/shadowed-use-visibility.stderr index 7c66fdf60b1d4..77bf2abe34555 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.stderr +++ b/src/test/ui/shadowed/shadowed-use-visibility.stderr @@ -2,13 +2,25 @@ error[E0603]: module `bar` is private --> $DIR/shadowed-use-visibility.rs:9:14 | LL | use foo::bar::f as g; - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/shadowed-use-visibility.rs:4:9 + | +LL | use foo as bar; + | ^^^^^^^^^^ error[E0603]: module `f` is private --> $DIR/shadowed-use-visibility.rs:15:10 | LL | use bar::f::f; - | ^ + | ^ this module is private + | +note: the module `f` is defined here + --> $DIR/shadowed-use-visibility.rs:11:9 + | +LL | use foo as f; + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr index c3edd62a15eda..537a400664aaa 100644 --- a/src/test/ui/stability-in-private-module.stderr +++ b/src/test/ui/stability-in-private-module.stderr @@ -2,7 +2,13 @@ error[E0603]: module `thread_info` is private --> $DIR/stability-in-private-module.rs:2:26 | LL | let _ = std::thread::thread_info::current_thread(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this module is private + | +note: the module `thread_info` is defined here + --> $SRC_DIR/libstd/thread/mod.rs:LL:COL + | +LL | use crate::sys_common::thread_info; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/static/static-priv-by-default2.stderr b/src/test/ui/static/static-priv-by-default2.stderr index 95bcf07633565..f6cd40412dd84 100644 --- a/src/test/ui/static/static-priv-by-default2.stderr +++ b/src/test/ui/static/static-priv-by-default2.stderr @@ -2,13 +2,25 @@ error[E0603]: static `private` is private --> $DIR/static-priv-by-default2.rs:15:30 | LL | use child::childs_child::private; - | ^^^^^^^ + | ^^^^^^^ this static is private + | +note: the static `private` is defined here + --> $DIR/static-priv-by-default2.rs:7:9 + | +LL | static private: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: static `private` is private --> $DIR/static-priv-by-default2.rs:23:33 | LL | use static_priv_by_default::private; - | ^^^^^^^ + | ^^^^^^^ this static is private + | +note: the static `private` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:3:1 + | +LL | static private: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-variant-privacy-xc.stderr b/src/test/ui/structs/struct-variant-privacy-xc.stderr index 39241b6b3fc1d..0203b7b5242e5 100644 --- a/src/test/ui/structs/struct-variant-privacy-xc.stderr +++ b/src/test/ui/structs/struct-variant-privacy-xc.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy-xc.rs:4:33 | LL | fn f(b: struct_variant_privacy::Bar) { - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/auxiliary/struct_variant_privacy.rs:1:1 + | +LL | enum Bar { + | ^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy-xc.rs:6:33 | LL | struct_variant_privacy::Bar::Baz { a: _a } => {} - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/auxiliary/struct_variant_privacy.rs:1:1 + | +LL | enum Bar { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-variant-privacy.stderr b/src/test/ui/structs/struct-variant-privacy.stderr index 127a650104485..d1b603f9d46fc 100644 --- a/src/test/ui/structs/struct-variant-privacy.stderr +++ b/src/test/ui/structs/struct-variant-privacy.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy.rs:7:14 | LL | fn f(b: foo::Bar) { - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/struct-variant-privacy.rs:2:5 + | +LL | enum Bar { + | ^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy.rs:9:14 | LL | foo::Bar::Baz { a: _a } => {} - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/struct-variant-privacy.rs:2:5 + | +LL | enum Bar { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/use/use-from-trait-xc.stderr b/src/test/ui/use/use-from-trait-xc.stderr index f7438cce22967..3f38a6cae7b81 100644 --- a/src/test/ui/use/use-from-trait-xc.stderr +++ b/src/test/ui/use/use-from-trait-xc.stderr @@ -44,13 +44,25 @@ error[E0603]: struct `Foo` is private --> $DIR/use-from-trait-xc.rs:14:24 | LL | use use_from_trait_xc::Foo::new; - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/auxiliary/use-from-trait-xc.rs:9:1 + | +LL | struct Foo; + | ^^^^^^^^^^^ error[E0603]: struct `Foo` is private --> $DIR/use-from-trait-xc.rs:17:24 | LL | use use_from_trait_xc::Foo::C; - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/auxiliary/use-from-trait-xc.rs:9:1 + | +LL | struct Foo; + | ^^^^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/use/use-mod/use-mod-3.stderr b/src/test/ui/use/use-mod/use-mod-3.stderr index 0c800ec35e409..4852759286ae6 100644 --- a/src/test/ui/use/use-mod/use-mod-3.stderr +++ b/src/test/ui/use/use-mod/use-mod-3.stderr @@ -2,13 +2,25 @@ error[E0603]: module `bar` is private --> $DIR/use-mod-3.rs:1:10 | LL | use foo::bar::{ - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/use-mod-3.rs:9:5 + | +LL | mod bar { pub type Bar = isize; } + | ^^^^^^^ error[E0603]: module `bar` is private --> $DIR/use-mod-3.rs:4:10 | LL | use foo::bar::{ - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/use-mod-3.rs:9:5 + | +LL | mod bar { pub type Bar = isize; } + | ^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/xcrate/xcrate-private-by-default.stderr b/src/test/ui/xcrate/xcrate-private-by-default.stderr index da52b4249e319..842069d6135cb 100644 --- a/src/test/ui/xcrate/xcrate-private-by-default.stderr +++ b/src/test/ui/xcrate/xcrate-private-by-default.stderr @@ -2,61 +2,121 @@ error[E0603]: static `j` is private --> $DIR/xcrate-private-by-default.rs:23:29 | LL | static_priv_by_default::j; - | ^ + | ^ this static is private + | +note: the static `j` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:47:1 + | +LL | static j: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: function `k` is private --> $DIR/xcrate-private-by-default.rs:25:29 | LL | static_priv_by_default::k; - | ^ + | ^ this function is private + | +note: the function `k` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:48:1 + | +LL | fn k() {} + | ^^^^^^ error[E0603]: unit struct `l` is private --> $DIR/xcrate-private-by-default.rs:27:29 | LL | static_priv_by_default::l; - | ^ + | ^ this unit struct is private + | +note: the unit struct `l` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:49:1 + | +LL | struct l; + | ^^^^^^^^^ error[E0603]: enum `m` is private --> $DIR/xcrate-private-by-default.rs:29:35 | LL | foo::(); - | ^ + | ^ this enum is private + | +note: the enum `m` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:50:1 + | +LL | enum m {} + | ^^^^^^ error[E0603]: type alias `n` is private --> $DIR/xcrate-private-by-default.rs:31:35 | LL | foo::(); - | ^ + | ^ this type alias is private + | +note: the type alias `n` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:51:1 + | +LL | type n = isize; + | ^^^^^^^^^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:35:29 | LL | static_priv_by_default::foo::a; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:37:29 | LL | static_priv_by_default::foo::b; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:39:29 | LL | static_priv_by_default::foo::c; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:41:35 | LL | foo::(); - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:43:35 | LL | foo::(); - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error: aborting due to 10 previous errors From c84efe9b6ca05f64d8b925acc2724971d186f8f6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 16:20:57 +0300 Subject: [PATCH 0417/1253] resolve: Say "import" when reporting private imports --- src/librustc_resolve/diagnostics.rs | 3 +++ src/test/ui/extern/extern-crate-visibility.rs | 4 ++-- src/test/ui/extern/extern-crate-visibility.stderr | 12 ++++++------ src/test/ui/import.stderr | 6 +++--- src/test/ui/imports/issue-55884-2.rs | 2 +- src/test/ui/imports/issue-55884-2.stderr | 6 +++--- src/test/ui/imports/reexports.stderr | 12 ++++++------ src/test/ui/privacy/privacy2.stderr | 6 +++--- src/test/ui/proc-macro/disappearing-resolution.rs | 2 +- .../ui/proc-macro/disappearing-resolution.stderr | 6 +++--- src/test/ui/shadowed/shadowed-use-visibility.rs | 4 ++-- src/test/ui/shadowed/shadowed-use-visibility.stderr | 12 ++++++------ 12 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 20c8f78b1cf0e..a433ae8ed676a 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -921,6 +921,9 @@ impl<'a> Resolver<'a> { if is_constructor { descr += " constructor"; } + if binding.is_import() { + descr += " import"; + } let mut err = struct_span_err!(session, ident.span, E0603, "{} `{}` is private", descr, ident); diff --git a/src/test/ui/extern/extern-crate-visibility.rs b/src/test/ui/extern/extern-crate-visibility.rs index e0a5cd5e98f4b..cda1227cc8e92 100644 --- a/src/test/ui/extern/extern-crate-visibility.rs +++ b/src/test/ui/extern/extern-crate-visibility.rs @@ -3,10 +3,10 @@ mod foo { } // Check that private crates can be used from outside their modules, albeit with warnings -use foo::core::cell; //~ ERROR crate `core` is private +use foo::core::cell; //~ ERROR crate import `core` is private fn f() { - foo::core::cell::Cell::new(0); //~ ERROR crate `core` is private + foo::core::cell::Cell::new(0); //~ ERROR crate import `core` is private use foo::*; mod core {} // Check that private crates are not glob imported diff --git a/src/test/ui/extern/extern-crate-visibility.stderr b/src/test/ui/extern/extern-crate-visibility.stderr index 6d38b4d8d66d6..d0c073d67a4ee 100644 --- a/src/test/ui/extern/extern-crate-visibility.stderr +++ b/src/test/ui/extern/extern-crate-visibility.stderr @@ -1,22 +1,22 @@ -error[E0603]: crate `core` is private +error[E0603]: crate import `core` is private --> $DIR/extern-crate-visibility.rs:6:10 | LL | use foo::core::cell; - | ^^^^ this crate is private + | ^^^^ this crate import is private | -note: the crate `core` is defined here +note: the crate import `core` is defined here --> $DIR/extern-crate-visibility.rs:2:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ -error[E0603]: crate `core` is private +error[E0603]: crate import `core` is private --> $DIR/extern-crate-visibility.rs:9:10 | LL | foo::core::cell::Cell::new(0); - | ^^^^ this crate is private + | ^^^^ this crate import is private | -note: the crate `core` is defined here +note: the crate import `core` is defined here --> $DIR/extern-crate-visibility.rs:2:5 | LL | extern crate core; diff --git a/src/test/ui/import.stderr b/src/test/ui/import.stderr index c66a4fa7151dc..5219ffacd15c0 100644 --- a/src/test/ui/import.stderr +++ b/src/test/ui/import.stderr @@ -13,13 +13,13 @@ error[E0432]: unresolved import `foo` LL | use foo; | ^^^ no `foo` in the root -error[E0603]: unresolved item `foo` is private +error[E0603]: unresolved item import `foo` is private --> $DIR/import.rs:15:10 | LL | zed::foo(); - | ^^^ this unresolved item is private + | ^^^ this unresolved item import is private | -note: the unresolved item `foo` is defined here +note: the unresolved item import `foo` is defined here --> $DIR/import.rs:10:9 | LL | use foo; diff --git a/src/test/ui/imports/issue-55884-2.rs b/src/test/ui/imports/issue-55884-2.rs index 1b4f652c9fc2f..75bb4206f97d6 100644 --- a/src/test/ui/imports/issue-55884-2.rs +++ b/src/test/ui/imports/issue-55884-2.rs @@ -9,6 +9,6 @@ mod parser { use ParseOptions; } -pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private +pub use parser::ParseOptions; //~ ERROR struct import `ParseOptions` is private fn main() {} diff --git a/src/test/ui/imports/issue-55884-2.stderr b/src/test/ui/imports/issue-55884-2.stderr index 9e77283cd5946..f16d2adb3656e 100644 --- a/src/test/ui/imports/issue-55884-2.stderr +++ b/src/test/ui/imports/issue-55884-2.stderr @@ -1,10 +1,10 @@ -error[E0603]: struct `ParseOptions` is private +error[E0603]: struct import `ParseOptions` is private --> $DIR/issue-55884-2.rs:12:17 | LL | pub use parser::ParseOptions; - | ^^^^^^^^^^^^ this struct is private + | ^^^^^^^^^^^^ this struct import is private | -note: the struct `ParseOptions` is defined here +note: the struct import `ParseOptions` is defined here --> $DIR/issue-55884-2.rs:9:9 | LL | use ParseOptions; diff --git a/src/test/ui/imports/reexports.stderr b/src/test/ui/imports/reexports.stderr index 67c12e0c8d3ca..b173884080f80 100644 --- a/src/test/ui/imports/reexports.stderr +++ b/src/test/ui/imports/reexports.stderr @@ -10,25 +10,25 @@ note: consider marking `foo` as `pub` in the imported module LL | pub use super::foo; | ^^^^^^^^^^ -error[E0603]: module `foo` is private +error[E0603]: module import `foo` is private --> $DIR/reexports.rs:33:15 | LL | use b::a::foo::S; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `foo` is defined here +note: the module import `foo` is defined here --> $DIR/reexports.rs:21:17 | LL | pub use super::foo; // This is OK since the value `foo` is visible enough. | ^^^^^^^^^^ -error[E0603]: module `foo` is private +error[E0603]: module import `foo` is private --> $DIR/reexports.rs:34:15 | LL | use b::b::foo::S as T; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `foo` is defined here +note: the module import `foo` is defined here --> $DIR/reexports.rs:26:17 | LL | pub use super::*; // This is also OK since the value `foo` is visible enough. diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr index d9f003ddae7ac..719dc27ccf4d6 100644 --- a/src/test/ui/privacy/privacy2.stderr +++ b/src/test/ui/privacy/privacy2.stderr @@ -4,13 +4,13 @@ error[E0432]: unresolved import `bar::foo` LL | use bar::foo; | ^^^^^^^^ no `foo` in `bar` -error[E0603]: function `foo` is private +error[E0603]: function import `foo` is private --> $DIR/privacy2.rs:23:20 | LL | use bar::glob::foo; - | ^^^ this function is private + | ^^^ this function import is private | -note: the function `foo` is defined here +note: the function import `foo` is defined here --> $DIR/privacy2.rs:10:13 | LL | use foo; diff --git a/src/test/ui/proc-macro/disappearing-resolution.rs b/src/test/ui/proc-macro/disappearing-resolution.rs index a01b8f302cae3..50f04b1eae150 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.rs +++ b/src/test/ui/proc-macro/disappearing-resolution.rs @@ -8,7 +8,7 @@ extern crate test_macros; mod m { use test_macros::Empty; } -use m::Empty; //~ ERROR derive macro `Empty` is private +use m::Empty; //~ ERROR derive macro import `Empty` is private // To resolve `empty_helper` we need to resolve `Empty`. // During initial resolution `use m::Empty` introduces no entries, so we proceed to `macro_use`, diff --git a/src/test/ui/proc-macro/disappearing-resolution.stderr b/src/test/ui/proc-macro/disappearing-resolution.stderr index d81ab5ebf9bc6..3beaedf61d73a 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.stderr +++ b/src/test/ui/proc-macro/disappearing-resolution.stderr @@ -4,13 +4,13 @@ error: cannot find attribute `empty_helper` in this scope LL | #[empty_helper] | ^^^^^^^^^^^^ -error[E0603]: derive macro `Empty` is private +error[E0603]: derive macro import `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 | LL | use m::Empty; - | ^^^^^ this derive macro is private + | ^^^^^ this derive macro import is private | -note: the derive macro `Empty` is defined here +note: the derive macro import `Empty` is defined here --> $DIR/disappearing-resolution.rs:9:9 | LL | use test_macros::Empty; diff --git a/src/test/ui/shadowed/shadowed-use-visibility.rs b/src/test/ui/shadowed/shadowed-use-visibility.rs index 8185e82ee830e..6b801972f4179 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.rs +++ b/src/test/ui/shadowed/shadowed-use-visibility.rs @@ -6,11 +6,11 @@ mod foo { } mod bar { - use foo::bar::f as g; //~ ERROR module `bar` is private + use foo::bar::f as g; //~ ERROR module import `bar` is private use foo as f; pub use foo::*; } -use bar::f::f; //~ ERROR module `f` is private +use bar::f::f; //~ ERROR module import `f` is private fn main() {} diff --git a/src/test/ui/shadowed/shadowed-use-visibility.stderr b/src/test/ui/shadowed/shadowed-use-visibility.stderr index 77bf2abe34555..cd8ec13794c6f 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.stderr +++ b/src/test/ui/shadowed/shadowed-use-visibility.stderr @@ -1,22 +1,22 @@ -error[E0603]: module `bar` is private +error[E0603]: module import `bar` is private --> $DIR/shadowed-use-visibility.rs:9:14 | LL | use foo::bar::f as g; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `bar` is defined here +note: the module import `bar` is defined here --> $DIR/shadowed-use-visibility.rs:4:9 | LL | use foo as bar; | ^^^^^^^^^^ -error[E0603]: module `f` is private +error[E0603]: module import `f` is private --> $DIR/shadowed-use-visibility.rs:15:10 | LL | use bar::f::f; - | ^ this module is private + | ^ this module import is private | -note: the module `f` is defined here +note: the module import `f` is defined here --> $DIR/shadowed-use-visibility.rs:11:9 | LL | use foo as f; From 0b60f1f2ae54b0bdb1623606db5dd18da1e80517 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 16 Jan 2020 22:19:55 +0300 Subject: [PATCH 0418/1253] Ignore some tests on platforms without libstd spans --- src/test/ui/issues/issue-38857.rs | 5 +++++ src/test/ui/issues/issue-38857.stderr | 4 ++-- src/test/ui/stability-in-private-module.rs | 5 +++++ src/test/ui/stability-in-private-module.stderr | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/ui/issues/issue-38857.rs b/src/test/ui/issues/issue-38857.rs index 81d881c100bb6..c0695f8216512 100644 --- a/src/test/ui/issues/issue-38857.rs +++ b/src/test/ui/issues/issue-38857.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433] diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr index dd7970e014fdb..ba0f1336ff09d 100644 --- a/src/test/ui/issues/issue-38857.stderr +++ b/src/test/ui/issues/issue-38857.stderr @@ -1,11 +1,11 @@ error[E0433]: failed to resolve: could not find `imp` in `sys` - --> $DIR/issue-38857.rs:2:23 + --> $DIR/issue-38857.rs:7:23 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ could not find `imp` in `sys` error[E0603]: module `sys` is private - --> $DIR/issue-38857.rs:2:18 + --> $DIR/issue-38857.rs:7:18 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ this module is private diff --git a/src/test/ui/stability-in-private-module.rs b/src/test/ui/stability-in-private-module.rs index f12e9198b0d7c..1815897f17a60 100644 --- a/src/test/ui/stability-in-private-module.rs +++ b/src/test/ui/stability-in-private-module.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let _ = std::thread::thread_info::current_thread(); //~^ERROR module `thread_info` is private diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr index 537a400664aaa..3a974164f9473 100644 --- a/src/test/ui/stability-in-private-module.stderr +++ b/src/test/ui/stability-in-private-module.stderr @@ -1,5 +1,5 @@ error[E0603]: module `thread_info` is private - --> $DIR/stability-in-private-module.rs:2:26 + --> $DIR/stability-in-private-module.rs:7:26 | LL | let _ = std::thread::thread_info::current_thread(); | ^^^^^^^^^^^ this module is private From 029a9c625371e756d93024efd3deb7636a90f8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 11:32:50 -0800 Subject: [PATCH 0419/1253] review comments --- .../traits/error_reporting/suggestions.rs | 49 +++++++++---------- src/librustc_error_codes/error_codes/E0746.md | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c3af063d518f0..bf6891214ace1 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -605,34 +605,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - let param_env = ty::ParamEnv::empty(); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - all_returns_have_same_type &= - Some(returned_ty) == last_ty || last_ty.is_none(); - last_ty = Some(returned_ty); - for predicate in predicates.iter() { - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= self.predicate_may_hold(&obl); - } + let mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); + let (last_ty, all_returns_have_same_type) = + ret_types.clone().fold((None, true), |(last_ty, mut same), returned_ty| { + same &= last_ty.map_or(true, |ty| ty == returned_ty); + (Some(returned_ty), same) + }); + let all_returns_conform_to_trait = + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + match ty_ret_ty.kind { + ty::Dynamic(predicates, _) => { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + ret_types.all(|returned_ty| { + predicates.iter().all(|predicate| { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + self.predicate_may_hold(&obl) + }) + }) } + _ => true, } - } - } else { - // We still want to verify whether all the return types conform to each other. - for expr in &visitor.0 { - let returned_ty = tables.node_type_opt(expr.hir_id); - all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); - last_ty = returned_ty; - } - } + } else { + true + }; let (snippet, last_ty) = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 041061f3380c1..16b2722f0eac2 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -13,7 +13,7 @@ impl T for S { } // Having the trait `T` as return type is invalid because -// bare trait objects do not have a statically known size: +// unboxed trait objects do not have a statically known size: fn foo() -> dyn T { S(42) } From 25a8f9473f29e732838b6d88394dd80fe645b7f6 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sat, 23 Nov 2019 14:52:40 +1000 Subject: [PATCH 0420/1253] Don't warn about snake case for field puns that don't introduce a new name. --- src/librustc_lint/nonstandard_style.rs | 15 ++++++++- ...62-no-snake-case-warning-for-field-puns.rs | 29 +++++++++++++++++ ...o-snake-case-warning-for-field-puns.stderr | 32 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index a2b7884241ff7..394da4a5bb0c1 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -350,7 +350,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) { - if let &PatKind::Binding(_, _, ident, _) = &p.kind { + if let &PatKind::Binding(_, hid, ident, _) = &p.kind { + if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) + { + if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind { + for field in field_pats.iter() { + if field.ident != ident { + // Only check if a new name has been introduced, to avoid warning + // on both the struct definition and this pattern. + self.check_snake_case(cx, "variable", &ident); + } + } + return; + } + } self.check_snake_case(cx, "variable", &ident); } } diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs new file mode 100644 index 0000000000000..c2b81959f2cb8 --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs @@ -0,0 +1,29 @@ +#![deny(non_snake_case)] +#![allow(unused_variables)] +#![allow(dead_code)] + +enum Foo { + Bad { + lowerCamelCaseName: bool, + //~^ ERROR structure field `lowerCamelCaseName` should have a snake case name + }, + Good { + snake_case_name: bool, + }, +} + +fn main() { + let b = Foo::Bad { lowerCamelCaseName: true }; + + match b { + Foo::Bad { lowerCamelCaseName } => {} + Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + //~^ ERROR variable `lowerCamelCaseBinding` should have a snake case name + } + + if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `anotherLowerCamelCaseBinding` should have a snake case name + + if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `yetAnotherLowerCamelCaseBinding` should have a snake case name +} diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr new file mode 100644 index 0000000000000..68956f21e8f1b --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr @@ -0,0 +1,32 @@ +error: structure field `lowerCamelCaseName` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9 + | +LL | lowerCamelCaseName: bool, + | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name` + | +note: lint level defined here + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: variable `lowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38 + | +LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + | ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding` + +error: variable `anotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41 + | +LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding` + +error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43 + | +LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding` + +error: aborting due to 4 previous errors + From 73124df6eba9d81affb3ef597fdaeb4fce82f7af Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Thu, 16 Jan 2020 20:11:16 +0000 Subject: [PATCH 0421/1253] Rust ./x.py fmt --- src/libcore/tests/fmt/builders.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index d8ec6764bc620..129c121e8ceac 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -100,18 +100,17 @@ mod debug_struct { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Foo") - .finish_non_exhaustive() + fmt.debug_struct("Foo").finish_non_exhaustive() } } - assert_eq!("Foo { .. }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { .. }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -129,12 +128,13 @@ mod debug_struct { assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { bar: true, baz: 10/20, .. }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -161,10 +161,12 @@ mod debug_struct { } } - assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", - format!("{:?}", Bar)); assert_eq!( -"Bar { + "Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", + format!("{:?}", Bar) + ); + assert_eq!( + "Bar { foo: Foo { bar: true, baz: 10/20, @@ -173,9 +175,9 @@ mod debug_struct { hello: \"world\", .. }", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } - } mod debug_tuple { From 3094c3792bb0bffbaaa0688d02c970054c353d1f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 21:36:39 +0100 Subject: [PATCH 0422/1253] Improve code readability --- src/librustdoc/clean/mod.rs | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ae15b458fbaea..0e9f363bec3f3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,8 +2121,8 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - if let Some(type_alias) = type_alias { - ret.push(Item { + let make_item = |trait_: Option, for_: Type, items: Vec| { + Item { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), @@ -2134,35 +2134,19 @@ impl Clean> for doctree::Impl<'_> { unsafety: self.unsafety, generics: self.generics.clean(cx), provided_trait_methods: provided.clone(), - trait_: trait_.clone(), - for_: type_alias, - items: items.clone(), + trait_, + for_, + items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, blanket_impl: None, }), - }); + } + }; + if let Some(type_alias) = type_alias { + ret.push(make_item(trait_.clone(), type_alias, items.clone())); } - ret.push(Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided, - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - }); + ret.push(make_item(trait_, for_, items)); ret } } From 7fbd30b1ae0ce9293302bbf4bfb814f1dc791107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 16 Jan 2020 23:15:52 +0100 Subject: [PATCH 0423/1253] don't clone types that are copy found via clippy --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc_ast_lowering/expr.rs | 6 +++--- src/librustc_builtin_macros/deriving/generic/mod.rs | 2 +- src/librustc_errors/annotate_snippet_emitter_writer.rs | 2 +- src/librustc_incremental/persist/save.rs | 2 +- src/librustc_lint/context.rs | 2 +- src/librustc_metadata/rmeta/decoder.rs | 2 +- src/librustc_metadata/rmeta/encoder.rs | 2 +- src/librustc_mir/borrow_check/borrow_set.rs | 4 ++-- src/librustc_mir_build/build/mod.rs | 2 +- src/librustc_passes/stability.rs | 2 +- src/librustc_traits/chalk_context/mod.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 2 +- src/libtest/lib.rs | 4 +--- 15 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c52d4335ea184..febf4f21a6755 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -2008,7 +2008,7 @@ impl<'tcx> ObligationCause<'tcx> { TypeError::IntrinsicCast => { Error0308("cannot coerce intrinsics to function pointers") } - TypeError::ObjectUnsafeCoercion(did) => Error0038(did.clone()), + TypeError::ObjectUnsafeCoercion(did) => Error0038(*did), _ => Error0308("mismatched types"), }, } diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 9a229e709a5e5..2866a1624de5b 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -909,18 +909,18 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind<'hir> { let inner = hir::InlineAsmInner { - inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(), + inputs: asm.inputs.iter().map(|&(c, _)| c).collect(), outputs: asm .outputs .iter() .map(|out| hir::InlineAsmOutput { - constraint: out.constraint.clone(), + constraint: out.constraint, is_rw: out.is_rw, is_indirect: out.is_indirect, span: out.expr.span, }) .collect(), - asm: asm.asm.clone(), + asm: asm.asm, asm_str_style: asm.asm_str_style, clobbers: asm.clobbers.clone().into(), volatile: asm.volatile, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 7092483843f70..9226f45816506 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -1608,7 +1608,7 @@ impl<'a> TraitDef<'a> { } else { ast::BindingMode::ByRef(mutbl) }; - cx.pat(path.span, PatKind::Ident(binding_mode, (*path).clone(), None)) + cx.pat(path.span, PatKind::Ident(binding_mode, *path, None)) }) .collect() } diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 7413cef6d32d4..009ab6ac5b12f 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -196,7 +196,7 @@ impl AnnotateSnippetEmitterWriter { ) { let converter = DiagnosticConverter { source_map: self.source_map.clone(), - level: level.clone(), + level: *level, message, code: code.clone(), msp: msp.clone(), diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 588e639f28946..87f39dedd0273 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -236,7 +236,7 @@ fn encode_work_product_index( let serialized_products: Vec<_> = work_products .iter() .map(|(id, work_product)| SerializedWorkProduct { - id: id.clone(), + id: *id, work_product: work_product.clone(), }) .collect(); diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 2b514c301f2a3..42ec8787cb287 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -245,7 +245,7 @@ impl LintStore { pub fn register_renamed(&mut self, old_name: &str, new_name: &str) { let target = match self.by_name.get(new_name) { - Some(&Id(lint_id)) => lint_id.clone(), + Some(&Id(lint_id)) => lint_id, _ => bug!("invalid lint renaming of {} to {}", old_name, new_name), }; self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target)); diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index eb3dcfa72278e..6280121f65566 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -840,7 +840,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_stability(&self, id: DefIndex) -> Option { match self.is_proc_macro(id) { - true => self.root.proc_macro_stability.clone(), + true => self.root.proc_macro_stability, false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)), } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 7f8791d0c34dc..8ad92ce75a851 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -504,7 +504,7 @@ impl<'tcx> EncodeContext<'tcx> { }, proc_macro_data, proc_macro_stability: if is_proc_macro { - tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone()) + tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| *stab) } else { None }, diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index f2a44986cc4d4..9d5cf3ec4bec0 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -200,8 +200,8 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { region, reserve_location: location, activation_location: TwoPhaseActivation::NotTwoPhase, - borrowed_place: borrowed_place.clone(), - assigned_place: assigned_place.clone(), + borrowed_place: *borrowed_place, + assigned_place: *assigned_place, }; let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 6214453e64f78..44ff493b5b4f0 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -65,7 +65,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { } else if cx.body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) - let fn_sig = cx.tables().liberated_fn_sigs()[id].clone(); + let fn_sig = cx.tables().liberated_fn_sigs()[id]; let fn_def_id = tcx.hir().local_def_id(id); let ty = tcx.type_of(fn_def_id); diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index af37d218d68f0..5ec7e73f873e0 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // deprecated_since and its reason. if let Some(parent_stab) = self.parent_stab { if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() { - stab.rustc_depr = parent_stab.rustc_depr.clone() + stab.rustc_depr = parent_stab.rustc_depr } } diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 4b10b08ddd94c..0b18352df3307 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -400,7 +400,7 @@ impl context::UnificationOps, ChalkArenas<'tcx>> &mut self, value: &Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>, ) -> (Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>, UniverseMap) { - (value.clone(), UniverseMap) + (*value, UniverseMap) } fn invert_goal( diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 6bb7f4995b6ec..084e6c8d083c5 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -175,7 +175,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), ty::FnPtr(sig) => { - let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder().clone() }; + let expected_sig = ExpectedSig { cause_span: None, sig: *sig.skip_binder() }; (Some(expected_sig), Some(ty::ClosureKind::Fn)) } _ => (None, None), diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 56013ee3a816f..f37f6921cebaf 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -239,7 +239,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // constraint, and add it to our list. Since we make sure to never re-add // deleted items, this process will always finish. while !vid_map.is_empty() { - let target = vid_map.keys().next().expect("Keys somehow empty").clone(); + let target = *vid_map.keys().next().expect("Keys somehow empty"); let deps = vid_map.remove(&target).expect("Entry somehow missing"); for smaller in deps.smaller.iter() { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 45669d120c7c2..4c4d795824318 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -485,9 +485,7 @@ pub fn run_test( } StaticBenchFn(benchfn) => { // Benchmarks aren't expected to panic, so we run them all in-process. - crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { - (benchfn.clone())(harness) - }); + crate::bench::benchmark(desc, monitor_ch, opts.nocapture, benchfn); } DynTestFn(f) => { match strategy { From d088d8a2c1bd706c458d36eac941949169514d86 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 16 Jan 2020 18:47:52 -0500 Subject: [PATCH 0424/1253] Revert previous attempt at detecting unsatisfiable predicates --- src/librustc/mir/mono.rs | 5 +---- src/librustc/query/mod.rs | 6 +++--- src/librustc/traits/fulfill.rs | 24 ++---------------------- src/librustc/traits/mod.rs | 20 ++++++++------------ src/librustc/ty/query/keys.rs | 9 --------- 5 files changed, 14 insertions(+), 50 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index e7a4c5b592105..51ce575e51f3b 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,7 +1,6 @@ use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; use crate::session::config::OptLevel; -use crate::traits::TraitQueryMode; use crate::ty::print::obsolete::DefPathBasedNames; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; use rustc_data_structures::base_n; @@ -168,9 +167,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(..) => return true, }; - // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\ - // to report an error if overflow somehow occurs. - tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard)) + tcx.substitute_normalize_and_test_predicates((def_id, &substs)) } pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index a20e011b91a75..f4c262fbac1d4 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1148,11 +1148,11 @@ rustc_queries! { desc { "normalizing `{:?}`", goal } } - query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool { + query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { no_force desc { |tcx| - "testing substituted normalized predicates in mode {:?}:`{}`", - key.2, tcx.def_path_str(key.0) + "testing substituted normalized predicates:`{}`", + tcx.def_path_str(key.0) } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 9e5abc80822c7..46ece6fc40593 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -16,7 +16,6 @@ use super::CodeSelectionError; use super::{ConstEvalFailure, Unimplemented}; use super::{FulfillmentError, FulfillmentErrorCode}; use super::{ObligationCause, PredicateObligation}; -use crate::traits::TraitQueryMode; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { type Predicate = ty::Predicate<'tcx>; @@ -63,9 +62,6 @@ pub struct FulfillmentContext<'tcx> { // a snapshot (they don't *straddle* a snapshot, so there // is no trouble there). usable_in_snapshot: bool, - - // The `TraitQueryMode` used when constructing a `SelectionContext` - query_mode: TraitQueryMode, } #[derive(Clone, Debug)] @@ -79,26 +75,12 @@ pub struct PendingPredicateObligation<'tcx> { static_assert_size!(PendingPredicateObligation<'_>, 136); impl<'a, 'tcx> FulfillmentContext<'tcx> { - /// Creates a new fulfillment context with `TraitQueryMode::Standard` - /// You almost always want to use this instead of `with_query_mode` + /// Creates a new fulfillment context. pub fn new() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: false, - query_mode: TraitQueryMode::Standard, - } - } - - /// Creates a new fulfillment context with the specified query mode. - /// This should only be used when you want to ignore overflow, - /// rather than reporting it as an error. - pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> { - FulfillmentContext { - predicates: ObligationForest::new(), - register_region_obligations: true, - usable_in_snapshot: false, - query_mode, } } @@ -107,7 +89,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: true, - query_mode: TraitQueryMode::Standard, } } @@ -116,7 +97,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: false, usable_in_snapshot: false, - query_mode: TraitQueryMode::Standard, } } @@ -237,7 +217,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { &mut self, infcx: &InferCtxt<'_, 'tcx>, ) -> Result<(), Vec>> { - let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode); + let mut selcx = SelectionContext::new(infcx); self.select(&mut selcx) } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 31de5409fc8be..7509c2251f083 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -95,7 +95,7 @@ pub enum IntercrateMode { } /// The mode that trait queries run in. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum TraitQueryMode { // Standard/un-canonicalized queries get accurate // spans etc. passed in and hence can do reasonable @@ -1014,17 +1014,16 @@ where /// environment. If this returns false, then either normalize /// encountered an error or one of the predicates did not hold. Used /// when creating vtables to check for unsatisfiable methods. -fn normalize_and_test_predicates<'tcx>( +pub fn normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: Vec>, - mode: TraitQueryMode, ) -> bool { - debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode); + debug!("normalize_and_test_predicates(predicates={:?})", predicates); let result = tcx.infer_ctxt().enter(|infcx| { let param_env = ty::ParamEnv::reveal_all(); - let mut selcx = SelectionContext::with_query_mode(&infcx, mode); - let mut fulfill_cx = FulfillmentContext::with_query_mode(mode); + let mut selcx = SelectionContext::new(&infcx); + let mut fulfill_cx = FulfillmentContext::new(); let cause = ObligationCause::dummy(); let Normalized { value: predicates, obligations } = normalize(&mut selcx, param_env, cause.clone(), &predicates); @@ -1044,12 +1043,12 @@ fn normalize_and_test_predicates<'tcx>( fn substitute_normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, - key: (DefId, SubstsRef<'tcx>, TraitQueryMode), + key: (DefId, SubstsRef<'tcx>), ) -> bool { debug!("substitute_normalize_and_test_predicates(key={:?})", key); let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; - let result = normalize_and_test_predicates(tcx, predicates, key.2); + let result = normalize_and_test_predicates(tcx, predicates); debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result); result @@ -1102,10 +1101,7 @@ fn vtable_methods<'tcx>( // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - // We don't expect overflow here, so report an error if it somehow ends - // up happening. - if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard) - { + if !normalize_and_test_predicates(tcx, predicates.predicates) { debug!("vtable_methods: predicates do not hold"); return None; } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 3fb3720a5638a..cbf335ad607ef 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -125,15 +125,6 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } -impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) { - fn query_crate(&self) -> CrateNum { - self.0.krate - } - fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - self.0.default_span(tcx) - } -} - impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { fn query_crate(&self) -> CrateNum { self.1.def_id().krate From 171fe82efc2ab420e3fe2e9ad5a44db093a751f1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 16 Jan 2020 18:53:51 -0500 Subject: [PATCH 0425/1253] Filter and test predicates using `normalize_and_test_predicates` for const-prop Fixes #68264 Previously, I attempted to use `substitute_normalize_and_test_predicates` to detect unsatisfiable bounds. Unfortunately, since const-prop runs in a generic environment (we don't have any of the function's generic parameters substituted), this could lead to cycle errors when attempting to normalize predicates. This check is replaced with a more precise check. We now only call `normalize_and_test_predicates` on predicates that have the possibility of being proved unsatisfiable - that is, predicates that don't depend on anything local to the function (e.g. generic parameters). This ensures that we don't hit cycle errors when we normalize said predicates, while still ensuring that we detect unsatisfiable predicates. --- src/librustc_mir/transform/const_prop.rs | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 9d5dbe3564ee0..badca10569404 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -14,7 +14,7 @@ use rustc::mir::{ SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; -use rustc::traits::TraitQueryMode; +use rustc::traits; use rustc::ty::layout::{ HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; @@ -90,28 +90,28 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // If there are unsatisfiable where clauses, then all bets are // off, and we just give up. // - // Note that we use TraitQueryMode::Canonical here, which causes - // us to treat overflow like any other error. This is because we - // are "speculatively" evaluating this item with the default substs. - // While this usually succeeds, it may fail with tricky impls - // (e.g. the typenum crate). Const-propagation is fundamentally - // "best-effort", and does not affect correctness in any way. - // Therefore, it's perfectly fine to just "give up" if we're - // unable to check the bounds with the default substs. + // We manually filter the predicates, skipping anything that's not + // "global". We are in a potentially generic context + // (e.g. we are evaluating a function without substituging generic + // parameters, so this filtering serves two purposes: // - // False negatives (failing to run const-prop on something when we actually - // could) are fine. However, false positives (running const-prop on - // an item with unsatisfiable bounds) can lead to us generating invalid - // MIR. - if !tcx.substitute_normalize_and_test_predicates(( - source.def_id(), - InternalSubsts::identity_for_item(tcx, source.def_id()), - TraitQueryMode::Canonical, - )) { - trace!( - "ConstProp skipped for item with unsatisfiable predicates: {:?}", - source.def_id() - ); + // 1. We skip evaluating any predicates that we would + // never be able prove are unsatisfiable (e.g. `` + // 2. We avoid trying to normalize predicates involving generic + // parameters (e.g. `::MyItem`). This can confuse + // the normalization code (leading to cycle errors), since + // it's usually never invoked in this way. + let predicates = tcx + .predicates_of(source.def_id()) + .predicates + .iter() + .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }) + .collect(); + if !traits::normalize_and_test_predicates( + tcx, + traits::elaborate_predicates(tcx, predicates).collect(), + ) { + trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", source.def_id()); return; } From 4dbae1e8baf5c42b42aa2ab4d1104ec019b75b83 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Fri, 17 Jan 2020 01:05:49 +0100 Subject: [PATCH 0426/1253] Allow added string.insert benchmarks to compile --- src/liballoc/benches/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/benches/string.rs b/src/liballoc/benches/string.rs index 599c8b1682851..5c95160ba2d14 100644 --- a/src/liballoc/benches/string.rs +++ b/src/liballoc/benches/string.rs @@ -1,5 +1,5 @@ use std::iter::repeat; -use test::Bencher; +use test::{black_box, Bencher}; #[bench] fn bench_with_capacity(b: &mut Bencher) { From 6246f7e1f90f1b72d5b9b530df2ee81beeb09f20 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 16 Jan 2020 16:29:32 -0800 Subject: [PATCH 0427/1253] Don't propagate __RUST_TEST_INVOKE to subprocess When -Z panic_abort_tests is enabled, we use an environment variable to tell the subprocess which test to invoke. If that subprocess then invokes another Rust test binary, chaos ensues. --- src/libtest/lib.rs | 3 ++- src/test/ui/test-panic-abort.rs | 11 +++++++++++ src/test/ui/test-panic-abort.run.stdout | 7 ++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 45669d120c7c2..7782f62d6ed35 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -153,12 +153,13 @@ pub fn test_main_static_abort(tests: &[&TestDescAndFn]) { // If we're being run in SpawnedSecondary mode, run the test here. run_test // will then exit the process. if let Ok(name) = env::var(SECONDARY_TEST_INVOKER_VAR) { + env::remove_var(SECONDARY_TEST_INVOKER_VAR); let test = tests .iter() .filter(|test| test.desc.name.as_slice() == name) .map(make_owned_test) .next() - .expect("couldn't find a test with the provided name"); + .expect(&format!("couldn't find a test with the provided name '{}'", name)); let TestDescAndFn { desc, testfn } = test; let testfn = match testfn { StaticTestFn(f) => f, diff --git a/src/test/ui/test-panic-abort.rs b/src/test/ui/test-panic-abort.rs index b0679ea1d3df2..b7bf5a150ea8b 100644 --- a/src/test/ui/test-panic-abort.rs +++ b/src/test/ui/test-panic-abort.rs @@ -11,6 +11,7 @@ #![cfg(test)] use std::io::Write; +use std::env; #[test] fn it_works() { @@ -35,3 +36,13 @@ fn it_fails() { fn it_exits() { std::process::exit(123); } + +#[test] +fn no_residual_environment() { + for (key, _) in env::vars() { + // Look for keys like __RUST_TEST_INVOKE. + if key.contains("TEST_INVOKE") { + panic!("shouldn't have '{}' in environment", key); + } + } +} diff --git a/src/test/ui/test-panic-abort.run.stdout b/src/test/ui/test-panic-abort.run.stdout index 46adcfbc2eb4a..2f4bc32ed6a1f 100644 --- a/src/test/ui/test-panic-abort.run.stdout +++ b/src/test/ui/test-panic-abort.run.stdout @@ -1,9 +1,10 @@ -running 4 tests +running 5 tests test it_exits ... FAILED test it_fails ... FAILED test it_panics ... ok test it_works ... ok +test no_residual_environment ... ok failures: @@ -17,7 +18,7 @@ testing123 testing321 thread 'main' panicked at 'assertion failed: `(left == right)` left: `2`, - right: `5`', $DIR/test-panic-abort.rs:31:5 + right: `5`', $DIR/test-panic-abort.rs:32:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace @@ -25,5 +26,5 @@ failures: it_exits it_fails -test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out From 10a9ea4c2622544d52ecef47fea0404a7ce0ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:57:06 -0800 Subject: [PATCH 0428/1253] Do not ICE on malformed suggestion spans --- src/librustc_errors/emitter.rs | 9 ++++++++- src/librustc_errors/lib.rs | 13 +++++++++++++ src/librustc_span/source_map.rs | 11 +++++++---- .../ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 526b4e2971bef..e37496f729952 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,6 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; + if !suggestion.has_valid_spans(&**sm) { + // Suggestions coming from macros can have malformed spans. This is a heavy handed + // approach to avoid ICEs by ignoring the suggestion outright. + return Ok(()); + } let mut buffer = StyledBuffer::new(); @@ -1505,7 +1510,9 @@ impl EmitterWriter { let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim()) && complete.lines().count() == 1; - let lines = sm.span_to_lines(parts[0].span).unwrap(); + let lines = sm + .span_to_lines(parts[0].span) + .expect("span_to_lines failed when emitting suggestion"); assert!(!lines.lines.is_empty()); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e24e8719133a9..889c84d6da132 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -10,6 +10,7 @@ pub use emitter::ColorConfig; +use log::debug; use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; @@ -143,6 +144,18 @@ pub struct SubstitutionPart { } impl CodeSuggestion { + /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach + /// to avoid ICEs by ignoring the suggestion outright. + pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { + !self.substitutions.iter().any(|subst| { + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("malformed span in suggestion: {:?}", subst); + } + invalid + }) + } + /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index fb5fcf4a8303b..9c7c0f0c8b0ec 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -473,20 +473,23 @@ impl SourceMap { lo.line != hi.line } - pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { - debug!("span_to_lines(sp={:?})", sp); - + pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> { let lo = self.lookup_char_pos(sp.lo()); debug!("span_to_lines: lo={:?}", lo); let hi = self.lookup_char_pos(sp.hi()); debug!("span_to_lines: hi={:?}", hi); - if lo.file.start_pos != hi.file.start_pos { return Err(SpanLinesError::DistinctSources(DistinctSources { begin: (lo.file.name.clone(), lo.file.start_pos), end: (hi.file.name.clone(), hi.file.start_pos), })); } + Ok((lo, hi)) + } + + pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { + debug!("span_to_lines(sp={:?})", sp); + let (lo, hi) = self.is_valid_span(sp)?; assert!(hi.line >= lo.line); let mut lines = Vec::with_capacity(hi.line - lo.line + 1); diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 655c31763ef44..cc124058cfcb8 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 19fdc6e091af973a378d53c13bb1ea42862171ad Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 19 Nov 2019 18:28:32 -0800 Subject: [PATCH 0429/1253] Document unsafe blocks in core::{cell, str, sync} --- src/libcore/cell.rs | 12 +++++++++-- src/libcore/str/lossy.rs | 6 ++++-- src/libcore/str/mod.rs | 44 ++++++++++++++++++++++++++++++-------- src/libcore/str/pattern.rs | 13 +++++++++-- src/libcore/sync/atomic.rs | 33 ++++++++++++++++++++++++++-- 5 files changed, 91 insertions(+), 17 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4fcd0d9737d56..c530432f802db 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -187,8 +187,6 @@ //! ``` //! -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] use crate::cmp::Ordering; @@ -368,6 +366,7 @@ impl Cell { if ptr::eq(self, other) { return; } + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { ptr::swap(self.value.get(), other.value.get()); } @@ -387,6 +386,7 @@ impl Cell { /// ``` #[stable(feature = "move_cell", since = "1.17.0")] pub fn replace(&self, val: T) -> T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe mem::replace(unsafe { &mut *self.value.get() }, val) } @@ -423,6 +423,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { *self.value.get() } } @@ -491,6 +492,7 @@ impl Cell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { &mut *self.value.get() } } @@ -510,6 +512,7 @@ impl Cell { #[inline] #[stable(feature = "as_cell", since = "1.37.0")] pub fn from_mut(t: &mut T) -> &Cell { + // SAFETY: `&mut` ensures unique access unsafe { &*(t as *mut T as *const Cell) } } } @@ -553,6 +556,7 @@ impl Cell<[T]> { /// ``` #[stable(feature = "as_cell", since = "1.37.0")] pub fn as_slice_of_cells(&self) -> &[Cell] { + // SAFETY: `Cell` has the same memory layout as `T` unsafe { &*(self as *const Cell<[T]> as *const [Cell]) } } } @@ -816,6 +820,8 @@ impl RefCell { #[inline] pub fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { + // SAFETY: `BorrowRef` ensures that there is only immutable access + // to the value while borrowed Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }), None => Err(BorrowError { _private: () }), } @@ -891,6 +897,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { + // SAFETY: `BorrowRef` gurantees unique access Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } @@ -940,6 +947,7 @@ impl RefCell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { + // SAFETY: `&mut` guarantees unique access unsafe { &mut *self.value.get() } } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 8a1fb9de54667..9d2e38734ef02 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -3,8 +3,6 @@ use crate::fmt::{self, Write}; use crate::mem; use crate::str as core_str; -// ignore-tidy-undocumented-unsafe - /// Lossy UTF-8 string. #[unstable(feature = "str_internals", issue = "none")] pub struct Utf8Lossy { @@ -17,6 +15,7 @@ impl Utf8Lossy { } pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy { + // SAFETY: both use the same memory layout, and UTF-8 correctness isn't required unsafe { mem::transmute(bytes) } } @@ -60,6 +59,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { while i < self.source.len() { let i_ = i; + // SAFETY: 0 <= i < self.source.len() let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; @@ -69,6 +69,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { macro_rules! error { () => {{ + // SAFETY: we have checked up to `i` that source is valid UTF-8 unsafe { let r = Utf8LossyChunk { valid: core_str::from_utf8_unchecked(&self.source[0..i_]), @@ -130,6 +131,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } let r = Utf8LossyChunk { + // SAFETY: we have checked that the entire source is valid UTF-8 valid: unsafe { core_str::from_utf8_unchecked(self.source) }, broken: &[], }; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ab771b1164bad..3139d6188e27f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1,5 +1,4 @@ // ignore-tidy-filelength -// ignore-tidy-undocumented-unsafe //! String manipulation. //! @@ -341,6 +340,7 @@ impl Utf8Error { #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { run_utf8_validation(v)?; + // SAFETY: just ran validation Ok(unsafe { from_utf8_unchecked(v) }) } @@ -379,6 +379,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { #[stable(feature = "str_mut_extras", since = "1.20.0")] pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { run_utf8_validation(v)?; + // SAFETY: just ran validation Ok(unsafe { from_utf8_unchecked_mut(v) }) } @@ -581,7 +582,7 @@ impl<'a> Iterator for Chars<'a> { #[inline] fn next(&mut self) -> Option { next_code_point(&mut self.iter).map(|ch| { - // str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value unsafe { char::from_u32_unchecked(ch) } }) } @@ -628,7 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] fn next_back(&mut self) -> Option { next_code_point_reverse(&mut self.iter).map(|ch| { - // str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value unsafe { char::from_u32_unchecked(ch) } }) } @@ -658,6 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { + // SAFETY: Chars is only made from a str, which guarantees the iter is valid utf8 unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } @@ -1102,6 +1104,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { fn get_end(&mut self) -> Option<&'a str> { if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { self.finished = true; + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries unsafe { let string = self.matcher.haystack().get_unchecked(self.start..self.end); Some(string) @@ -1119,6 +1122,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match() { + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries Some((a, b)) => unsafe { let elt = haystack.get_unchecked(self.start..a); self.start = b; @@ -1151,11 +1155,13 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match_back() { + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries Some((a, b)) => unsafe { let elt = haystack.get_unchecked(b..self.end); self.end = a; Some(elt) }, + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries None => unsafe { self.finished = true; Some(haystack.get_unchecked(self.start..self.end)) @@ -1295,6 +1301,7 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { + // SAFETY: `Searcher` guaratees that `start` and `end` lie on unicode boundaries self.0 .next_match() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1305,6 +1312,7 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0 .next_match_back() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1348,6 +1356,7 @@ where impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0.next_match().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1359,6 +1368,7 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0.next_match_back().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1579,6 +1589,9 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { let ptr = v.as_ptr(); while index < blocks_end { + // SAFETY: since `align - index` and `ascii_block_size` are multiples of + // `usize_bytes`, `ptr.add(index)` is always aligned with a `usize` so we + // may cast directly to a `const` pointer. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte @@ -1804,6 +1817,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1815,6 +1829,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1845,6 +1860,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) @@ -1873,6 +1889,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1881,6 +1898,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1903,8 +1921,8 @@ mod traits { } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end) @@ -1934,6 +1952,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1942,6 +1961,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1966,8 +1986,8 @@ mod traits { } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, slice.len()) @@ -2238,7 +2258,6 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "str_as_bytes", since = "1.32.0")] #[inline(always)] - // SAFETY: const sound because we transmute two types with the same layout #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn as_bytes(&self) -> &[u8] { @@ -2247,6 +2266,7 @@ impl str { str: &'a str, slice: &'a [u8], } + // SAFETY: const sound because we transmute two types with the same layout unsafe { Slices { str: self }.slice } } @@ -2573,6 +2593,7 @@ impl str { pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { + // SAFETY: just checked that `mid` is on a char boundary unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) } } else { slice_error_fail(self, 0, mid) @@ -2617,6 +2638,7 @@ impl str { if self.is_char_boundary(mid) { let len = self.len(); let ptr = self.as_mut_ptr(); + // SAFETY: just checked that `mid` is on a char boundary unsafe { ( from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), @@ -3805,8 +3827,8 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(i..j) } } @@ -3844,8 +3866,8 @@ impl str { if let Some((a, _)) = matcher.next_reject() { i = a; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(i..self.len()) } } @@ -3970,8 +3992,8 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(0..j) } } @@ -4166,6 +4188,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_uppercase(&mut self) { + // SAFETY: safe because we transmute two types with the same layout let me = unsafe { self.as_bytes_mut() }; me.make_ascii_uppercase() } @@ -4191,6 +4214,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { + // SAFETY: safe because we transmute two types with the same layout let me = unsafe { self.as_bytes_mut() }; me.make_ascii_lowercase() } @@ -4356,6 +4380,7 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str + // SAFETY: `str` is guranteed to be UTF-8 fn default() -> Self { unsafe { from_utf8_unchecked_mut(&mut []) } } @@ -4412,6 +4437,7 @@ impl_fn_for_zst! { #[derive(Clone)] struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str { + // SAFETY: not safe unsafe { from_utf8_unchecked(bytes) } }; } diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 46d9499394a38..ef64d8b0fdf88 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -3,8 +3,6 @@ //! For more details, see the traits [`Pattern`], [`Searcher`], //! [`ReverseSearcher`], and [`DoubleEndedSearcher`]. -// ignore-tidy-undocumented-unsafe - #![unstable( feature = "pattern", reason = "API not fully fleshed out and ready to be stabilized", @@ -271,6 +269,14 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { #[inline] fn next(&mut self) -> SearchStep { let old_finger = self.finger; + // SAFETY: 1-4 guarantee safety of `get_unchecked` + // 1. `self.finger` and `self.finger_back` are kept on unicode boundaries + // (this is invariant) + // 2. `self.finger >= 0` since it starts at 0 and only increases + // 3. `self.finger < self.finger_back` because otherwise the char `iter` + // would return `SearchStep::Done` + // 4. `self.finger` comes before the end of the haystack because `self.finger_back` + // starts at the end and only decreases let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) }; let mut iter = slice.chars(); let old_len = iter.iter.len(); @@ -293,6 +299,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { // get the haystack after the last character found let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?; // the last byte of the utf8 encoded needle + // SAFETY: we have an invariant that `utf8_size < 5` let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) }; if let Some(index) = memchr::memchr(last_byte, bytes) { // The new finger is the index of the byte we found, @@ -336,6 +343,7 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { #[inline] fn next_back(&mut self) -> SearchStep { let old_finger = self.finger_back; + // SAFETY: see the comment for next() above let slice = unsafe { self.haystack.get_unchecked(self.finger..old_finger) }; let mut iter = slice.chars(); let old_len = iter.iter.len(); @@ -363,6 +371,7 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { return None; }; // the last byte of the utf8 encoded needle + // SAFETY: we have an invariant that `utf8_size < 5` let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) }; if let Some(index) = memchr::memrchr(last_byte, bytes) { // we searched a slice that was offset by self.finger, diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index fae95ca5cdb36..889f182561b63 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -112,8 +112,6 @@ //! println!("live threads: {}", old_thread_count + 1); //! ``` -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))] @@ -350,6 +348,7 @@ impl AtomicBool { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut bool { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *(self.v.get() as *mut bool) } } @@ -400,6 +399,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.v.get(), order) != 0 } } @@ -432,6 +432,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.v.get(), val as u8, order); } @@ -463,6 +464,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn swap(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -558,6 +560,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { + // SAFETY: data races are prevented by atomic intrinsics match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) } { @@ -615,6 +618,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { + // SAFETY: data races are prevented by atomic intrinsics match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) } { @@ -661,6 +665,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -756,6 +761,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -797,6 +803,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -872,6 +879,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut *mut T { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *self.p.get() } } @@ -923,6 +931,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> *mut T { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T } } @@ -957,6 +966,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); } @@ -990,6 +1000,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } @@ -1074,6 +1085,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { let res = atomic_compare_exchange( self.p.get() as *mut usize, @@ -1137,6 +1149,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { let res = atomic_compare_exchange_weak( self.p.get() as *mut usize, @@ -1290,6 +1303,7 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5); #[inline] #[$stable_access] pub fn get_mut(&mut self) -> &mut $int_type { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *self.v.get() } } } @@ -1344,6 +1358,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5); #[inline] #[$stable] pub fn load(&self, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.v.get(), order) } } } @@ -1378,6 +1393,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.v.get(), val, order); } } } @@ -1408,6 +1424,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); #[$stable] #[$cfg_cas] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.v.get(), val, order) } } } @@ -1510,6 +1527,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } } @@ -1562,6 +1580,7 @@ loop { new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } @@ -1596,6 +1615,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_add(self.v.get(), val, order) } } } @@ -1628,6 +1648,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_sub(self.v.get(), val, order) } } } @@ -1663,6 +1684,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001); #[$stable] #[$cfg_cas] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_and(self.v.get(), val, order) } } } @@ -1699,6 +1721,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); #[$stable_nand] #[$cfg_cas] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_nand(self.v.get(), val, order) } } } @@ -1734,6 +1757,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111); #[$stable] #[$cfg_cas] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_or(self.v.get(), val, order) } } } @@ -1769,6 +1793,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); #[$stable] #[$cfg_cas] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_xor(self.v.get(), val, order) } } } @@ -1880,6 +1905,7 @@ assert!(max_foo == 42); issue = "48655")] #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { $max_fn(self.v.get(), val, order) } } } @@ -1932,6 +1958,7 @@ assert_eq!(min_foo, 12); issue = "48655")] #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { $min_fn(self.v.get(), val, order) } } } @@ -2526,6 +2553,7 @@ pub fn fence(order: Ordering) { // https://github.com/WebAssembly/tool-conventions/issues/59. We should // follow that discussion and implement a solution when one comes about! #[cfg(not(target_arch = "wasm32"))] + // SAFETY: using an atomic fence is safe unsafe { match order { Acquire => intrinsics::atomic_fence_acq(), @@ -2613,6 +2641,7 @@ pub fn fence(order: Ordering) { #[inline] #[stable(feature = "compiler_fences", since = "1.21.0")] pub fn compiler_fence(order: Ordering) { + // SAFETY: doesn't compile to machine code unsafe { match order { Acquire => intrinsics::atomic_singlethreadfence_acq(), From a93e99cae7c1e6352304f65be93f28f1b5713231 Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 19 Nov 2019 18:39:36 -0800 Subject: [PATCH 0430/1253] Fix typo "gurantees -> guarantees" --- src/libcore/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c530432f802db..f351735bef240 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -897,7 +897,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { - // SAFETY: `BorrowRef` gurantees unique access + // SAFETY: `BorrowRef` guarantees unique access Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } From e0140ffeb0a7378f6568f5b8efebcfc58278f03a Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 26 Dec 2019 11:57:57 -0800 Subject: [PATCH 0431/1253] Apply suggestions from code review Co-Authored-By: Ralf Jung --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3139d6188e27f..f89edf1910fac 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -659,7 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { - // SAFETY: Chars is only made from a str, which guarantees the iter is valid utf8 + // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid utf8 unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } From ca2fae8edbf0fce88e8e780d69745b26c856f4fc Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 26 Dec 2019 12:56:34 -0800 Subject: [PATCH 0432/1253] Elaborate on SAFETY comments --- src/libcore/cell.rs | 25 +++++++++----- src/libcore/str/lossy.rs | 9 ++--- src/libcore/str/mod.rs | 67 +++++++++++++++++++------------------- src/libcore/sync/atomic.rs | 64 ++++++++++++++++++------------------ 4 files changed, 88 insertions(+), 77 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f351735bef240..e7eecf7540ad7 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -366,7 +366,10 @@ impl Cell { if ptr::eq(self, other) { return; } - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can be risky if called from separate threads, but `Cell` + // is `!Sync` so this won't happen. This also won't invalidate any + // pointers since `Cell` makes sure nothing else will be pointing into + // either of these `Cell`s. unsafe { ptr::swap(self.value.get(), other.value.get()); } @@ -386,7 +389,8 @@ impl Cell { /// ``` #[stable(feature = "move_cell", since = "1.17.0")] pub fn replace(&self, val: T) -> T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. mem::replace(unsafe { &mut *self.value.get() }, val) } @@ -423,7 +427,8 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. unsafe { *self.value.get() } } @@ -492,7 +497,9 @@ impl Cell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees + // unique access. unsafe { &mut *self.value.get() } } @@ -512,7 +519,7 @@ impl Cell { #[inline] #[stable(feature = "as_cell", since = "1.37.0")] pub fn from_mut(t: &mut T) -> &Cell { - // SAFETY: `&mut` ensures unique access + // SAFETY: `&mut` ensures unique access. unsafe { &*(t as *mut T as *const Cell) } } } @@ -556,7 +563,7 @@ impl Cell<[T]> { /// ``` #[stable(feature = "as_cell", since = "1.37.0")] pub fn as_slice_of_cells(&self) -> &[Cell] { - // SAFETY: `Cell` has the same memory layout as `T` + // SAFETY: `Cell` has the same memory layout as `T`. unsafe { &*(self as *const Cell<[T]> as *const [Cell]) } } } @@ -821,7 +828,7 @@ impl RefCell { pub fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { // SAFETY: `BorrowRef` ensures that there is only immutable access - // to the value while borrowed + // to the value while borrowed. Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }), None => Err(BorrowError { _private: () }), } @@ -897,7 +904,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { - // SAFETY: `BorrowRef` guarantees unique access + // SAFETY: `BorrowRef` guarantees unique access. Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } @@ -947,7 +954,7 @@ impl RefCell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - // SAFETY: `&mut` guarantees unique access + // SAFETY: `&mut` guarantees unique access. unsafe { &mut *self.value.get() } } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 9d2e38734ef02..88b2bc551b7d1 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -15,7 +15,7 @@ impl Utf8Lossy { } pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy { - // SAFETY: both use the same memory layout, and UTF-8 correctness isn't required + // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required. unsafe { mem::transmute(bytes) } } @@ -59,7 +59,8 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { while i < self.source.len() { let i_ = i; - // SAFETY: 0 <= i < self.source.len() + // SAFETY: `i` starts at `0`, is less than `self.source.len()`, and + // only increases, so `0 <= i < self.source.len()`. let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; @@ -69,7 +70,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { macro_rules! error { () => {{ - // SAFETY: we have checked up to `i` that source is valid UTF-8 + // SAFETY: We have checked up to `i` that source is valid UTF-8. unsafe { let r = Utf8LossyChunk { valid: core_str::from_utf8_unchecked(&self.source[0..i_]), @@ -131,7 +132,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } let r = Utf8LossyChunk { - // SAFETY: we have checked that the entire source is valid UTF-8 + // SAFETY: We have checked that the entire source is valid UTF-8. valid: unsafe { core_str::from_utf8_unchecked(self.source) }, broken: &[], }; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f89edf1910fac..ec1713d1d4baa 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -340,7 +340,7 @@ impl Utf8Error { #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { run_utf8_validation(v)?; - // SAFETY: just ran validation + // SAFETY: Just ran validation. Ok(unsafe { from_utf8_unchecked(v) }) } @@ -379,7 +379,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { #[stable(feature = "str_mut_extras", since = "1.20.0")] pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { run_utf8_validation(v)?; - // SAFETY: just ran validation + // SAFETY: Just ran validation. Ok(unsafe { from_utf8_unchecked_mut(v) }) } @@ -582,7 +582,7 @@ impl<'a> Iterator for Chars<'a> { #[inline] fn next(&mut self) -> Option { next_code_point(&mut self.iter).map(|ch| { - // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value. unsafe { char::from_u32_unchecked(ch) } }) } @@ -629,7 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] fn next_back(&mut self) -> Option { next_code_point_reverse(&mut self.iter).map(|ch| { - // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value. unsafe { char::from_u32_unchecked(ch) } }) } @@ -659,7 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { - // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid utf8 + // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8. unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } @@ -1104,7 +1104,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { fn get_end(&mut self) -> Option<&'a str> { if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { self.finished = true; - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. unsafe { let string = self.matcher.haystack().get_unchecked(self.start..self.end); Some(string) @@ -1122,7 +1122,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match() { - // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries. Some((a, b)) => unsafe { let elt = haystack.get_unchecked(self.start..a); self.start = b; @@ -1155,13 +1155,13 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match_back() { - // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries. Some((a, b)) => unsafe { let elt = haystack.get_unchecked(b..self.end); self.end = a; Some(elt) }, - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. None => unsafe { self.finished = true; Some(haystack.get_unchecked(self.start..self.end)) @@ -1301,7 +1301,7 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { - // SAFETY: `Searcher` guaratees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1312,7 +1312,7 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match_back() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1356,7 +1356,7 @@ where impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0.next_match().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1368,7 +1368,7 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0.next_match_back().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1589,9 +1589,10 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { let ptr = v.as_ptr(); while index < blocks_end { - // SAFETY: since `align - index` and `ascii_block_size` are multiples of - // `usize_bytes`, `ptr.add(index)` is always aligned with a `usize` so we - // may cast directly to a `const` pointer. + // SAFETY: since `align - index` and `ascii_block_size` are + // multiples of `usize_bytes`, `block = ptr.add(index)` is + // always aligned with a `usize` so it's safe to dereference + // both `block` and `block.offset(1)`. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte @@ -1817,7 +1818,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1829,7 +1830,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1860,7 +1861,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) @@ -1889,7 +1890,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1898,7 +1899,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1922,7 +1923,7 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end) @@ -1952,7 +1953,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1961,7 +1962,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1987,7 +1988,7 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, slice.len()) @@ -2593,7 +2594,7 @@ impl str { pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { - // SAFETY: just checked that `mid` is on a char boundary + // SAFETY: just checked that `mid` is on a char boundary. unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) } } else { slice_error_fail(self, 0, mid) @@ -2638,7 +2639,7 @@ impl str { if self.is_char_boundary(mid) { let len = self.len(); let ptr = self.as_mut_ptr(); - // SAFETY: just checked that `mid` is on a char boundary + // SAFETY: just checked that `mid` is on a char boundary. unsafe { ( from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), @@ -3827,7 +3828,7 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(i..j) } @@ -3866,7 +3867,7 @@ impl str { if let Some((a, _)) = matcher.next_reject() { i = a; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(i..self.len()) } @@ -3992,7 +3993,7 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(0..j) } @@ -4188,7 +4189,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_uppercase(&mut self) { - // SAFETY: safe because we transmute two types with the same layout + // SAFETY: safe because we transmute two types with the same layout. let me = unsafe { self.as_bytes_mut() }; me.make_ascii_uppercase() } @@ -4214,7 +4215,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { - // SAFETY: safe because we transmute two types with the same layout + // SAFETY: safe because we transmute two types with the same layout. let me = unsafe { self.as_bytes_mut() }; me.make_ascii_lowercase() } @@ -4380,7 +4381,7 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str - // SAFETY: `str` is guranteed to be UTF-8 + // SAFETY: `str` is guranteed to be UTF-8. fn default() -> Self { unsafe { from_utf8_unchecked_mut(&mut []) } } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 889f182561b63..8d55dc55ef2d6 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -348,7 +348,7 @@ impl AtomicBool { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut bool { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *(self.v.get() as *mut bool) } } @@ -399,7 +399,8 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. unsafe { atomic_load(self.v.get(), order) != 0 } } @@ -432,7 +433,8 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. unsafe { atomic_store(self.v.get(), val as u8, order); } @@ -464,7 +466,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn swap(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -560,7 +562,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) } { @@ -618,7 +620,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) } { @@ -665,7 +667,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -761,7 +763,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -803,7 +805,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -879,7 +881,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut *mut T { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *self.p.get() } } @@ -931,7 +933,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> *mut T { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T } } @@ -966,7 +968,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); } @@ -1000,7 +1002,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } @@ -1085,7 +1087,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { let res = atomic_compare_exchange( self.p.get() as *mut usize, @@ -1149,7 +1151,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { let res = atomic_compare_exchange_weak( self.p.get() as *mut usize, @@ -1303,7 +1305,7 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5); #[inline] #[$stable_access] pub fn get_mut(&mut self) -> &mut $int_type { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *self.v.get() } } } @@ -1358,7 +1360,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5); #[inline] #[$stable] pub fn load(&self, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.v.get(), order) } } } @@ -1393,7 +1395,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.v.get(), val, order); } } } @@ -1424,7 +1426,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); #[$stable] #[$cfg_cas] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val, order) } } } @@ -1527,7 +1529,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } } @@ -1580,7 +1582,7 @@ loop { new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } @@ -1615,7 +1617,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.v.get(), val, order) } } } @@ -1648,7 +1650,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.v.get(), val, order) } } } @@ -1684,7 +1686,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001); #[$stable] #[$cfg_cas] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val, order) } } } @@ -1721,7 +1723,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); #[$stable_nand] #[$cfg_cas] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_nand(self.v.get(), val, order) } } } @@ -1757,7 +1759,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111); #[$stable] #[$cfg_cas] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val, order) } } } @@ -1793,7 +1795,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); #[$stable] #[$cfg_cas] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val, order) } } } @@ -1905,7 +1907,7 @@ assert!(max_foo == 42); issue = "48655")] #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { $max_fn(self.v.get(), val, order) } } } @@ -1958,7 +1960,7 @@ assert_eq!(min_foo, 12); issue = "48655")] #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { $min_fn(self.v.get(), val, order) } } } @@ -2553,7 +2555,7 @@ pub fn fence(order: Ordering) { // https://github.com/WebAssembly/tool-conventions/issues/59. We should // follow that discussion and implement a solution when one comes about! #[cfg(not(target_arch = "wasm32"))] - // SAFETY: using an atomic fence is safe + // SAFETY: using an atomic fence is safe. unsafe { match order { Acquire => intrinsics::atomic_fence_acq(), @@ -2641,7 +2643,7 @@ pub fn fence(order: Ordering) { #[inline] #[stable(feature = "compiler_fences", since = "1.21.0")] pub fn compiler_fence(order: Ordering) { - // SAFETY: doesn't compile to machine code + // SAFETY: using an atomic fence is safe. unsafe { match order { Acquire => intrinsics::atomic_singlethreadfence_acq(), From c103c284b93039149f0ec2a4f3d20ca89f34c0ad Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 18:38:04 -0800 Subject: [PATCH 0433/1253] Move comments for tidy --- src/libcore/str/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ec1713d1d4baa..3bfeee87cc013 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1301,9 +1301,9 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match() + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } @@ -1312,9 +1312,9 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match_back() + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } } @@ -3901,8 +3901,8 @@ impl str { "The first search step from Searcher \ must include the first character" ); + // SAFETY: `Searcher` is known to return valid indices. unsafe { - // Searcher is known to return valid indices. Some(self.get_unchecked(len..)) } } else { @@ -3942,8 +3942,8 @@ impl str { "The first search step from ReverseSearcher \ must include the last character" ); + // SAFETY: `Searcher` is known to return valid indices. unsafe { - // Searcher is known to return valid indices. Some(self.get_unchecked(..start)) } } else { @@ -4381,8 +4381,8 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str - // SAFETY: `str` is guranteed to be UTF-8. fn default() -> Self { + // SAFETY: The empty string is valid UTF-8. unsafe { from_utf8_unchecked_mut(&mut []) } } } From 0f2ee495e9a9d677466ce0c1827ba20919a5ca1f Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 18:50:53 -0800 Subject: [PATCH 0434/1253] Fix formatting: ./x.py fmt --- src/libcore/str/mod.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3bfeee87cc013..5a7cddd4041d5 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3829,9 +3829,7 @@ impl str { j = b; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(i..j) - } + unsafe { self.get_unchecked(i..j) } } /// Returns a string slice with all prefixes that match a pattern @@ -3868,9 +3866,7 @@ impl str { i = a; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(i..self.len()) - } + unsafe { self.get_unchecked(i..self.len()) } } /// Returns a string slice with the prefix removed. @@ -3902,9 +3898,7 @@ impl str { must include the first character" ); // SAFETY: `Searcher` is known to return valid indices. - unsafe { - Some(self.get_unchecked(len..)) - } + unsafe { Some(self.get_unchecked(len..)) } } else { None } @@ -3943,9 +3937,7 @@ impl str { must include the last character" ); // SAFETY: `Searcher` is known to return valid indices. - unsafe { - Some(self.get_unchecked(..start)) - } + unsafe { Some(self.get_unchecked(..start)) } } else { None } @@ -3994,9 +3986,7 @@ impl str { j = b; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(0..j) - } + unsafe { self.get_unchecked(0..j) } } /// Returns a string slice with all prefixes that match a pattern From 03240e1359f68bdddcdb236f3a89f9907b907449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 18:27:18 -0800 Subject: [PATCH 0435/1253] review comments --- src/librustc_errors/emitter.rs | 9 ++++---- src/librustc_errors/lib.rs | 21 ++++++++----------- .../miri_unleashed/mutable_const2.stderr | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index e37496f729952..b0e0cb611afaf 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,7 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; - if !suggestion.has_valid_spans(&**sm) { + + // Render the replacements for each suggestion + let suggestions = suggestion.splice_lines(&**sm); + + if suggestions.is_empty() { // Suggestions coming from macros can have malformed spans. This is a heavy handed // approach to avoid ICEs by ignoring the suggestion outright. return Ok(()); @@ -1497,9 +1501,6 @@ impl EmitterWriter { Some(Style::HeaderMsg), ); - // Render the replacements for each suggestion - let suggestions = suggestion.splice_lines(&**sm); - let mut row_num = 2; let mut notice_capitalization = false; for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 889c84d6da132..827e9b831f32d 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -144,18 +144,6 @@ pub struct SubstitutionPart { } impl CodeSuggestion { - /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach - /// to avoid ICEs by ignoring the suggestion outright. - pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { - !self.substitutions.iter().any(|subst| { - let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); - if invalid { - debug!("malformed span in suggestion: {:?}", subst); - } - invalid - }) - } - /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { @@ -187,6 +175,15 @@ impl CodeSuggestion { self.substitutions .iter() + .filter(|subst| { + // Suggestions coming from macros can have malformed spans. This is a heavy + // handed approach to avoid ICEs by ignoring the suggestion outright. + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("splice_lines: suggestion contains an invalid span: {:?}", subst); + } + !invalid + }) .cloned() .map(|mut substitution| { // Assumption: all spans are in the same file, and all spans diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index cc124058cfcb8..0d7fb845a40ee 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 022a7de26f5cb386ec853eec3b7f44dcd516a6d1 Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 19:26:02 -0800 Subject: [PATCH 0436/1253] Add SAFETY comment for atomic example --- src/libcore/sync/atomic.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8d55dc55ef2d6..9d449bb991507 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1989,7 +1989,9 @@ extern { } let mut atomic = ", stringify!($atomic_type), "::new(1); -unsafe { +", +// SAFETY: Safe as long as `my_atomic_op` is atomic. +"unsafe { my_atomic_op(atomic.as_mut_ptr()); } # } From b1d0c118ff726fc8c5ff2a5a19840a9e36e8940e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 16 Jan 2020 08:24:34 -0500 Subject: [PATCH 0437/1253] [self-profiler] Add example to `-Z help` to turn on query key recording Also add the `default` option so that it's easy to add query key recording to the default. --- src/librustc_data_structures/profiling.rs | 2 ++ src/librustc_session/options.rs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 004db0a79a880..44cef727f034b 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -136,9 +136,11 @@ bitflags::bitflags! { } } +// keep this in sync with the `-Z self-profile-events` help message in librustc_session/options.rs const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("none", EventFilter::NONE), ("all", EventFilter::ALL), + ("default", EventFilter::DEFAULT), ("generic-activity", EventFilter::GENERIC_ACTIVITIES), ("query-provider", EventFilter::QUERY_PROVIDERS), ("query-cache-hit", EventFilter::QUERY_CACHE_HITS), diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 4b5736adc17c3..2a0ed27b63b08 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -923,8 +923,12 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, parse_switch_with_opt_path, [UNTRACKED], "run the self profiler and output the raw event data"), + // keep this in sync with the event filter names in librustc_data_structures/profiling.rs self_profile_events: Option> = (None, parse_opt_comma_list, [UNTRACKED], - "specifies which kinds of events get recorded by the self profiler"), + "specifies which kinds of events get recorded by the self profiler; + for example: `-Z self-profile-events=default,query-keys` + all options: none, all, default, generic-activity, query-provider, query-cache-hit + query-blocked, incr-cache-load, query-keys"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emits a section containing stack size metadata"), plt: Option = (None, parse_opt_bool, [TRACKED], From 343eee6082a90016b315b82b048e5a6774472afe Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Tue, 7 Jan 2020 21:45:49 +0100 Subject: [PATCH 0438/1253] perf: Filter out and process fixed constraints first in region expansion Should reduce the number of elements as well as branches in the extremely hot loop and process_constraint in benchmarks such as unicode_normalization --- .../infer/lexical_region_resolve/mod.rs | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 0bc49a2901505..f4c1965a04179 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -295,30 +295,49 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - let mut process_constraint = |constraint: &Constraint<'tcx>| { - let (a_region, b_vid, b_data, retain) = match *constraint { + let mut changed = false; + let mut constraints = Vec::new(); + for constraint in self.data.constraints.keys() { + let (a_region, b_vid, b_data) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (a_region, b_vid, b_data, false) + (a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => return (false, false), + VarValue::ErrorValue => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); - let retain = match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => false, - _ => true, - }; - (a_region, b_vid, b_data, retain) + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => (), + _ => constraints.push((a_vid, b_vid)), + } + (a_region, b_vid, b_data) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - return (false, false); + continue; } }; + let edge_changed = self.expand_node(a_region, b_vid, b_data); + if edge_changed { + changed = true + } + } + let mut process_constraint = |a_vid, b_vid| { + let (a_region, b_data, retain) = match *var_values.value(a_vid) { + VarValue::ErrorValue => return (false, false), + VarValue::Value(a_region) => { + let b_data = var_values.value_mut(b_vid); + let retain = match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => false, + _ => true, + }; + (a_region, b_data, retain) + } + }; let changed = self.expand_node(a_region, b_vid, b_data); (changed, retain) }; @@ -326,15 +345,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Using bitsets to track the remaining elements is faster than using a // `Vec` by itself (which requires removing elements, which requires // element shuffling, which is slow). - let constraints: Vec<_> = self.data.constraints.keys().collect(); let mut live_indices: BitSet = BitSet::new_filled(constraints.len()); let mut killed_indices: BitSet = BitSet::new_empty(constraints.len()); - let mut changed = true; while changed { changed = false; for index in live_indices.iter() { - let constraint = constraints[index]; - let (edge_changed, retain) = process_constraint(constraint); + let (a_vid, b_vid) = constraints[index]; + let (edge_changed, retain) = process_constraint(a_vid, b_vid); changed |= edge_changed; if !retain { let changed = killed_indices.insert(index); @@ -790,8 +807,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.var_infos[node_idx].origin.span(), &format!( "collect_error_for_expanding_node() could not find \ - error for var {:?} in universe {:?}, lower_bounds={:#?}, \ - upper_bounds={:#?}", + error for var {:?} in universe {:?}, lower_bounds={:#?}, \ + upper_bounds={:#?}", node_idx, node_universe, lower_bounds, upper_bounds ), ); From 917eb187905591c5470cca3e742c17b0fbb495a2 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Wed, 8 Jan 2020 10:35:51 +0100 Subject: [PATCH 0439/1253] perf: Only search the potentially changed constraints in lexical_region_resolve --- .../infer/lexical_region_resolve/mod.rs | 79 +++++++------------ 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f4c1965a04179..18c25ef0dd9e1 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_hir::def_id::DefId; -use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::Span; use std::fmt; @@ -295,23 +294,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - let mut changed = false; - let mut constraints = Vec::new(); + let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len()); + let mut changes = Vec::new(); for constraint in self.data.constraints.keys() { - let (a_region, b_vid, b_data) = match *constraint { + let (a_vid, a_region, b_vid, b_data) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (a_region, b_vid, b_data) + (None, a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { VarValue::ErrorValue => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); - match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => (), - _ => constraints.push((a_vid, b_vid)), - } - (a_region, b_vid, b_data) + (Some(a_vid), a_region, b_vid, b_data) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { @@ -320,54 +315,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { continue; } }; - let edge_changed = self.expand_node(a_region, b_vid, b_data); - if edge_changed { - changed = true + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); + } + if let Some(a_vid) = a_vid { + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => (), + _ => { + constraints[a_vid].push((a_vid, b_vid)); + constraints[b_vid].push((a_vid, b_vid)); + } + } } } - let mut process_constraint = |a_vid, b_vid| { - let (a_region, b_data, retain) = match *var_values.value(a_vid) { - VarValue::ErrorValue => return (false, false), - VarValue::Value(a_region) => { - let b_data = var_values.value_mut(b_vid); - let retain = match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => false, - _ => true, - }; - (a_region, b_data, retain) + while let Some(vid) = changes.pop() { + constraints[vid].retain(|&(a_vid, b_vid)| { + let a_region = match *var_values.value(a_vid) { + VarValue::ErrorValue => return false, + VarValue::Value(a_region) => a_region, + }; + let b_data = var_values.value_mut(b_vid); + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); } - }; - let changed = self.expand_node(a_region, b_vid, b_data); - (changed, retain) - }; - - // Using bitsets to track the remaining elements is faster than using a - // `Vec` by itself (which requires removing elements, which requires - // element shuffling, which is slow). - let mut live_indices: BitSet = BitSet::new_filled(constraints.len()); - let mut killed_indices: BitSet = BitSet::new_empty(constraints.len()); - while changed { - changed = false; - for index in live_indices.iter() { - let (a_vid, b_vid) = constraints[index]; - let (edge_changed, retain) = process_constraint(a_vid, b_vid); - changed |= edge_changed; - if !retain { - let changed = killed_indices.insert(index); - debug_assert!(changed); + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => false, + _ => true, } - } - live_indices.subtract(&killed_indices); - - // We could clear `killed_indices` here, but we don't need to and - // it's cheaper not to. + }); } } - // This function is very hot in some workloads. There's a single callsite - // so always inlining is ok even though it's large. - #[inline(always)] fn expand_node( &self, a_region: Region<'tcx>, From c431cd751f6b0257443cd4d25c67ab36a8e9bc12 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 17 Jan 2020 08:13:04 -0500 Subject: [PATCH 0440/1253] Fix typo Co-Authored-By: Oliver Scherer --- src/librustc_mir/transform/const_prop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index badca10569404..5cbee929019dd 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -92,7 +92,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // // We manually filter the predicates, skipping anything that's not // "global". We are in a potentially generic context - // (e.g. we are evaluating a function without substituging generic + // (e.g. we are evaluating a function without substituting generic // parameters, so this filtering serves two purposes: // // 1. We skip evaluating any predicates that we would From 3fef3d8b76e70da88366e45a62f98592cf9be76c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 17 Jan 2020 08:22:40 -0500 Subject: [PATCH 0441/1253] Add @weiznich's regression test --- src/test/ui/consts/issue-68264-overflow.rs | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/ui/consts/issue-68264-overflow.rs diff --git a/src/test/ui/consts/issue-68264-overflow.rs b/src/test/ui/consts/issue-68264-overflow.rs new file mode 100644 index 0000000000000..8f21e0648d4c7 --- /dev/null +++ b/src/test/ui/consts/issue-68264-overflow.rs @@ -0,0 +1,43 @@ +// check-pass +// compile-flags: --emit=mir,link +// Regression test for issue #68264 +// Checks that we don't encounter overflow +// when running const-prop on functions with +// complicated bounds +pub trait Query {} + +pub trait AsQuery { + type Query: Query; +} +pub trait Table: AsQuery + Sized {} + +pub trait LimitDsl { + type Output; +} + +pub(crate) trait LoadQuery: RunQueryDsl {} + +impl AsQuery for T { + type Query = Self; +} + +impl LimitDsl for T +where + T: Table, + T::Query: LimitDsl, +{ + type Output = ::Output; +} + +pub(crate) trait RunQueryDsl: Sized { + fn first(self, _conn: &Conn) -> U + where + Self: LimitDsl, + Self::Output: LoadQuery, + { + // Overflow is caused by this function body + unimplemented!() + } +} + +fn main() {} From 34878d7b05813e090b370f48b8d437e4bd875094 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Fri, 17 Jan 2020 14:43:36 +0100 Subject: [PATCH 0442/1253] Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD and Solaris See ip(4P) man page: IP_MULTICAST_TTL Time to live for multicast datagrams. This option takes an unsigned character as an argument. Its value is the TTL that IP uses on outgoing multi- cast datagrams. The default is 1. IP_MULTICAST_LOOP Loopback for multicast datagrams. Normally multi- cast datagrams are delivered to members on the sending host (or sending zone). Setting the unsigned character argument to 0 causes the oppo- site behavior, meaning that when multiple zones are present, the datagrams are delivered to all zones except the sending zone. https://docs.oracle.com/cd/E88353_01/html/E37851/ip-4p.html https://man.openbsd.org/ip.4 --- src/libstd/sys_common/net.rs | 68 ++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index c7d4828892c04..32e392f1efc86 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -12,6 +12,10 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use libc::{c_int, c_void}; +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] +use libc::{c_uchar}; #[cfg(not(any( target_os = "dragonfly", @@ -565,24 +569,6 @@ impl UdpSocket { Ok(raw != 0) } - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } - pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int) } @@ -663,6 +649,52 @@ impl UdpSocket { } } +#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris")))] +impl UdpSocket { + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } +} + +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] +impl UdpSocket { + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_uchar) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_uchar) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } +} + impl FromInner for UdpSocket { fn from_inner(socket: Socket) -> UdpSocket { UdpSocket { inner: socket } From cdc828e7f92c5835db4188f27cbdb7170d32c94e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 17 Jan 2020 17:09:05 +0100 Subject: [PATCH 0443/1253] Stop treating `FalseEdges` and `FalseUnwind` as having semantic value for const eval --- .../transform/qualify_min_const_fn.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 7034556740849..d927553c72e8b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -309,7 +309,11 @@ fn check_terminator( ) -> McfResult { let span = terminator.source_info.span; match &terminator.kind { - TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume => Ok(()), + TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Goto { .. } + | TerminatorKind::Return + | TerminatorKind::Resume => Ok(()), TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body), TerminatorKind::DropAndReplace { location, value, .. } => { @@ -317,13 +321,10 @@ fn check_terminator( check_operand(tcx, value, span, def_id, body) } - TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } - if !feature_allowed(tcx, def_id, sym::const_if_match) => - { + TerminatorKind::SwitchInt { .. } if !feature_allowed(tcx, def_id, sym::const_if_match) => { Err((span, "loops and conditional expressions are not stable in const fn".into())) } - TerminatorKind::FalseEdges { .. } => Ok(()), TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => { check_operand(tcx, discr, span, def_id, body) } @@ -367,13 +368,5 @@ fn check_terminator( TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => { check_operand(tcx, cond, span, def_id, body) } - - TerminatorKind::FalseUnwind { .. } if feature_allowed(tcx, def_id, sym::const_loop) => { - Ok(()) - } - - TerminatorKind::FalseUnwind { .. } => { - Err((span, "loops are not allowed in const fn".into())) - } } } From a91f77ca26f65e566b93a0f086a894e60ec7c257 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 17 Jan 2020 14:21:14 +0000 Subject: [PATCH 0444/1253] Add regression test for integer literals in generic arguments in where clauses --- ...eger-literal-generic-arg-in-where-clause.rs | 18 ++++++++++++++++++ ...-literal-generic-arg-in-where-clause.stderr | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs new file mode 100644 index 0000000000000..30fbfda112c55 --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn takes_closure_of_array_3(f: F) where F: Fn([i32; 3]) { + f([1, 2, 3]); +} + +fn takes_closure_of_array_3_apit(f: impl Fn([i32; 3])) { + f([1, 2, 3]); +} + +fn returns_closure_of_array_3() -> impl Fn([i32; 3]) { + |_| {} +} + +fn main() {} diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr new file mode 100644 index 0000000000000..7f37f3e2791ec --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/integer-literal-generic-arg-in-where-clause.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From 9c6c2f16f00ed6f24866d2d4927b49d79b453a23 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:35:37 +0100 Subject: [PATCH 0445/1253] Clean up E0198 explanation --- src/librustc_error_codes/error_codes/E0198.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0198.md b/src/librustc_error_codes/error_codes/E0198.md index 6504d60dbd1d5..687214a205096 100644 --- a/src/librustc_error_codes/error_codes/E0198.md +++ b/src/librustc_error_codes/error_codes/E0198.md @@ -1,17 +1,18 @@ -A negative implementation is one that excludes a type from implementing a -particular trait. Not being able to use a trait is always a safe operation, -so negative implementations are always safe and never need to be marked as -unsafe. +A negative implementation was marked as unsafe. -```compile_fail -#![feature(optin_builtin_traits)] +Erroneous code example: +```compile_fail struct Foo; -// unsafe is unnecessary -unsafe impl !Clone for Foo { } +unsafe impl !Clone for Foo { } // error! ``` +A negative implementation is one that excludes a type from implementing a +particular trait. Not being able to use a trait is always a safe operation, +so negative implementations are always safe and never need to be marked as +unsafe. + This will compile: ```ignore (ignore auto_trait future compatibility warning) From 298e8ad5dc79ecb9b5b6140499e950d6ac5f09b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:49:03 +0100 Subject: [PATCH 0446/1253] Extend url in heading test a bit --- src/test/rustdoc/remove-url-from-headings.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs index 50e45a7f53a1e..9761c1ddbe23f 100644 --- a/src/test/rustdoc/remove-url-from-headings.rs +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -7,7 +7,7 @@ /// fooo /// -/// # Implementing [stuff](http://a.a) somewhere +/// # Implementing [stuff](http://a.a "title") somewhere /// /// hello /// From 482dc77dee59dd44448973758980806bd63aa5a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:51:07 +0100 Subject: [PATCH 0447/1253] formatting --- src/librustdoc/clean/mod.rs | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0e9f363bec3f3..20a5a6c54984d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,27 +2121,25 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - let make_item = |trait_: Option, for_: Type, items: Vec| { - Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided.clone(), - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - } + let make_item = |trait_: Option, for_: Type, items: Vec| Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_, + for_, + items, + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), }; if let Some(type_alias) = type_alias { ret.push(make_item(trait_.clone(), type_alias, items.clone())); From e8a4b9319cbf5b3f56b3cdd8ad11e86ff7168345 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:54:07 +0100 Subject: [PATCH 0448/1253] Clean up E0199 explanation --- src/librustc_error_codes/error_codes/E0199.md | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0199.md b/src/librustc_error_codes/error_codes/E0199.md index d0c12dc6f1755..88130e8e5e596 100644 --- a/src/librustc_error_codes/error_codes/E0199.md +++ b/src/librustc_error_codes/error_codes/E0199.md @@ -1,14 +1,23 @@ +A trait implementation was marked as unsafe while the trait is safe. + +Erroneous code example: + +```compile_fail,E0199 +struct Foo; + +trait Bar { } + +unsafe impl Bar for Foo { } // error! +``` + Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing -the unsafe marker on the trait noted in the error will resolve this problem. +the unsafe marker on the trait noted in the error will resolve this problem: -```compile_fail,E0199 +``` struct Foo; trait Bar { } -// this won't compile because Bar is safe -unsafe impl Bar for Foo { } -// this will compile -impl Bar for Foo { } +impl Bar for Foo { } // ok! ``` From 8fa8b81a7701ba8c14476d86b641d5cbe6cfa713 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 18 Jan 2020 00:34:33 +0300 Subject: [PATCH 0449/1253] Fix some tests failing in `--pass check` mode --- src/test/ui/consts/array-literal-index-oob.rs | 1 + .../ui/consts/array-literal-index-oob.stderr | 8 +++---- .../ui/consts/const-eval/promoted_errors.rs | 1 + .../consts/const-eval/promoted_errors.stderr | 20 ++++++++--------- .../ui/consts/const-eval/promoted_errors2.rs | 1 + .../consts/const-eval/promoted_errors2.stderr | 22 +++++++++---------- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs index 64aeb46894d16..af63d1f75a770 100644 --- a/src/test/ui/consts/array-literal-index-oob.rs +++ b/src/test/ui/consts/array-literal-index-oob.rs @@ -1,4 +1,5 @@ // build-pass +// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) #![warn(const_err)] diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr index 50ad8e83e905c..e93aa324784c3 100644 --- a/src/test/ui/consts/array-literal-index-oob.stderr +++ b/src/test/ui/consts/array-literal-index-oob.stderr @@ -1,17 +1,17 @@ warning: index out of bounds: the len is 3 but the index is 4 - --> $DIR/array-literal-index-oob.rs:6:8 + --> $DIR/array-literal-index-oob.rs:7:8 | LL | &{ [1, 2, 3][4] }; | ^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/array-literal-index-oob.rs:3:9 + --> $DIR/array-literal-index-oob.rs:4:9 | LL | #![warn(const_err)] | ^^^^^^^^^ warning: reaching this expression at runtime will panic or abort - --> $DIR/array-literal-index-oob.rs:6:8 + --> $DIR/array-literal-index-oob.rs:7:8 | LL | &{ [1, 2, 3][4] }; | ---^^^^^^^^^^^^-- @@ -19,7 +19,7 @@ LL | &{ [1, 2, 3][4] }; | indexing out of bounds: the len is 3 but the index is 4 warning: erroneous constant used - --> $DIR/array-literal-index-oob.rs:6:5 + --> $DIR/array-literal-index-oob.rs:7:5 | LL | &{ [1, 2, 3][4] }; | ^^^^^^^^^^^^^^^^^ referenced constant has errors diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index fee232185d29a..22f863fb15ac4 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -1,4 +1,5 @@ // build-pass +// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) // compile-flags: -O #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 4de22fdf4ab1e..b4330deb3ef10 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,59 +1,59 @@ warning: this expression will panic at runtime - --> $DIR/promoted_errors.rs:8:14 + --> $DIR/promoted_errors.rs:9:14 | LL | let _x = 0u32 - 1; | ^^^^^^^^ attempt to subtract with overflow | note: lint level defined here - --> $DIR/promoted_errors.rs:4:9 + --> $DIR/promoted_errors.rs:5:9 | LL | #![warn(const_err)] | ^^^^^^^^^ warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:10:20 + --> $DIR/promoted_errors.rs:11:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ warning: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:10:20 + --> $DIR/promoted_errors.rs:11:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ dividing by zero warning: erroneous constant used - --> $DIR/promoted_errors.rs:10:20 + --> $DIR/promoted_errors.rs:11:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ referenced constant has errors warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:14:14 + --> $DIR/promoted_errors.rs:15:14 | LL | let _x = 1 / (1 - 1); | ^^^^^^^^^^^ warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:16:20 + --> $DIR/promoted_errors.rs:17:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ warning: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:16:20 + --> $DIR/promoted_errors.rs:17:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ dividing by zero warning: erroneous constant used - --> $DIR/promoted_errors.rs:16:20 + --> $DIR/promoted_errors.rs:17:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ referenced constant has errors warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:20:14 + --> $DIR/promoted_errors.rs:21:14 | LL | let _x = 1 / (false as u32); | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs index 41a989d91c5d3..62c77f76d9064 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.rs +++ b/src/test/ui/consts/const-eval/promoted_errors2.rs @@ -1,4 +1,5 @@ // build-pass +// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors) // compile-flags: -C overflow-checks=on -O #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr index 4f7ba8bf385d3..a4dad295edd79 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr @@ -1,65 +1,65 @@ warning: attempt to subtract with overflow - --> $DIR/promoted_errors2.rs:7:20 + --> $DIR/promoted_errors2.rs:8:20 | LL | println!("{}", 0u32 - 1); | ^^^^^^^^ | note: lint level defined here - --> $DIR/promoted_errors2.rs:4:9 + --> $DIR/promoted_errors2.rs:5:9 | LL | #![warn(const_err)] | ^^^^^^^^^ warning: attempt to subtract with overflow - --> $DIR/promoted_errors2.rs:9:14 + --> $DIR/promoted_errors2.rs:10:14 | LL | let _x = 0u32 - 1; | ^^^^^^^^ warning: attempt to divide by zero - --> $DIR/promoted_errors2.rs:11:20 + --> $DIR/promoted_errors2.rs:12:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ warning: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors2.rs:11:20 + --> $DIR/promoted_errors2.rs:12:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ dividing by zero warning: erroneous constant used - --> $DIR/promoted_errors2.rs:11:20 + --> $DIR/promoted_errors2.rs:12:20 | LL | println!("{}", 1 / (1 - 1)); | ^^^^^^^^^^^ referenced constant has errors warning: attempt to divide by zero - --> $DIR/promoted_errors2.rs:15:14 + --> $DIR/promoted_errors2.rs:16:14 | LL | let _x = 1 / (1 - 1); | ^^^^^^^^^^^ warning: attempt to divide by zero - --> $DIR/promoted_errors2.rs:17:20 + --> $DIR/promoted_errors2.rs:18:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ warning: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors2.rs:17:20 + --> $DIR/promoted_errors2.rs:18:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ dividing by zero warning: erroneous constant used - --> $DIR/promoted_errors2.rs:17:20 + --> $DIR/promoted_errors2.rs:18:20 | LL | println!("{}", 1 / (false as u32)); | ^^^^^^^^^^^^^^^^^^ referenced constant has errors warning: attempt to divide by zero - --> $DIR/promoted_errors2.rs:21:14 + --> $DIR/promoted_errors2.rs:22:14 | LL | let _x = 1 / (false as u32); | ^^^^^^^^^^^^^^^^^^ From dda32e4e535fb3fb9e728b8c96386db7d231b247 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Fri, 17 Jan 2020 22:46:32 +0100 Subject: [PATCH 0450/1253] refactor fix using cfg_if! --- src/libstd/sys_common/net.rs | 175 +++++++++++------------------------ 1 file changed, 55 insertions(+), 120 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 32e392f1efc86..152da978bfd85 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -12,80 +12,43 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use libc::{c_int, c_void}; -#[cfg(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] -use libc::{c_uchar}; - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -)))] -use crate::sys::net::netc::IPV6_ADD_MEMBERSHIP; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -)))] -use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP; -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -))] -use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -))] -use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku" -))] -use libc::MSG_NOSIGNAL; -#[cfg(not(any( - target_os = "linux", - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku" -)))] -const MSG_NOSIGNAL: c_int = 0x0; + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris", target_os = "haiku", target_os = "l4re"))] { + use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; + use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; + } else { + use crate::sys::net::netc::IPV6_ADD_MEMBERSHIP; + use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP; + } +} + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "linux", target_os = "android", + target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "haiku"))] { + use libc::MSG_NOSIGNAL; + } else { + const MSG_NOSIGNAL: c_int = 0x0; + } +} + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] { + type ip_mcast_type_v4 = c_uchar; + } else { + type ip_mcast_type_v4 = c_int; + } +} //////////////////////////////////////////////////////////////////////////////// // sockaddr and misc bindings @@ -569,6 +532,24 @@ impl UdpSocket { Ok(raw != 0) } + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as ip_mcast_type_v4) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as ip_mcast_type_v4) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } + pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int) } @@ -649,52 +630,6 @@ impl UdpSocket { } } -#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris")))] -impl UdpSocket { - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } -} - -#[cfg(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] -impl UdpSocket { - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_uchar) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_uchar) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } -} - impl FromInner for UdpSocket { fn from_inner(socket: Socket) -> UdpSocket { UdpSocket { inner: socket } From 79061d0e02f70ecbf3333057eac36dcc6c4b1727 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Fri, 17 Jan 2020 23:44:44 +0000 Subject: [PATCH 0451/1253] rustdoc: Catch fatal errors when syntax highlighting For some errors the lexer will unwind so we need to handle that in addition to handling `token::Unknown`. --- src/librustdoc/html/highlight.rs | 5 +++-- src/librustdoc/passes/check_code_block_syntax.rs | 5 +++-- src/test/rustdoc-ui/invalid-syntax.rs | 6 ++++++ src/test/rustdoc-ui/invalid-syntax.stderr | 15 +++++++++++++++ src/test/rustdoc/bad-codeblock-syntax.rs | 7 +++++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index aa52b769c38ed..5bea1b5614159 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -41,7 +41,7 @@ pub fn render_with_highlighting( let fm = sess .source_map() .new_source_file(FileName::Custom(String::from("rustdoc-highlighting")), src.to_owned()); - let highlight_result = { + let highlight_result = rustc_driver::catch_fatal_errors(|| { let lexer = lexer::StringReader::new(&sess, fm, None); let mut classifier = Classifier::new(lexer, sess.source_map()); @@ -51,7 +51,8 @@ pub fn render_with_highlighting( } else { Ok(String::from_utf8_lossy(&highlighted_source).into_owned()) } - }; + }) + .unwrap_or(Err(())); match highlight_result { Ok(highlighted_source) => { diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 0bab4423b3dfd..2903fd9dcd660 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -40,7 +40,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { dox[code_block.code].to_owned(), ); - let validation_status = { + let validation_status = rustc_driver::catch_fatal_errors(|| { let mut has_syntax_errors = false; let mut only_whitespace = true; // even if there is a syntax error, we need to run the lexer over the whole file @@ -61,7 +61,8 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { } else { None } - }; + }) + .unwrap_or(Some(CodeBlockInvalid::SyntaxError)); if let Some(code_block_invalid) = validation_status { let mut diag = if let Some(sp) = diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs index 34e92c421047d..72037dd74be35 100644 --- a/src/test/rustdoc-ui/invalid-syntax.rs +++ b/src/test/rustdoc-ui/invalid-syntax.rs @@ -93,3 +93,9 @@ pub fn empty_rust_with_whitespace() {} /// pub fn indent_after_fenced() {} //~^^^ WARNING could not parse code block as Rust code + +/// ``` +/// "invalid +/// ``` +pub fn invalid() {} +//~^^^^ WARNING could not parse code block as Rust code diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr index 32cc20755ecf4..a90d3bbb979f6 100644 --- a/src/test/rustdoc-ui/invalid-syntax.stderr +++ b/src/test/rustdoc-ui/invalid-syntax.stderr @@ -132,3 +132,18 @@ LL | /// \____/ | = note: error from rustc: unknown start of token: \ +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:97:5 + | +LL | /// ``` + | _____^ +LL | | /// "invalid +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unterminated double quote string +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ^^^^^^^ + diff --git a/src/test/rustdoc/bad-codeblock-syntax.rs b/src/test/rustdoc/bad-codeblock-syntax.rs index ae8fbe4a2a800..afef86ec9c77f 100644 --- a/src/test/rustdoc/bad-codeblock-syntax.rs +++ b/src/test/rustdoc/bad-codeblock-syntax.rs @@ -33,3 +33,10 @@ pub fn ok() {} /// /// ``` pub fn escape() {} + +// @has bad_codeblock_syntax/fn.unterminated.html +// @has - '//*[@class="docblock"]/pre/code' '"unterminated' +/// ``` +/// "unterminated +/// ``` +pub fn unterminated() {} From 239a7d9124ee486e9d0096429136d719437b83b2 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Sat, 18 Jan 2020 00:38:37 +0100 Subject: [PATCH 0452/1253] refactor fix using cfg_if! (fix build) --- src/libstd/sys_common/net.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 152da978bfd85..7e603a8682ba5 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -44,9 +44,9 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris"))] { - type ip_mcast_type_v4 = c_uchar; + type IpV4MultiCastType = c_uchar; } else { - type ip_mcast_type_v4 = c_int; + type IpV4MultiCastType = c_int; } } @@ -533,20 +533,30 @@ impl UdpSocket { } pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as ip_mcast_type_v4) + setsockopt( + &self.inner, + c::IPPROTO_IP, + c::IP_MULTICAST_LOOP, + multicast_loop_v4 as IpV4MultiCastType, + ) } pub fn multicast_loop_v4(&self) -> io::Result { - let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; Ok(raw != 0) } pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as ip_mcast_type_v4) + setsockopt( + &self.inner, + c::IPPROTO_IP, + c::IP_MULTICAST_TTL, + multicast_ttl_v4 as IpV4MultiCastType, + ) } pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; Ok(raw as u32) } From d461e6d6cbd0c716f8b7e951285507451611df59 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:20 -0800 Subject: [PATCH 0453/1253] Use named fields for `ast::ItemKind::Impl` --- src/librustc/hir/map/mod.rs | 2 +- src/librustc_ast_lowering/item.rs | 21 ++++++++-------- src/librustc_ast_passes/ast_validation.rs | 24 +++++++++++++++---- src/librustc_ast_passes/feature_gate.rs | 2 +- .../deriving/generic/mod.rs | 16 ++++++------- src/librustc_builtin_macros/deriving/mod.rs | 16 ++++++------- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/internal.rs | 2 +- src/librustc_parse/parser/item.rs | 20 ++++++++-------- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/def_collector.rs | 2 +- src/librustc_resolve/late.rs | 16 ++++++------- src/librustc_save_analysis/dump_visitor.rs | 4 ++-- src/librustc_save_analysis/lib.rs | 12 +++++----- src/librustc_save_analysis/sig.rs | 14 +++++------ src/libsyntax/ast.rs | 23 ++++++++++-------- src/libsyntax/mut_visit.rs | 14 ++++++++--- src/libsyntax/print/pprust.rs | 16 ++++++------- src/libsyntax/visit.rs | 16 +++++++++---- 19 files changed, 130 insertions(+), 94 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 46c5ee272d235..8b4f0c6bde2b5 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -821,7 +821,7 @@ impl<'hir> Map<'hir> { | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) - | ItemKind::Impl(..) => true, + | ItemKind::Impl { .. } => true, _ => false, }, Node::ForeignItem(fi) => match fi.kind { diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index beb53a19ac4ff..648c4f7e46aad 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -67,14 +67,15 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { if let Some(hir_id) = item_hir_id { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind { - if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + if let ItemKind::Impl { ref of_trait, .. } = item.kind { + if of_trait.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); this.lctx .diagnostic() .span_err(item.span, "const trait impls are not yet implemented"); } - this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item)); + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); } else { visit::walk_item(this, item); } @@ -173,7 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> { vec } ItemKind::MacroDef(..) => SmallVec::new(), - ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id], + ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id], ItemKind::Static(ref ty, ..) => { let mut ids = smallvec![i.id]; if self.sess.features_untracked().impl_trait_in_bindings { @@ -361,15 +362,15 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(generics, ImplTraitContext::disallowed()), ) } - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, - ref ast_generics, - ref trait_ref, - ref ty, - ref impl_items, - ) => { + generics: ref ast_generics, + of_trait: ref trait_ref, + self_ty: ref ty, + items: ref impl_items, + } => { let def_id = self.resolver.definitions().local_def_id(id); // Lower the "impl header" first. This ordering is important diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index c915b7ba21692..23701459025ae 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -612,9 +612,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } match item.kind { - ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness: _, + generics: _, + of_trait: Some(_), + ref self_ty, + ref items, + } => { self.invalid_visibility(&item.vis, None); - if let TyKind::Err = ty.kind { + if let TyKind::Err = self_ty.kind { self.err_handler() .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") .help("use `auto trait Trait {}` instead") @@ -629,7 +637,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ) .emit(); } - for impl_item in impl_items { + for impl_item in items { self.invalid_visibility(&impl_item.vis, None); if let AssocItemKind::Fn(ref sig, _) = impl_item.kind { self.check_trait_fn_not_const(sig.header.constness); @@ -637,7 +645,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness, + generics: _, + of_trait: None, + self_ty: _, + items: _, + } => { self.invalid_visibility( &item.vis, Some("place qualifiers on individual impl items instead"), diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 1e4b1ae077762..71cd66ddef409 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -339,7 +339,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(_, polarity, defaultness, ..) => { + ast::ItemKind::Impl { polarity, defaultness, .. } => { if polarity == ast::ImplPolarity::Negative { gate_feature_post!( &self, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 9226f45816506..d346dbc8b4ee7 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -705,15 +705,15 @@ impl<'a> TraitDef<'a> { self.span, Ident::invalid(), a, - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, - trait_generics, - opt_trait_ref, - self_type, - methods.into_iter().chain(associated_types).collect(), - ), + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + generics: trait_generics, + of_trait: opt_trait_ref, + self_ty: self_type, + items: methods.into_iter().chain(associated_types).collect(), + }, ) } diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 4d83a6635ab17..9aa7623dc9f77 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -156,15 +156,15 @@ fn inject_impl_of_structural_trait( span, ast::Ident::invalid(), attrs, - ItemKind::Impl( - ast::Unsafety::Normal, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, + ItemKind::Impl { + unsafety: ast::Unsafety::Normal, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, generics, - Some(trait_ref), - self_type, - Vec::new(), - ), + of_trait: Some(trait_ref), + self_ty: self_type, + items: Vec::new(), + }, ); push(Annotatable::Item(newitem)); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6314c2b99539a..a15f69d7d51eb 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -251,7 +251,7 @@ impl EarlyLintPass for UnsafeCode { self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait") } - ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => { + ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => { self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait") } diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 5a5aedc2e9715..91aeccbb5e334 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -221,7 +221,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]); impl EarlyLintPass for LintPassImpl { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.kind { + if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index d4756dff49a9d..1921a6c850689 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -634,15 +634,15 @@ impl<'a> Parser<'a> { let constness = constness.map(|c| c.node); let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - Some(trait_ref), - ty_second, - impl_items, - ) + of_trait: Some(trait_ref), + self_ty: ty_second, + items: impl_items, + } } None => { // Reject `impl const Type {}` here @@ -653,15 +653,15 @@ impl<'a> Parser<'a> { } // impl Type - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - None, - ty_first, - impl_items, - ) + of_trait: None, + self_ty: ty_first, + items: impl_items, + } } }; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e8ed64a18702d..40a89ef067458 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -815,7 +815,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items do not add names to modules. - ItemKind::Impl(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} + ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(), } diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index f564ea644bdc1..696ba0e994c7d 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let def_data = match &i.kind { - ItemKind::Impl(..) => DefPathData::Impl, + ItemKind::Impl { .. } => DefPathData::Impl, ItemKind::Mod(..) if i.ident.name == kw::Invalid => { return visit::walk_item(self, i); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index defca4944bcd8..08cd9c4d1d53a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -797,14 +797,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.resolve_adt(item, generics); } - ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => { - self.resolve_implementation( - generics, - opt_trait_ref, - &self_type, - item.id, - impl_items, - ) + ItemKind::Impl { + ref generics, + ref of_trait, + ref self_ty, + items: ref impl_items, + .. + } => { + self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items); } ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2f2ba560fa20a..d252fc542c325 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1300,8 +1300,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.process_struct(item, def, ty_params) } Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - Impl(.., ref ty_params, ref trait_ref, ref typ, ref impl_items) => { - self.process_impl(item, ty_params, trait_ref, &typ, impl_items) + Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => { + self.process_impl(item, generics, of_trait, &self_ty, items) } Trait(_, _, ref generics, ref trait_refs, ref methods) => { self.process_trait(item, generics, trait_refs, methods) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c3221d925bc3b..5412533fce7d8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -305,8 +305,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => { - if let ast::TyKind::Path(None, ref path) = typ.kind { + ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => { + if let ast::TyKind::Path(None, ref path) = self_ty.kind { // Common case impl for a struct or something basic. if generated_code(path.span) { return None; @@ -317,14 +317,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let impl_id = self.next_impl_id(); let span = self.span_from_span(sub_span); - let type_data = self.lookup_def_id(typ.id); + let type_data = self.lookup_def_id(self_ty.id); type_data.map(|type_data| { Data::RelationData( Relation { kind: RelationKind::Impl { id: impl_id }, span: span.clone(), from: id_from_def_id(type_data), - to: trait_ref + to: of_trait .as_ref() .and_then(|t| self.lookup_def_id(t.ref_id)) .map(id_from_def_id) @@ -332,14 +332,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }, Impl { id: impl_id, - kind: match *trait_ref { + kind: match *of_trait { Some(_) => ImplKind::Direct, None => ImplKind::Inherent, }, span: span, value: String::new(), parent: None, - children: impls + children: items .iter() .map(|i| id_from_node_id(i.id, self)) .collect(), diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index e7b86cfba4f7d..779d3f55018d5 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -482,15 +482,15 @@ impl Sig for ast::Item { Ok(sig) } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - _, - ) => { + ref of_trait, + ref self_ty, + items: _, + } => { let mut text = String::new(); if let ast::Defaultness::Default = defaultness { text.push_str("default "); @@ -505,7 +505,7 @@ impl Sig for ast::Item { text.push(' '); - let trait_sig = if let Some(ref t) = *opt_trait { + let trait_sig = if let Some(ref t) = *of_trait { if polarity == ast::ImplPolarity::Negative { text.push('!'); } @@ -517,7 +517,7 @@ impl Sig for ast::Item { text_sig(String::new()) }; - let ty_sig = ty.make(offset + text.len(), id, scx)?; + let ty_sig = self_ty.make(offset + text.len(), id, scx)?; text.push_str(&ty_sig.text); text.push_str(" {}"); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 331eb109ec0b4..a5a4eb1583bed 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2614,15 +2614,18 @@ pub enum ItemKind { /// An implementation. /// /// E.g., `impl Foo { .. }` or `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics, - Option, // (optional) trait this impl implements - P, // self - Vec, - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics, + + /// The trait being implemented, if any. + of_trait: Option, + + self_ty: P, + items: Vec, + }, /// A macro invocation. /// /// E.g., `foo!(..)`. @@ -2649,7 +2652,7 @@ impl ItemKind { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item", + ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item", } } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 58d4e46111b83..750d054e8a0f2 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -918,10 +918,18 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { vis.visit_variant_data(variant_data); vis.visit_generics(generics); } - ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + generics, + of_trait, + self_ty, + items, + } => { vis.visit_generics(generics); - visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref)); - vis.visit_ty(ty); + visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); + vis.visit_ty(self_ty); items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); } ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 11c8cb8ef7500..bc67980c454c0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1226,15 +1226,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - ref impl_items, - ) => { + ref of_trait, + ref self_ty, + ref items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -1250,19 +1250,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = *opt_trait { + if let Some(ref t) = *of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(ty); + self.print_type(self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.print_assoc_item(impl_item); } self.bclose(item.span); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3c2ebacbc4e34..d03a9dfc16758 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -308,11 +308,19 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); visitor.visit_enum_def(enum_definition, generics, item.id, item.span) } - ItemKind::Impl(_, _, _, ref generics, ref opt_trait_reference, ref typ, ref impl_items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + ref generics, + ref of_trait, + ref self_ty, + ref items, + } => { visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item, impl_items); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { From 766f6c5d0ad5c71f42ab3a305572bf1e7b5edafa Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Fri, 17 Jan 2020 16:11:52 -0800 Subject: [PATCH 0454/1253] Actually pass target LLVM args to LLVM --- src/librustc_codegen_llvm/llvm_util.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 52613fef7e612..4823fe10c463f 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -58,9 +58,10 @@ unsafe fn configure_llvm(sess: &Session) { let cg_opts = sess.opts.cg.llvm_args.iter(); let tg_opts = sess.target.target.options.llvm_args.iter(); + let sess_args = cg_opts.chain(tg_opts); let user_specified_args: FxHashSet<_> = - cg_opts.chain(tg_opts).map(|s| llvm_arg_to_arg_name(s)).filter(|s| s.len() > 0).collect(); + sess_args.clone().map(|s| llvm_arg_to_arg_name(s)).filter(|s| s.len() > 0).collect(); { // This adds the given argument to LLVM. Unless `force` is true @@ -107,7 +108,7 @@ unsafe fn configure_llvm(sess: &Session) { // during inlining. Unfortunately these may block other optimizations. add("-preserve-alignment-assumptions-during-inlining=false", false); - for arg in &sess.opts.cg.llvm_args { + for arg in sess_args { add(&(*arg), true); } } From 4743995ed3f7a60e5e0b66eb6a095483883d8c90 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 17 Jan 2020 16:14:29 -0800 Subject: [PATCH 0455/1253] Use named fields for `hir::ItemKind::Impl` --- src/librustc/hir/check_attr.rs | 4 +- src/librustc/hir/map/mod.rs | 6 +-- src/librustc/infer/error_reporting/mod.rs | 2 +- .../traits/error_reporting/suggestions.rs | 5 +-- src/librustc/traits/util.rs | 2 +- src/librustc/traits/wf.rs | 8 ++-- src/librustc_ast_lowering/item.rs | 14 +++--- src/librustc_hir/hir.rs | 25 ++++++----- src/librustc_hir/intravisit.rs | 16 +++++-- src/librustc_hir/print.rs | 16 +++---- .../persist/dirty_clean.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_metadata/rmeta/encoder.rs | 14 +++--- src/librustc_mir/monomorphize/collector.rs | 6 +-- src/librustc_passes/dead.rs | 8 ++-- src/librustc_passes/reachable.rs | 10 ++--- src/librustc_passes/stability.rs | 10 ++--- src/librustc_privacy/lib.rs | 44 +++++++++---------- src/librustc_resolve/lifetimes.rs | 10 ++--- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_traits/lowering/environment.rs | 4 +- src/librustc_ty/ty.rs | 8 ++-- src/librustc_typeck/check/mod.rs | 10 +---- src/librustc_typeck/check/wfcheck.rs | 6 +-- src/librustc_typeck/coherence/builtin.rs | 9 ++-- .../coherence/inherent_impls.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/coherence/unsafety.rs | 2 +- src/librustc_typeck/collect.rs | 36 +++++++-------- src/librustc_typeck/impl_wf_check.rs | 6 +-- src/librustdoc/clean/inline.rs | 8 ++-- src/librustdoc/test.rs | 4 +- src/librustdoc/visit_ast.rs | 18 ++++---- 33 files changed, 166 insertions(+), 161 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 5a99e7965538b..5a4d7ceea2734 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -112,7 +112,7 @@ impl Target { ItemKind::Union(..) => Target::Union, ItemKind::Trait(..) => Target::Trait, ItemKind::TraitAlias(..) => Target::TraitAlias, - ItemKind::Impl(..) => Target::Impl, + ItemKind::Impl { .. } => Target::Impl, } } @@ -144,7 +144,7 @@ impl Target { let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id); let containing_item = tcx.hir().expect_item(parent_hir_id); let containing_impl_is_for_trait = match &containing_item.kind { - hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(), + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), }; if containing_impl_is_for_trait { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 8b4f0c6bde2b5..6d7f53133a666 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -341,7 +341,7 @@ impl<'hir> Map<'hir> { | ItemKind::Use(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) - | ItemKind::Impl(..) => return None, + | ItemKind::Impl { .. } => return None, }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Fn(..) => DefKind::Fn, @@ -604,7 +604,7 @@ impl<'hir> Map<'hir> { | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, ..) | ItemKind::TraitAlias(ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) => Some(generics), + | ItemKind::Impl { ref generics, .. } => Some(generics), _ => None, }, _ => None, @@ -1332,7 +1332,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", }; format!("{} {}{}", item_str, path_str(), id_str) } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index febf4f21a6755..a2009461fa568 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -254,7 +254,7 @@ fn emit_msg_span( fn item_scope_tag(item: &hir::Item<'_>) -> &'static str { match item.kind { - hir::ItemKind::Impl(..) => "impl", + hir::ItemKind::Impl { .. } => "impl", hir::ItemKind::Struct(..) => "struct", hir::ItemKind::Union(..) => "union", hir::ItemKind::Enum(..) => "enum", diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index bf6891214ace1..c09fd3079731c 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -88,8 +88,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), - .. + kind: hir::ItemKind::Impl { generics, .. }, .. }) if projection.is_some() => { // Missing associated type bound. suggest_restriction(&generics, "the associated type", err); @@ -115,7 +114,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), + kind: hir::ItemKind::Impl { generics, .. }, span, .. }) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 65fd809657bd0..f058a4d2df24a 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -651,7 +651,7 @@ pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool { match tcx.hir().as_local_hir_id(node_item_def_id) { Some(hir_id) => { let item = tcx.hir().expect_item(hir_id); - if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind { + if let hir::ItemKind::Impl { defaultness, .. } = item.kind { defaultness.is_default() } else { false diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 2301395f557f1..869ba5315c1ae 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -229,9 +229,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | // = note: expected type `u32` // found type `()` - if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) { + if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) { let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item) = impl_items + if let Some(impl_item) = items .iter() .filter(|item| item.ident == trait_assoc_item.ident) .next() @@ -279,14 +279,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool` if let ( ty::Projection(ty::ProjectionTy { item_def_id, .. }), - Some(hir::ItemKind::Impl(.., impl_items)), + Some(hir::ItemKind::Impl { items, .. }), ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { if let Some((impl_item, trait_assoc_item)) = trait_assoc_items .filter(|i| i.def_id == *item_def_id) .next() .and_then(|trait_assoc_item| { - impl_items + items .iter() .filter(|i| i.ident == trait_assoc_item.ident) .next() diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 648c4f7e46aad..6da2d457f3c3b 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -119,7 +119,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let old_len = self.in_scope_lifetimes.len(); let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind { - hir::ItemKind::Impl(_, _, _, ref generics, ..) + hir::ItemKind::Impl { ref generics, .. } | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..], _ => &[], }; @@ -418,15 +418,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, - self.lower_defaultness(defaultness, true /* [1] */), + defaultness: self.lower_defaultness(defaultness, true /* [1] */), generics, - trait_ref, - lowered_ty, - new_impl_items, - ) + of_trait: trait_ref, + self_ty: lowered_ty, + items: new_impl_items, + } } ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => { let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed()); diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 5c1d600c837c4..1fef871b5140e 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2436,15 +2436,18 @@ pub enum ItemKind<'hir> { TraitAlias(Generics<'hir>, GenericBounds<'hir>), /// An implementation, e.g., `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics<'hir>, - Option>, // (optional) trait this impl implements - &'hir Ty<'hir>, // self - &'hir [ImplItemRef<'hir>], - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics<'hir>, + + /// The trait being implemented, if any. + of_trait: Option>, + + self_ty: &'hir Ty<'hir>, + items: &'hir [ImplItemRef<'hir>], + }, } impl ItemKind<'_> { @@ -2465,7 +2468,7 @@ impl ItemKind<'_> { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", } } @@ -2478,7 +2481,7 @@ impl ItemKind<'_> { | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, _, _) - | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics, + | ItemKind::Impl { ref generics, .. } => generics, _ => return None, }) } diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 3dbc5253a9abf..1a73e41db9da5 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -566,12 +566,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span) } - ItemKind::Impl(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => { + ItemKind::Impl { + unsafety: _, + defaultness: _, + polarity: _, + ref generics, + ref of_trait, + ref self_ty, + items, + } => { visitor.visit_id(item.hir_id); visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item_ref, impl_item_refs); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item_ref, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 759f423070aa0..6c7d419395317 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -627,15 +627,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident.name, item.span, true); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - impl_items, - ) => { + ref of_trait, + ref self_ty, + items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -651,19 +651,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = opt_trait { + if let Some(ref t) = of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(&ty); + self.print_type(&self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.ann.nested(self, Nested::ImplItem(impl_item.id)); } self.bclose(item.span); diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index ddfed53fa3349..c5e74868bda4a 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -315,7 +315,7 @@ impl DirtyCleanVisitor<'tcx> { //HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT), // An implementation, eg `impl Trait for Foo { .. }` - HirItem::Impl(..) => ("ItemKind::Impl", LABELS_IMPL), + HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL), _ => self.tcx.sess.span_fatal( attr.span, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a15f69d7d51eb..c8d3d5f9c83d8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -431,7 +431,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { "a trait" } hir::ItemKind::TyAlias(..) => "a type alias", - hir::ItemKind::Impl(.., Some(ref trait_ref), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => { // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. let real_trait = trait_ref.path.res.def_id(); @@ -439,7 +439,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { match cx.tcx.hir().find(hir_id) { Some(Node::Item(item)) => { if let hir::VisibilityKind::Inherited = item.vis.node { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { self.private_traits.insert(impl_item_ref.id.hir_id); } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 8ad92ce75a851..9d2bea28c8c2e 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1073,7 +1073,7 @@ impl EncodeContext<'tcx> { ctor: None, }), adt_def.repr) } - hir::ItemKind::Impl(_, _, defaultness, ..) => { + hir::ItemKind::Impl { defaultness, .. } => { let trait_ref = self.tcx.impl_trait_ref(def_id); let polarity = self.tcx.impl_polarity(def_id); let parent = if let Some(trait_ref) = trait_ref { @@ -1149,7 +1149,7 @@ impl EncodeContext<'tcx> { }) ) } - hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record!(self.per_def.children[def_id] <- associated_item_def_ids.iter().map(|&def_id| { @@ -1172,13 +1172,13 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) => self.encode_item_type(def_id), + | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id), _ => {} } if let hir::ItemKind::Fn(..) = item.kind { record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); } - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); } @@ -1199,7 +1199,7 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => { @@ -1645,7 +1645,7 @@ impl EncodeContext<'tcx> { hir::ItemKind::Union(..) => { self.encode_fields(def_id); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() { self.encode_info_for_impl_item(trait_item_def_id); } @@ -1666,7 +1666,7 @@ struct ImplVisitor<'tcx> { impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 85377180bea46..f4611c32e0a32 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -954,7 +954,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { // Nothing to do, just keep recursing. } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { create_mono_items_for_default_impls(self.tcx, item, self.output); } @@ -1098,7 +1098,7 @@ fn create_mono_items_for_default_impls<'tcx>( output: &mut Vec>, ) { match item.kind { - hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => { + hir::ItemKind::Impl { ref generics, ref items, .. } => { for param in generics.params { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} @@ -1119,7 +1119,7 @@ fn create_mono_items_for_default_impls<'tcx>( let param_env = ty::ParamEnv::reveal_all(); let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); let overridden_methods: FxHashSet<_> = - impl_item_refs.iter().map(|iiref| iiref.ident.modern()).collect(); + items.iter().map(|iiref| iiref.ident.modern()).collect(); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains(&method.ident.modern()) { continue; diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index f2778b2aa6bcd..2ff9d744f2c4d 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -405,10 +405,10 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> { } } } - hir::ItemKind::Impl(.., ref opt_trait, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { let impl_item = self.krate.impl_item(impl_item_ref.id); - if opt_trait.is_some() + if of_trait.is_some() || has_allow_dead_code_or_lang_attr( self.tcx, impl_item.hir_id, @@ -586,7 +586,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::Impl(..) => { + | hir::ItemKind::Impl { .. } => { // FIXME(66095): Because item.span is annotated with things // like expansion data, and ident.span isn't, we use the // def_span method if it's part of a macro invocation diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index 5ce677f52cea6..667898046ac36 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -35,7 +35,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: Codegen hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => { return true; } - hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => { let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id)); generics.requires_monomorphization(tcx) } @@ -181,7 +181,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // does too. let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap(); match self.tcx.hir().expect_item(impl_hir_id).kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { let generics = self.tcx.generics_of(impl_did); generics.requires_monomorphization(self.tcx) } @@ -266,7 +266,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Struct(..) @@ -349,9 +349,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx } // We need only trait impls here, not inherent impls, and only non-exported ones - if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind { if !self.access_levels.is_reachable(item.hir_id) { - self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id)); + self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id)); let trait_def_id = match trait_ref.path.res { Res::Def(DefKind::Trait, def_id) => def_id, diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 5ec7e73f873e0..b649f36f2fc58 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -219,11 +219,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => { + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => { self.in_trait_impl = false; kind = AnnotationKind::Container; } - hir::ItemKind::Impl(.., Some(_), _, _) => { + hir::ItemKind::Impl { of_trait: Some(_), .. } => { self.in_trait_impl = true; } hir::ItemKind::Struct(ref sd, _) => { @@ -308,7 +308,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {} _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()), } @@ -463,9 +463,9 @@ impl Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(.., Some(ref t), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref t), items, .. } => { if let Res::Def(DefKind::Trait, trait_did) = t.path.res { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let trait_item_def_id = self .tcx diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 70d4841ec244b..90a422a4dcf6c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -255,8 +255,8 @@ fn def_id_visibility<'tcx>( Node::ImplItem(impl_item) => { match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) { Node::Item(item) => match &item.kind { - hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis, - hir::ItemKind::Impl(.., Some(trait_ref), _, _) => { + hir::ItemKind::Impl { of_trait: None, .. } => &impl_item.vis, + hir::ItemKind::Impl { of_trait: Some(trait_ref), .. } => { return def_id_visibility(tcx, trait_ref.path.res.def_id()); } kind => bug!("unexpected item kind: {:?}", kind), @@ -686,7 +686,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { let inherited_item_level = match item.kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { Option::::of_impl(item.hir_id, self.tcx, &self.access_levels) } // Foreign modules inherit level from parents. @@ -730,9 +730,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { - if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { + if of_trait.is_some() || impl_item_ref.vis.node.is_pub() { self.update(impl_item_ref.id.hir_id, item_level); } } @@ -827,11 +827,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } // Visit everything except for private impl items. - hir::ItemKind::Impl(.., impl_item_refs) => { + hir::ItemKind::Impl { items, .. } => { if item_level.is_some() { self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item_level = self.get(impl_item_ref.id.hir_id); if impl_item_level.is_some() { self.reach(impl_item_ref.id.hir_id, impl_item_level) @@ -1510,7 +1510,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // (i.e., we could just return here to not check them at // all, or some worse estimation of whether an impl is // publicly visible). - hir::ItemKind::Impl(.., ref g, ref trait_ref, ref self_, impl_item_refs) => { + hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => { // `impl [... for] Private` is never visible. let self_contains_private; // `impl [... for] Public<...>`, but not `impl [... for] @@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { at_outer_type: true, outer_type_is_public_path: false, }; - visitor.visit_ty(&self_); + visitor.visit_ty(&self_ty); self_contains_private = visitor.contains_private; self_is_public_path = visitor.outer_type_is_public_path; } @@ -1533,7 +1533,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // Miscellaneous info about the impl: // `true` iff this is `impl Private for ...`. - let not_private_trait = trait_ref.as_ref().map_or( + let not_private_trait = of_trait.as_ref().map_or( true, // no trait counts as public trait |tr| { let did = tr.path.res.def_id(); @@ -1554,8 +1554,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // directly because we might have `impl> ...`, // and we shouldn't warn about the generics if all the methods // are private (because `T` won't be visible externally). - let trait_or_some_public_method = trait_ref.is_some() - || impl_item_refs.iter().any(|impl_item_ref| { + let trait_or_some_public_method = of_trait.is_some() + || items.iter().any(|impl_item_ref| { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item.kind { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { @@ -1570,9 +1570,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { if !self_contains_private && not_private_trait && trait_or_some_public_method { intravisit::walk_generics(self, g); - match *trait_ref { + match of_trait { None => { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { // This is where we choose whether to walk down // further into the impl to check its items. We // should only walk into public items so that we @@ -1594,7 +1594,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - Some(ref tr) => { + Some(tr) => { // Any private types in a trait impl fall into three // categories. // 1. mentioned in the trait definition @@ -1611,7 +1611,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { intravisit::walk_path(self, &tr.path); // Those in 3. are warned with this call. - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind { self.visit_ty(ty); @@ -1619,11 +1619,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - } else if trait_ref.is_none() && self_is_public_path { + } else if of_trait.is_none() && self_is_public_path { // `impl Public { ... }`. Any public static // methods will be visible as `Public::foo`. let mut found_pub_static = false; - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { @@ -1997,12 +1997,12 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { + hir::ItemKind::Impl { ref of_trait, items, .. } => { let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default()); self.check(item.hir_id, impl_vis).generics().predicates(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = tcx.hir().impl_item(impl_item_ref.id); - let impl_item_vis = if trait_ref.is_none() { + let impl_item_vis = if of_trait.is_none() { min( ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx), impl_vis, diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index d6143eec73c00..5fae8f3318743 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -416,11 +416,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x let track_lifetime_uses = match item.kind { - hir::ItemKind::Impl(..) => true, + hir::ItemKind::Impl { .. } => true, _ => false, }; // These kinds of items have only early-bound lifetime parameters. @@ -1638,7 +1638,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } match parent.kind { hir::ItemKind::Trait(_, _, ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { index += generics.params.len() as u32; } _ => {} @@ -2067,12 +2067,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(_, body), .. }) => { - if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) = + if let hir::ItemKind::Impl { ref self_ty, ref items, .. } = self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind { impl_self = Some(self_ty); assoc_item_kind = - impl_items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); + items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); } Some(body) } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 5412533fce7d8..537fe198a0c39 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -405,9 +405,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { { Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { Some(Node::Item(item)) => match item.kind { - hir::ItemKind::Impl(.., ref ty, _) => { + hir::ItemKind::Impl { ref self_ty, .. } => { let mut qualname = String::from("<"); - qualname.push_str(&self.tcx.hir().hir_to_pretty_string(ty.hir_id)); + qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id)); let trait_id = self.tcx.trait_id_of_impl(impl_id); let mut decl_id = None; diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 315efe5cf71e7..7df27e67d5b1c 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -195,8 +195,8 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { }, Node::Item(item) => match item.kind { - ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl, - ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl, + ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl, + ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl, ItemKind::Fn(..) => NodeKind::Fn, _ => NodeKind::Other, }, diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index fc8beb67e4ada..d47e54366b550 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -128,8 +128,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { let parent_def_id = tcx.hir().local_def_id(parent_id); let parent_item = tcx.hir().expect_item(parent_id); match parent_item.kind { - hir::ItemKind::Impl(.., ref impl_item_refs) => { - if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { + hir::ItemKind::Impl { ref items, .. } => { + if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) { let assoc_item = associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref); debug_assert_eq!(assoc_item.def_id, def_id); @@ -194,8 +194,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { .map(|trait_item_ref| trait_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), ), - hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( - impl_item_refs + hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter( + items .iter() .map(|impl_item_ref| impl_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dff68b9986cc9..4affdc4a9d64e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1709,17 +1709,11 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) { check_enum(tcx, it.span, &enum_definition.variants, it.hir_id); } hir::ItemKind::Fn(..) => {} // entirely within check_item_body - hir::ItemKind::Impl(.., ref impl_item_refs) => { + hir::ItemKind::Impl { ref items, .. } => { debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id); let impl_def_id = tcx.hir().local_def_id(it.hir_id); if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) { - check_impl_items_against_trait( - tcx, - it.span, - impl_def_id, - impl_trait_ref, - impl_item_refs, - ); + check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items); let trait_def_id = impl_trait_ref.def_id; check_on_unimplemented(tcx, trait_def_id, it); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index a496a6e12ce1a..5e91e98a7dfa5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -97,7 +97,7 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` - hir::ItemKind::Impl(_, _, defaultness, _, ref trait_ref, ref self_ty, _) => { + hir::ItemKind::Impl { defaultness, ref of_trait, ref self_ty, .. } => { let is_auto = tcx .impl_trait_ref(tcx.hir().local_def_id(item.hir_id)) .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); @@ -107,11 +107,11 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { } match polarity { ty::ImplPolarity::Positive => { - check_impl(tcx, item, self_ty, trait_ref); + check_impl(tcx, item, self_ty, of_trait); } ty::ImplPolarity::Negative => { // FIXME(#27579): what amount of WF checking do we need for neg impls? - if trait_ref.is_some() && !is_auto { + if of_trait.is_some() && !is_auto { struct_span_err!( tcx.sess, item.span, diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 8b3db15c02b4e..516dc16d46bd8 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -57,7 +57,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) { let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT"); let sp = match tcx.hir().expect_item(impl_hir_id).kind { - ItemKind::Impl(.., ty, _) => ty.span, + ItemKind::Impl { self_ty, .. } => self_ty.span, _ => bug!("expected Drop impl item"), }; @@ -94,7 +94,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { Ok(()) => {} Err(CopyImplementationError::InfrigingFields(fields)) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind { tr.path.span } else { span @@ -113,7 +113,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { } Err(CopyImplementationError::NotAnAdt) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., ref ty, _) = item.kind { ty.span } else { span }; + let span = + if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span }; struct_span_err!( tcx.sess, @@ -490,7 +491,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn return err_info; } else if diff_fields.len() > 1 { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind { t.path.span } else { tcx.hir().span(impl_hir_id) diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 673c1bd9fd831..d313e32fc20e0 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -47,7 +47,7 @@ struct InherentCollect<'tcx> { impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let ty = match item.kind { - hir::ItemKind::Impl(.., None, ref ty, _) => ty, + hir::ItemKind::Impl { of_trait: None, ref self_ty, .. } => self_ty, _ => return, }; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 1878f9385a891..9ba8fa4247f26 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -27,7 +27,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let def_id = self.tcx.hir().local_def_id(item.hir_id); // "Trait" impl - if let hir::ItemKind::Impl(.., generics, Some(tr), impl_ty, _) = &item.kind { + if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind { debug!( "coherence2::orphan check: trait impl {}", self.tcx.hir().node_to_string(item.hir_id) @@ -72,7 +72,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { let msg = format!("{} is not defined in the current crate{}", ty, postfix); if *is_target_ty { // Point at `D` in `impl for C in D` - err.span_label(impl_ty.span, &msg); + err.span_label(self_ty.span, &msg); } else { // Point at `C` in `impl for C in D` err.span_label(tr.path.span, &msg); diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 3f4035b0998d6..48b96886d3a71 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -88,7 +88,7 @@ impl UnsafetyChecker<'tcx> { impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> { fn visit_item(&mut self, item: &'v hir::Item<'v>) { - if let hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) = item.kind { + if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind { self.check_unsafety_coherence(item, Some(generics), unsafety, polarity); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index dca3289747e4c..a03b9f747372e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -184,7 +184,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir | hir::ItemKind::Enum(_, generics) | hir::ItemKind::TraitAlias(generics, _) | hir::ItemKind::Trait(_, _, generics, ..) - | hir::ItemKind::Impl(_, _, _, generics, ..) + | hir::ItemKind::Impl { generics, .. } | hir::ItemKind::Struct(_, generics) => (generics, true), hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }) | hir::ItemKind::TyAlias(_, generics) => (generics, false), @@ -401,7 +401,7 @@ fn type_param_predicates( Node::Item(item) => { match item.kind { ItemKind::Fn(.., ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) + | ItemKind::Impl { ref generics, .. } | ItemKind::TyAlias(_, ref generics) | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::Enum(_, ref generics) @@ -531,7 +531,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { tcx.predicates_of(def_id); convert_enum_variant_types(tcx, def_id, &enum_definition.variants); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { tcx.generics_of(def_id); tcx.type_of(def_id); tcx.impl_trait_ref(def_id); @@ -1052,9 +1052,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { Node::Item(item) => { match item.kind { - ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => { - generics - } + ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics, ItemKind::TyAlias(_, ref generics) | ItemKind::Enum(_, ref generics) @@ -1338,7 +1336,9 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { icx.to_ty(ty) } } - ItemKind::TyAlias(ref ty, _) | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty), + ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => { + icx.to_ty(self_ty) + } ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) @@ -1956,12 +1956,10 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => { - opt_trait_ref.as_ref().map(|ast_trait_ref| { - let selfty = tcx.type_of(def_id); - AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) - }) - } + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| { + let selfty = tcx.type_of(def_id); + AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) + }), _ => bug!(), } } @@ -1971,19 +1969,21 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let item = tcx.hir().expect_item(hir_id); match &item.kind { - hir::ItemKind::Impl(_, hir::ImplPolarity::Negative, ..) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be negative"); } ty::ImplPolarity::Negative } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be inherent"); } ty::ImplPolarity::Positive } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => { + hir::ItemKind::Impl { + polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. + } => { if is_rustc_reservation { ty::ImplPolarity::Reservation } else { @@ -2142,7 +2142,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat Node::Item(item) => { match item.kind { - ItemKind::Impl(_, _, defaultness, ref generics, ..) => { + ItemKind::Impl { defaultness, ref generics, .. } => { if defaultness.is_default() { is_default_impl_trait = tcx.impl_trait_ref(def_id); } @@ -2359,7 +2359,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // before uses of `U`. This avoids false ambiguity errors // in trait checking. See `setup_constraining_predicates` // for details. - if let Node::Item(&Item { kind: ItemKind::Impl(..), .. }) = node { + if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { let self_ty = tcx.type_of(def_id); let trait_ref = tcx.impl_trait_ref(def_id); cgp::setup_constraining_predicates( diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fb87b285fa29f..9ee4e7c48190d 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -75,10 +75,10 @@ struct ImplWfCheck<'tcx> { impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { ref items, .. } = item.kind { let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); - enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs); - enforce_impl_items_are_distinct(self.tcx, impl_item_refs); + enforce_impl_params_are_constrained(self.tcx, impl_def_id, items); + enforce_impl_items_are_distinct(self.tcx, items); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..342eaad3a8f91 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -331,7 +331,7 @@ pub fn build_impl( let for_ = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref t, _) => t.clean(cx), + hir::ItemKind::Impl { self_ty, .. } => self_ty.clean(cx), _ => panic!("did given to build_impl was not an impl"), } } else { @@ -351,9 +351,9 @@ pub fn build_impl( let predicates = tcx.explicit_predicates_of(did); let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => ( - item_ids.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::>(), - gen.clean(cx), + hir::ItemKind::Impl { ref generics, ref items, .. } => ( + items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::>(), + generics.clean(cx), ), _ => panic!("did given to build_impl was not an impl"), } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f899e722a5615..05d4141568981 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -905,8 +905,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { } fn visit_item(&mut self, item: &'hir hir::Item) { - let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.kind { - self.map.hir_to_pretty_string(ty.hir_id) + let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind { + self.map.hir_to_pretty_string(self_ty.hir_id) } else { item.ident.to_string() }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 5fa9270959cca..fdff18779e795 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -558,27 +558,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.trait_aliases.push(t); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref trait_, - for_, - ref item_ids, - ) => { + ref of_trait, + self_ty, + ref items, + } => { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. - if !self.inlining && trait_.is_none() { + if !self.inlining && of_trait.is_none() { let items = - item_ids.iter().map(|ii| self.cx.tcx.hir().impl_item(ii.id)).collect(); + items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); let i = Impl { unsafety, polarity, defaultness, generics, - trait_, - for_, + trait_: of_trait, + for_: self_ty, items, attrs: &item.attrs, id: item.hir_id, From 79359315d6d096b4783b48a3550b5714b8c04d6b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 16 Jan 2020 22:18:17 +0100 Subject: [PATCH 0456/1253] get rid of real_drop_in_place again --- src/libcore/ptr/mod.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index d7b351f13458a..c1976868bf760 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -169,22 +169,12 @@ mod mut_ptr; /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually. #[stable(feature = "drop_in_place", since = "1.8.0")] -#[inline(always)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - real_drop_in_place(&mut *to_drop) -} - -// The real `drop_in_place` -- the one that gets called implicitly when variables go -// out of scope -- should have a safe reference and not a raw pointer as argument -// type. When we drop a local variable, we access it with a pointer that behaves -// like a safe reference; transmuting that to a raw pointer does not mean we can -// actually access it with raw pointers. #[lang = "drop_in_place"] #[allow(unconditional_recursion)] -unsafe fn real_drop_in_place(to_drop: &mut T) { +pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. - real_drop_in_place(to_drop) + drop_in_place(to_drop) } /// Creates a null raw pointer. From ec063a0ae8c2fc8aeb7ae6984dc08aeb5d25e434 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Jan 2020 09:38:42 +0100 Subject: [PATCH 0457/1253] adjust mir-opt tests --- src/test/mir-opt/retag.rs | 6 +++--- src/test/mir-opt/slice-drop-shim.rs | 4 ++-- src/test/mir-opt/unusual-item-types.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index ccecaeac96b83..1c88a9e4d5a32 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -113,8 +113,8 @@ fn main() { // } // } // END rustc.main-{{closure}}.EraseRegions.after.mir -// START rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir -// fn std::ptr::real_drop_in_place(_1: &mut Test) -> () { +// START rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +// fn std::intrinsics::drop_in_place(_1: *mut Test) -> () { // ... // bb0: { // Retag([raw] _1); @@ -126,4 +126,4 @@ fn main() { // return; // } // } -// END rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir +// END rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs index 5a37b67229c37..a25375594d3e1 100644 --- a/src/test/mir-opt/slice-drop-shim.rs +++ b/src/test/mir-opt/slice-drop-shim.rs @@ -6,7 +6,7 @@ fn main() { // END RUST SOURCE -// START rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir +// START rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir // let mut _2: usize; // let mut _3: usize; // let mut _4: usize; @@ -87,4 +87,4 @@ fn main() { // _3 = Len((*_1)); // switchInt(move _2) -> [0usize: bb8, otherwise: bb14]; // } -// END rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir +// END rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index f4d848dfc7ad1..88cfb62a0d094 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -45,7 +45,7 @@ fn main() { // } // END rustc.E-V-{{constant}}.mir_map.0.mir -// START rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +// START rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir // bb0: { // goto -> bb7; // } @@ -71,7 +71,7 @@ fn main() { // _2 = &mut (*_1); // _3 = const as std::ops::Drop>::drop(move _2) -> [return: bb6, unwind: bb5]; // } -// END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +// END rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir // START rustc.Test-X-{{constructor}}.mir_map.0.mir // fn Test::X(_1: usize) -> Test { From 6106758fcee3a08da04a395c1af9fbc2e7c2c816 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Jan 2020 12:24:54 +0100 Subject: [PATCH 0458/1253] adjust ui tests --- src/test/ui/consts/miri_unleashed/drop.stderr | 6 +++--- .../issue-38591-non-regular-dropck-recursion.stderr | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr index 2cdeb598c8cc6..2439d527bd197 100644 --- a/src/test/ui/consts/miri_unleashed/drop.stderr +++ b/src/test/ui/consts/miri_unleashed/drop.stderr @@ -7,17 +7,17 @@ LL | let _v: Vec = Vec::new(); error[E0080]: could not evaluate static initializer --> $SRC_DIR/libcore/ptr/mod.rs:LL:COL | -LL | / unsafe fn real_drop_in_place(to_drop: &mut T) { +LL | / pub unsafe fn drop_in_place(to_drop: *mut T) { LL | | // Code here does not matter - this is replaced by the LL | | // real drop glue by the compiler. -LL | | real_drop_in_place(to_drop) +LL | | drop_in_place(to_drop) LL | | } | |_^ calling non-const function ` as std::ops::Drop>::drop` | ::: $DIR/drop.rs:23:1 | LL | }; - | - inside call to `std::ptr::real_drop_in_place::> - shim(Some(std::vec::Vec))` at $DIR/drop.rs:23:1 + | - inside call to `std::intrinsics::drop_in_place::> - shim(Some(std::vec::Vec))` at $DIR/drop.rs:23:1 error: aborting due to previous error diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr index 77309a82a0fa7..de6df4cd0268c 100644 --- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -1,4 +1,4 @@ -error: reached the recursion limit while instantiating `std::ptr::real_drop_in_place::> - shim(Some(S))` +error: reached the recursion limit while instantiating `std::intrinsics::drop_in_place::> - shim(Some(S))` error: aborting due to previous error From 45dd44c0e130479e6532ddb0505401a41884d2bb Mon Sep 17 00:00:00 2001 From: msizanoen1 <55322658+msizanoen1@users.noreply.github.com> Date: Sat, 18 Jan 2020 18:59:51 +0700 Subject: [PATCH 0459/1253] Add `riscv64gc-unknown-linux-gnu` into target list in build-manifest Missed in #68037 r? @alexcrichton --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 481163a1a9abe..cff04e197e48a 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -110,6 +110,7 @@ static TARGETS: &[&str] = &[ "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf", + "riscv64gc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparcv9-sun-solaris", From af6282f92a6d4dd9c556535fc40b4b04f531b8a5 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 18 Jan 2020 13:33:17 +0100 Subject: [PATCH 0460/1253] Fix table of syscalls in docs of std::time::Instant. --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 0b6e728dceb1d..2e3e3b743a49f 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -65,7 +65,7 @@ pub use core::time::Duration; /// /// | Platform | System call | /// |:---------:|:--------------------------------------------------------------------:| -/// | Cloud ABI | [clock_time_get (Monotonic Clock)] | +/// | CloudABI | [clock_time_get (Monotonic Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | UNIX | [clock_gettime (Monotonic Clock)] | /// | Darwin | [mach_absolute_time] | @@ -79,7 +79,7 @@ pub use core::time::Duration; /// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get /// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime /// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html -/// [clock_time_get (Monotonic Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt +/// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// /// **Disclaimer:** These system calls might change over time. /// From 366f619a49162588770af9f23099ca9407d1992a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 18 Jan 2020 13:33:17 +0100 Subject: [PATCH 0461/1253] Fix table of syscalls in docs of std::time::SystemTime. --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 2e3e3b743a49f..5bc8fe5ae6d79 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -144,7 +144,7 @@ pub struct Instant(time::Instant); /// /// | Platform | System call | /// |:---------:|:--------------------------------------------------------------------:| -/// | Cloud ABI | [clock_time_get (Realtime Clock)] | +/// | CloudABI | [clock_time_get (Realtime Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | UNIX | [clock_gettime (Realtime Clock)] | /// | DARWIN | [gettimeofday] | @@ -152,7 +152,7 @@ pub struct Instant(time::Instant); /// | WASI | [__wasi_clock_time_get (Realtime Clock)] | /// | Windows | [GetSystemTimeAsFileTime] | /// -/// [clock_time_get (Realtime Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt +/// [clock_time_get (Realtime Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode /// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html From 6b7f3e50df3b4235756df9354ea90cf821460a8b Mon Sep 17 00:00:00 2001 From: lcnr/Bastian Kauschke Date: Sat, 18 Jan 2020 14:43:08 +0100 Subject: [PATCH 0462/1253] improve type_name_of_val docs --- src/libcore/any.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 7935c9b1b392d..c5dcdfed12ae0 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -476,11 +476,15 @@ pub const fn type_name() -> &'static str { /// /// This is intended for diagnostic use. The exact contents and format of the /// string are not specified, other than being a best-effort description of the -/// type. For example, `type_name_of::>(None)` could return +/// type. For example, `type_name_of_val::>(None)` could return /// `"Option"` or `"std::option::Option"`, but not /// `"foobar"`. In addition, the output may change between versions of the /// compiler. /// +/// This function does not resolve trait objects, +/// meaning that `type_name_of_val(&7u32 as &dyn Debug)` +/// may return `"dyn Debug"`, but not `"u32"`. +/// /// The type name should not be considered a unique identifier of a type; /// multiple types may share the same type name. /// From 9746b05da995629780f559e68cde2a3d41b3b2bc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Jan 2020 13:12:30 +0100 Subject: [PATCH 0463/1253] clean up e0200 explanation --- src/librustc_error_codes/error_codes/E0200.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0200.md b/src/librustc_error_codes/error_codes/E0200.md index 865e91430ac44..7245bb59ce5ff 100644 --- a/src/librustc_error_codes/error_codes/E0200.md +++ b/src/librustc_error_codes/error_codes/E0200.md @@ -1,14 +1,23 @@ +An unsafe trait was implemented without an unsafe implementation. + +Erroneous code example: + +```compile_fail,E0200 +struct Foo; + +unsafe trait Bar { } + +impl Bar for Foo { } // error! +``` + Unsafe traits must have unsafe implementations. This error occurs when an implementation for an unsafe trait isn't marked as unsafe. This may be resolved by marking the unsafe implementation as unsafe. -```compile_fail,E0200 +``` struct Foo; unsafe trait Bar { } -// this won't compile because Bar is unsafe and impl isn't unsafe -impl Bar for Foo { } -// this will compile -unsafe impl Bar for Foo { } +unsafe impl Bar for Foo { } // ok! ``` From c41443a2b729054c48cd798e341f75f076b390a7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:16:16 +0100 Subject: [PATCH 0464/1253] stabilize slice_patterns --- src/librustc_ast_passes/feature_gate.rs | 21 --------------------- src/librustc_feature/accepted.rs | 2 ++ src/librustc_feature/active.rs | 3 --- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 71cd66ddef409..461072873bb52 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -470,29 +470,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_expr(self, e) } - fn visit_arm(&mut self, arm: &'a ast::Arm) { - visit::walk_arm(self, arm) - } - fn visit_pat(&mut self, pattern: &'a ast::Pat) { match &pattern.kind { - PatKind::Slice(pats) => { - for pat in &*pats { - let span = pat.span; - let inner_pat = match &pat.kind { - PatKind::Ident(.., Some(pat)) => pat, - _ => pat, - }; - if inner_pat.is_rest() { - gate_feature_post!( - &self, - slice_patterns, - span, - "subslice patterns are unstable" - ); - } - } - } PatKind::Box(..) => { gate_feature_post!( &self, diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs index d880fc84b3819..007cee4c76424 100644 --- a/src/librustc_feature/accepted.rs +++ b/src/librustc_feature/accepted.rs @@ -257,6 +257,8 @@ declare_features! ( /// Allows relaxing the coherence rules such that /// `impl ForeignTrait for ForeignType` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), + /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. + (accepted, slice_patterns, "1.42.0", Some(62254), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 4c8c47a567113..6af9b6c087278 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -262,9 +262,6 @@ declare_features! ( /// Allows using non lexical lifetimes (RFC 2094). (active, nll, "1.0.0", Some(43234), None), - /// Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(62254), None), - /// Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None), From 0aebb0811548202b177ab411a7570e1fd3e43bc0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:31:35 +0100 Subject: [PATCH 0465/1253] slice_patterns: adjust error codes --- src/librustc_error_codes/error_codes/E0527.md | 2 -- src/librustc_error_codes/error_codes/E0528.md | 4 ---- src/librustc_error_codes/error_codes/E0730.md | 2 -- 3 files changed, 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0527.md b/src/librustc_error_codes/error_codes/E0527.md index 4bff39dc770e0..97ea312693881 100644 --- a/src/librustc_error_codes/error_codes/E0527.md +++ b/src/librustc_error_codes/error_codes/E0527.md @@ -17,8 +17,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0528.md b/src/librustc_error_codes/error_codes/E0528.md index 4b6ea2469919c..54c2c4d4e9d0f 100644 --- a/src/librustc_error_codes/error_codes/E0528.md +++ b/src/librustc_error_codes/error_codes/E0528.md @@ -4,8 +4,6 @@ matched array. Example of erroneous code: ```compile_fail,E0528 -#![feature(slice_patterns)] - let r = &[1, 2]; match r { &[a, b, c, rest @ ..] => { // error: pattern requires at least 3 @@ -19,8 +17,6 @@ Ensure that the matched array has at least as many elements as the pattern requires. You can match an arbitrary number of remaining elements with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4, 5]; match r { &[a, b, c, rest @ ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md index 803a25148651c..bf1f72be32589 100644 --- a/src/librustc_error_codes/error_codes/E0730.md +++ b/src/librustc_error_codes/error_codes/E0730.md @@ -18,8 +18,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! From a70b24018936fe59f0a037adfa13f2255d8aa5d2 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 18 Jan 2020 18:35:36 +0100 Subject: [PATCH 0466/1253] Make iter::Empty implement Send and Sync for any T --- src/libcore/iter/sources.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index a65d47cc2c1f0..25dfc573e416a 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -208,6 +208,11 @@ pub fn repeat_with A>(repeater: F) -> RepeatWith { #[stable(feature = "iter_empty", since = "1.2.0")] pub struct Empty(marker::PhantomData); +#[stable(feature = "iter_empty_send_sync", since = "1.42.0")] +unsafe impl Send for Empty {} +#[stable(feature = "iter_empty_send_sync", since = "1.42.0")] +unsafe impl Sync for Empty {} + #[stable(feature = "core_impl_debug", since = "1.9.0")] impl fmt::Debug for Empty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { From d7a18f89864a4360230e3cbbdcbf22d9864a86e0 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 17 Jan 2019 00:07:22 +0100 Subject: [PATCH 0467/1253] Add a test for iter::empty::<*mut i32> being Sync and Send --- src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs index 44beb9dc1e534..2f6d35f01be62 100644 --- a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs +++ b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs @@ -88,6 +88,7 @@ fn main() { is_sync_send!((1..)); is_sync_send!(repeat(1)); is_sync_send!(empty::()); + is_sync_send!(empty::<*mut i32>()); is_sync_send!(once(1)); // for option.rs From 3ccb0f9b8f990df7f2149655fb3bf7585ddc8cad Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:32:02 +0100 Subject: [PATCH 0468/1253] slice_patterns: remove internal uses of gate --- src/libcore/lib.rs | 2 +- src/libcore/tests/lib.rs | 2 +- src/librustc/benches/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_ast_passes/lib.rs | 2 +- src/librustc_codegen_ssa/lib.rs | 2 +- src/librustc_metadata/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_mir_build/lib.rs | 2 +- src/librustc_parse/lib.rs | 2 +- src/librustc_passes/lib.rs | 2 +- src/librustc_target/lib.rs | 2 +- src/librustc_ty/lib.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/libstd/lib.rs | 2 +- src/libsyntax/lib.rs | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 15720ddcfc677..f77b4d7461e74 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -133,7 +133,7 @@ #![feature(associated_type_bounds)] #![feature(const_type_id)] #![feature(const_caller_location)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8c034938c2bb9..f0420247acfbd 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -19,7 +19,7 @@ #![feature(range_is_empty)] #![feature(raw)] #![feature(saturating_neg)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(sort_internals)] #![feature(slice_partition_at_index)] #![feature(specialization)] diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs index ffb12f11c5136..de82b262e4956 100644 --- a/src/librustc/benches/lib.rs +++ b/src/librustc/benches/lib.rs @@ -1,4 +1,4 @@ -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(test)] extern crate test; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b894aabd90100..69ca40636948f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -42,7 +42,7 @@ #![feature(optin_builtin_traits)] #![feature(option_expect_none)] #![feature(range_is_empty)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(unboxed_closures)] #![feature(thread_local)] diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index eadbc485296e8..5de45f4e1f365 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -2,7 +2,7 @@ //! parsed by `rustc_parse` and then lowered, after the passes in this crate, //! by `rustc_ast_lowering`. -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] pub mod ast_validation; pub mod feature_gate; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index ee527ecb509b2..aba77231268e7 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -4,7 +4,7 @@ #![feature(box_syntax)] #![feature(core_intrinsics)] #![feature(libc)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 0fec4bff1633d..cf925ab91875f 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -10,7 +10,7 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustc_private)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 1c25b269b18fd..5e42ba3279027 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -7,7 +7,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nll)] #![feature(in_band_lifetimes)] #![feature(inner_deref)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index 5a17f36e1da25..42292d635bc75 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -5,7 +5,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(bool_to_option)] #![recursion_limit = "256"] diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 9227e968ecc4f..08f4f210152dd 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -2,7 +2,7 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] use syntax::ast; use syntax::print::pprust; diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 65eb07b989d83..d746f097928ea 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -7,7 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 17413e77f9007..84c6d720b8e00 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -11,7 +11,7 @@ #![feature(box_syntax)] #![feature(bool_to_option)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #[macro_use] extern crate log; diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs index 2548d2cff9766..e5ec98743e0ae 100644 --- a/src/librustc_ty/lib.rs +++ b/src/librustc_ty/lib.rs @@ -8,7 +8,7 @@ #![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b951883ac195a..95cd3c631ed22 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -64,7 +64,7 @@ This API is completely unstable and subject to change. #![feature(exhaustive_patterns)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(try_blocks)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f90647472c678..c8fae91fcf3a5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -294,7 +294,7 @@ #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(staged_api)] #![feature(std_internals)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 0184a3214b5b4..b0c2aa3dbb28e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -13,7 +13,7 @@ #![feature(label_break_value)] #![feature(nll)] #![feature(try_trait)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(unicode_internals)] #![recursion_limit = "256"] From 3e3cac010b318c6a2aa89ffbbafaea169898ba3d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:33:10 +0100 Subject: [PATCH 0469/1253] slice_patterns: remove feature gate test --- .../feature-gate-slice-patterns.rs | 17 ------ .../feature-gate-slice-patterns.stderr | 57 ------------------- 2 files changed, 74 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-slice-patterns.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-slice-patterns.stderr diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs deleted file mode 100644 index f2a1b135b69cb..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Test that slice pattern syntax with `..` is gated by `slice_patterns` feature gate - -fn main() { - let x = [1, 2, 3, 4, 5]; - match x { - [1, 2, ..] => {} //~ ERROR subslice patterns are unstable - [1, .., 5] => {} //~ ERROR subslice patterns are unstable - [.., 4, 5] => {} //~ ERROR subslice patterns are unstable - } - - let x = [ 1, 2, 3, 4, 5 ]; - match x { - [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable - [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable - [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable - } -} diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr deleted file mode 100644 index d4946a42b8f3d..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:6:16 - | -LL | [1, 2, ..] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:7:13 - | -LL | [1, .., 5] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:8:10 - | -LL | [.., 4, 5] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:13:11 - | -LL | [ xs @ .., 4, 5 ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:14:14 - | -LL | [ 1, xs @ .., 5 ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:15:17 - | -LL | [ 1, 2, xs @ .. ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0658`. From a1eadca88f03de91f5eecd316419d32e2a302c2b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:23:42 +0100 Subject: [PATCH 0470/1253] slice_patterns: remove gates in tests --- src/test/mir-opt/uniform_array_move_out.rs | 1 - .../subslice-patterns-const-eval-match.rs | 2 +- .../subslice-patterns-const-eval.rs | 2 - .../array-slice-vec/subslice-patterns-pass.rs | 2 - .../ui/array-slice-vec/vec-matching-fixed.rs | 2 - .../ui/array-slice-vec/vec-matching-fold.rs | 2 - .../vec-matching-legal-tail-element-borrow.rs | 3 +- src/test/ui/array-slice-vec/vec-matching.rs | 2 - .../ui/array-slice-vec/vec-tail-matching.rs | 2 - .../ui/binding/empty-types-in-patterns.rs | 3 +- .../ui/binding/irrefutable-slice-patterns.rs | 3 +- .../ui/binding/match-byte-array-patterns.rs | 1 - src/test/ui/binding/match-vec-alternatives.rs | 1 - .../ui/binding/zero_sized_subslice_match.rs | 1 - .../borrowck-closures-slice-patterns-ok.rs | 1 - .../borrowck-closures-slice-patterns.rs | 2 - .../borrowck-closures-slice-patterns.stderr | 16 ++-- .../ui/borrowck/borrowck-describe-lvalue.rs | 2 - .../borrowck/borrowck-describe-lvalue.stderr | 64 ++++++------- .../borrowck-move-out-from-array-match.rs | 2 - .../borrowck-move-out-from-array-match.stderr | 20 ++--- ...ck-move-out-from-array-no-overlap-match.rs | 2 - ...ove-out-from-array-no-overlap-match.stderr | 18 ++-- ...borrowck-move-out-from-array-no-overlap.rs | 2 - .../borrowck-move-out-from-array-use-match.rs | 2 - ...rowck-move-out-from-array-use-match.stderr | 28 +++--- ...ove-out-from-array-use-no-overlap-match.rs | 2 - ...out-from-array-use-no-overlap-match.stderr | 18 ++-- ...owck-move-out-from-array-use-no-overlap.rs | 2 - .../borrowck-move-out-from-array-use.rs | 2 - .../borrowck-move-out-from-array-use.stderr | 28 +++--- .../borrowck/borrowck-move-out-from-array.rs | 2 - .../borrowck-move-out-from-array.stderr | 20 ++--- .../borrowck/borrowck-move-out-of-vec-tail.rs | 2 - .../borrowck-move-out-of-vec-tail.stderr | 2 +- ...e-pattern-element-loan-array-no-overlap.rs | 2 - ...rrowck-slice-pattern-element-loan-array.rs | 2 - ...ck-slice-pattern-element-loan-array.stderr | 16 ++-- ...rrowck-slice-pattern-element-loan-rpass.rs | 4 +- ...e-pattern-element-loan-slice-no-overlap.rs | 2 - ...rrowck-slice-pattern-element-loan-slice.rs | 2 - ...ck-slice-pattern-element-loan-slice.stderr | 22 ++--- .../borrowck-vec-pattern-element-loan.rs | 2 - .../borrowck-vec-pattern-element-loan.stderr | 6 +- .../borrowck-vec-pattern-loan-from-mut.rs | 2 - .../borrowck-vec-pattern-loan-from-mut.stderr | 2 +- .../borrowck-vec-pattern-move-tail.rs | 4 - .../borrowck-vec-pattern-move-tail.stderr | 2 +- .../borrowck/borrowck-vec-pattern-nesting.rs | 1 - .../borrowck-vec-pattern-nesting.stderr | 16 ++-- .../borrowck-vec-pattern-tail-element-loan.rs | 2 - ...rowck-vec-pattern-tail-element-loan.stderr | 2 +- .../ui/consts/const_prop_slice_pat_ice.rs | 1 - src/test/ui/drop/dynamic-drop-async.rs | 1 - src/test/ui/drop/dynamic-drop.rs | 7 +- src/test/ui/error-codes/E0528.rs | 2 - src/test/ui/error-codes/E0528.stderr | 2 +- src/test/ui/ignore-all-the-things.rs | 4 +- src/test/ui/issues/issue-12369.rs | 1 - src/test/ui/issues/issue-12369.stderr | 4 +- src/test/ui/issues/issue-12567.rs | 2 - src/test/ui/issues/issue-12567.stderr | 4 +- src/test/ui/issues/issue-15080.rs | 1 - src/test/ui/issues/issue-15104.rs | 1 - src/test/ui/issues/issue-17877.rs | 1 - src/test/ui/issues/issue-23311.rs | 3 +- src/test/ui/issues/issue-26619.rs | 2 - src/test/ui/issues/issue-26619.stderr | 2 +- src/test/ui/issues/issue-37598.rs | 1 - src/test/ui/issues/issue-7784.rs | 1 - src/test/ui/match/match-vec-mismatch.rs | 2 - src/test/ui/match/match-vec-mismatch.stderr | 10 +-- src/test/ui/moves/move-out-of-array-ref.rs | 2 - .../ui/moves/move-out-of-array-ref.stderr | 8 +- .../exhaustiveness-non-exhaustive.rs | 2 +- .../ui/or-patterns/exhaustiveness-pass.rs | 2 +- .../exhaustiveness-unreachable-pattern.rs | 2 +- src/test/ui/parser/match-vec-invalid.rs | 2 - src/test/ui/parser/match-vec-invalid.stderr | 24 +---- src/test/ui/parser/pat-lt-bracket-6.rs | 1 - src/test/ui/parser/pat-lt-bracket-6.stderr | 16 +--- .../borrowck-move-and-move.rs | 1 - .../borrowck-move-and-move.stderr | 32 +++---- .../borrowck-pat-at-and-box-pass.rs | 1 - .../borrowck-pat-at-and-box.rs | 1 - .../borrowck-pat-at-and-box.stderr | 48 +++++----- .../borrowck-pat-by-copy-bindings-in-at.rs | 1 - .../borrowck-pat-ref-both-sides.rs | 1 - .../borrowck-pat-ref-mut-and-ref.rs | 1 - .../borrowck-pat-ref-mut-and-ref.stderr | 90 +++++++++---------- .../borrowck-pat-ref-mut-twice.rs | 1 - .../borrowck-pat-ref-mut-twice.stderr | 64 ++++++------- .../issue-53820-slice-pattern-large-array.rs | 2 - ...413-constants-and-slices-exhaustiveness.rs | 2 +- .../usefulness/match-byte-array-patterns.rs | 1 - .../match-byte-array-patterns.stderr | 18 ++-- .../usefulness/match-slice-patterns.rs | 2 - .../usefulness/match-slice-patterns.stderr | 2 +- .../usefulness/match-vec-unreachable.rs | 1 - .../usefulness/match-vec-unreachable.stderr | 8 +- .../usefulness/non-exhaustive-match-nested.rs | 2 - .../non-exhaustive-match-nested.stderr | 4 +- .../usefulness/non-exhaustive-match.rs | 1 - .../usefulness/non-exhaustive-match.stderr | 16 ++-- .../non-exhaustive-pattern-witness.rs | 2 - .../non-exhaustive-pattern-witness.stderr | 14 +-- .../slice-patterns-exhaustiveness.rs | 2 - .../slice-patterns-exhaustiveness.stderr | 32 +++---- .../usefulness/slice-patterns-irrefutable.rs | 1 - .../usefulness/slice-patterns-reachability.rs | 1 - .../slice-patterns-reachability.stderr | 14 +-- .../ui/rfc-2005-default-binding-mode/slice.rs | 2 - .../slice.stderr | 2 +- .../rfc-2005-default-binding-mode/slice.rs | 1 - src/test/ui/trailing-comma.rs | 2 - .../ui/uninhabited/uninhabited-patterns.rs | 2 +- 116 files changed, 349 insertions(+), 490 deletions(-) diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs index f2e1864096ea9..d587d237227ad 100644 --- a/src/test/mir-opt/uniform_array_move_out.rs +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -1,5 +1,4 @@ #![feature(box_syntax)] -#![feature(slice_patterns)] fn move_out_from_end() { let a = [box 1, box 2]; diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs index 0e767d9613a99..69c33921868cf 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs @@ -2,7 +2,7 @@ // run-pass -#![feature(slice_patterns, const_fn, const_if_match)] +#![feature(const_fn, const_if_match)] #[derive(PartialEq, Debug, Clone)] struct N(u8); diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs index 5444f8a9051bd..0b793fa0120e9 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs @@ -2,8 +2,6 @@ // run-pass -#![feature(slice_patterns)] - #[derive(PartialEq, Debug, Clone)] struct N(u8); diff --git a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs index 1ebf3def78876..e05790911f52d 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs @@ -4,8 +4,6 @@ // run-pass -#![feature(slice_patterns)] - #![allow(unreachable_patterns)] use std::convert::identity; diff --git a/src/test/ui/array-slice-vec/vec-matching-fixed.rs b/src/test/ui/array-slice-vec/vec-matching-fixed.rs index 5253bc1b21430..fdeb7e4fda640 100644 --- a/src/test/ui/array-slice-vec/vec-matching-fixed.rs +++ b/src/test/ui/array-slice-vec/vec-matching-fixed.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - fn a() { let x = [1, 2, 3]; match x { diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs index f416160db2422..998899271e411 100644 --- a/src/test/ui/array-slice-vec/vec-matching-fold.rs +++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - use std::fmt::Debug; fn foldl(values: &[T], diff --git a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs index f0602c328b071..ed34f074a929a 100644 --- a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs +++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs @@ -1,7 +1,6 @@ // run-pass -#![allow(unused_variables)] -#![feature(slice_patterns)] +#![allow(unused_variables)] pub fn main() { let x = &[1, 2, 3, 4, 5]; diff --git a/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs index 49c736bd72847..7009244aa189a 100644 --- a/src/test/ui/array-slice-vec/vec-matching.rs +++ b/src/test/ui/array-slice-vec/vec-matching.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - fn a() { let x = [1]; match x { diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs index 3c7b160dcc540..5f1699227d8e6 100644 --- a/src/test/ui/array-slice-vec/vec-tail-matching.rs +++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - struct Foo { string: &'static str } diff --git a/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs index 4271ffb7b1b4d..0d0dbcaf40f43 100644 --- a/src/test/ui/binding/empty-types-in-patterns.rs +++ b/src/test/ui/binding/empty-types-in-patterns.rs @@ -1,7 +1,8 @@ // run-pass + #![feature(never_type, never_type_fallback)] #![feature(exhaustive_patterns)] -#![feature(slice_patterns)] + #![allow(unreachable_patterns)] #![allow(unreachable_code)] #![allow(unused_variables)] diff --git a/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs index ac733ef6e9c86..048e1e5e9b4b6 100644 --- a/src/test/ui/binding/irrefutable-slice-patterns.rs +++ b/src/test/ui/binding/irrefutable-slice-patterns.rs @@ -1,7 +1,6 @@ // run-pass -// #47096 -#![feature(slice_patterns)] +// Regression test for #47096. fn foo(s: &[i32]) -> &[i32] { let &[ref xs @ ..] = s; diff --git a/src/test/ui/binding/match-byte-array-patterns.rs b/src/test/ui/binding/match-byte-array-patterns.rs index e87745705da08..f0c988c01c2b8 100644 --- a/src/test/ui/binding/match-byte-array-patterns.rs +++ b/src/test/ui/binding/match-byte-array-patterns.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let buf = &[0u8; 4]; diff --git a/src/test/ui/binding/match-vec-alternatives.rs b/src/test/ui/binding/match-vec-alternatives.rs index 9b06a86a7b91e..af95eb95df04c 100644 --- a/src/test/ui/binding/match-vec-alternatives.rs +++ b/src/test/ui/binding/match-vec-alternatives.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { match (l1, l2) { diff --git a/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs index 5326fa612a87b..187c2983633e7 100644 --- a/src/test/ui/binding/zero_sized_subslice_match.rs +++ b/src/test/ui/binding/zero_sized_subslice_match.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let x = [(), ()]; diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs index a70ccb7aa4b73..0229ca37a692a 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs @@ -1,6 +1,5 @@ // Check that closure captures for slice patterns are inferred correctly -#![feature(slice_patterns)] #![allow(unused_variables)] // run-pass diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs index 984eb8804b7a2..32057d5c126ed 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs @@ -1,7 +1,5 @@ // Check that closure captures for slice patterns are inferred correctly -#![feature(slice_patterns)] - fn arr_by_ref(mut x: [String; 3]) { let f = || { let [ref y, ref z @ ..] = x; diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr index c5b27f5f8b403..483975e5778a8 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:9:13 + --> $DIR/borrowck-closures-slice-patterns.rs:7:13 | LL | let f = || { | -- immutable borrow occurs here @@ -13,7 +13,7 @@ LL | f(); | - immutable borrow later used here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-closures-slice-patterns.rs:18:13 + --> $DIR/borrowck-closures-slice-patterns.rs:16:13 | LL | let mut f = || { | -- mutable borrow occurs here @@ -27,7 +27,7 @@ LL | f(); | - mutable borrow later used here error[E0382]: borrow of moved value: `x` - --> $DIR/borrowck-closures-slice-patterns.rs:27:5 + --> $DIR/borrowck-closures-slice-patterns.rs:25:5 | LL | fn arr_by_move(x: [String; 3]) { | - move occurs because `x` has type `[std::string::String; 3]`, which does not implement the `Copy` trait @@ -40,7 +40,7 @@ LL | &x; | ^^ value borrowed here after move error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:35:13 + --> $DIR/borrowck-closures-slice-patterns.rs:33:13 | LL | let f = || { | -- immutable borrow occurs here @@ -54,7 +54,7 @@ LL | f(); | - immutable borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/borrowck-closures-slice-patterns.rs:44:13 + --> $DIR/borrowck-closures-slice-patterns.rs:42:13 | LL | let mut f = || { | -- closure construction occurs here @@ -68,7 +68,7 @@ LL | f(); | - first borrow later used here error[E0382]: borrow of moved value: `x` - --> $DIR/borrowck-closures-slice-patterns.rs:53:5 + --> $DIR/borrowck-closures-slice-patterns.rs:51:5 | LL | fn arr_box_by_move(x: Box<[String; 3]>) { | - move occurs because `x` has type `std::boxed::Box<[std::string::String; 3]>`, which does not implement the `Copy` trait @@ -81,7 +81,7 @@ LL | &x; | ^^ value borrowed here after move error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:61:13 + --> $DIR/borrowck-closures-slice-patterns.rs:59:13 | LL | let f = || { | -- immutable borrow occurs here @@ -95,7 +95,7 @@ LL | f(); | - immutable borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/borrowck-closures-slice-patterns.rs:70:13 + --> $DIR/borrowck-closures-slice-patterns.rs:68:13 | LL | let mut f = || { | -- closure construction occurs here diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs index 8425960aa8600..c8bfbe0729c59 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs @@ -1,7 +1,5 @@ // ignore-tidy-linelength -#![feature(slice_patterns)] - pub struct Foo { x: u32 } diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index 4213523d2fa4b..075e0e2e4515e 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:258:13 + --> $DIR/borrowck-describe-lvalue.rs:256:13 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -9,7 +9,7 @@ LL | *y = 1; | ------ first borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:268:20 + --> $DIR/borrowck-describe-lvalue.rs:266:20 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -19,7 +19,7 @@ LL | *y = 1; | ------ first borrow later used here error: captured variable cannot escape `FnMut` closure body - --> $DIR/borrowck-describe-lvalue.rs:266:16 + --> $DIR/borrowck-describe-lvalue.rs:264:16 | LL | || { | - inferred to be a `FnMut` closure @@ -35,7 +35,7 @@ LL | | } = note: ...therefore, they cannot allow references to captured variables to escape error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:41:9 + --> $DIR/borrowck-describe-lvalue.rs:39:9 | LL | let x = f.x(); | - borrow of `f` occurs here @@ -45,7 +45,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:48:9 + --> $DIR/borrowck-describe-lvalue.rs:46:9 | LL | let x = g.x(); | - borrow of `g` occurs here @@ -55,7 +55,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:55:9 + --> $DIR/borrowck-describe-lvalue.rs:53:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -65,7 +65,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:63:20 + --> $DIR/borrowck-describe-lvalue.rs:61:20 | LL | let x = e.x(); | - borrow of `e` occurs here @@ -77,7 +77,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:71:9 + --> $DIR/borrowck-describe-lvalue.rs:69:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -87,7 +87,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:78:9 + --> $DIR/borrowck-describe-lvalue.rs:76:9 | LL | let x = f.x(); | - borrow of `*f` occurs here @@ -97,7 +97,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:85:9 + --> $DIR/borrowck-describe-lvalue.rs:83:9 | LL | let x = g.x(); | - borrow of `*g` occurs here @@ -107,7 +107,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:92:9 + --> $DIR/borrowck-describe-lvalue.rs:90:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -117,7 +117,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:100:20 + --> $DIR/borrowck-describe-lvalue.rs:98:20 | LL | let x = e.x(); | - borrow of `*e` occurs here @@ -129,7 +129,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:109:9 + --> $DIR/borrowck-describe-lvalue.rs:107:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -139,7 +139,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:117:15 + --> $DIR/borrowck-describe-lvalue.rs:115:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -151,7 +151,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:122:18 + --> $DIR/borrowck-describe-lvalue.rs:120:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -163,7 +163,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:127:25 + --> $DIR/borrowck-describe-lvalue.rs:125:25 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -175,7 +175,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:132:28 + --> $DIR/borrowck-describe-lvalue.rs:130:28 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -187,7 +187,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:143:15 + --> $DIR/borrowck-describe-lvalue.rs:141:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -199,7 +199,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:148:18 + --> $DIR/borrowck-describe-lvalue.rs:146:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -211,7 +211,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:153:15 + --> $DIR/borrowck-describe-lvalue.rs:151:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -223,7 +223,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:158:18 + --> $DIR/borrowck-describe-lvalue.rs:156:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -235,7 +235,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:171:13 + --> $DIR/borrowck-describe-lvalue.rs:169:13 | LL | let x = &mut e; | ------ borrow of `e` occurs here @@ -247,7 +247,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:171:18 + --> $DIR/borrowck-describe-lvalue.rs:169:18 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -259,7 +259,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:175:23 + --> $DIR/borrowck-describe-lvalue.rs:173:23 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -271,7 +271,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:188:22 + --> $DIR/borrowck-describe-lvalue.rs:186:22 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -283,7 +283,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:194:28 + --> $DIR/borrowck-describe-lvalue.rs:192:28 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -295,7 +295,7 @@ LL | drop(x); | - mutable borrow later used here error[E0503]: cannot use `*v` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:236:9 + --> $DIR/borrowck-describe-lvalue.rs:234:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -306,7 +306,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[_].y` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:236:9 + --> $DIR/borrowck-describe-lvalue.rs:234:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -317,7 +317,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:247:24 + --> $DIR/borrowck-describe-lvalue.rs:245:24 | LL | let x = &mut v; | ------ mutable borrow occurs here @@ -329,7 +329,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:210:29 + --> $DIR/borrowck-describe-lvalue.rs:208:29 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -340,7 +340,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:225:33 + --> $DIR/borrowck-describe-lvalue.rs:223:33 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -351,7 +351,7 @@ LL | drop(x); | - mutable borrow later used here error[E0382]: use of moved value: `x` - --> $DIR/borrowck-describe-lvalue.rs:278:22 + --> $DIR/borrowck-describe-lvalue.rs:276:22 | LL | drop(x); | - value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs index 232d43679b484..c1513fcba8a66 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr index e46a58a8a3500..84930b000ccb3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-match.rs:15:14 + --> $DIR/borrowck-move-out-from-array-match.rs:13:14 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | [.., _y] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-match.rs:25:14 + --> $DIR/borrowck-move-out-from-array-match.rs:23:14 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | [.., _y] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:35:15 + --> $DIR/borrowck-move-out-from-array-match.rs:33:15 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | [.., (_y, _)] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:46:11 + --> $DIR/borrowck-move-out-from-array-match.rs:44:11 | LL | [_x, _, _] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:57:11 + --> $DIR/borrowck-move-out-from-array-match.rs:55:11 | LL | [.., _x] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:68:11 + --> $DIR/borrowck-move-out-from-array-match.rs:66:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:79:11 + --> $DIR/borrowck-move-out-from-array-match.rs:77:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:91:11 + --> $DIR/borrowck-move-out-from-array-match.rs:89:11 | LL | [_y @ .., _, _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | [(_x, _), _, _] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:101:15 + --> $DIR/borrowck-move-out-from-array-match.rs:99:15 | LL | [_, _, _y @ ..] => {} | ------- value moved here @@ -98,7 +98,7 @@ LL | [.., (_x, _)] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:112:11 + --> $DIR/borrowck-move-out-from-array-match.rs:110:11 | LL | [x @ .., _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs index e5e61697c68c6..056b8e672bd93 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs @@ -3,8 +3,6 @@ // Once the bug is fixed, the test, which is derived from a // passing test for `let` statements, should become check-pass. -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr index 72cd4207cce65..ff5eab2442c83 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:19:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:17:11 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:30:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:28:11 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:43:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:41:11 | LL | [_x, _, _] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:54:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:52:11 | LL | [.., _x] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:65:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:63:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:76:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:74:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:87:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} | ------- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:98:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:111:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs index 8f274cf73cb0e..c91b4286b6478 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs index 1ca3df52ada91..604a25cdcc1d6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr index 028442a4c07ea..0ef63105cfbd3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:15:14 + --> $DIR/borrowck-move-out-from-array-use-match.rs:13:14 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | [.., ref _y] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:25:14 + --> $DIR/borrowck-move-out-from-array-use-match.rs:23:14 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | [.., ref _y] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-use-match.rs:35:15 + --> $DIR/borrowck-move-out-from-array-use-match.rs:33:15 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | [.., (ref _y, _)] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:46:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:44:11 | LL | [_x, _, _] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:57:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:55:11 | LL | [.., _x] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:68:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:66:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:79:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:77:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:91:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:89:11 | LL | [_y @ .., _, _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | [(ref _x, _), _, _] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:101:15 + --> $DIR/borrowck-move-out-from-array-use-match.rs:99:15 | LL | [_, _, _y @ ..] => {} | ------- value moved here @@ -98,7 +98,7 @@ LL | [.., (ref _x, _)] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:112:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:110:11 | LL | [x @ .., _] => {} | ------ value moved here @@ -109,7 +109,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:125:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:123:5 | LL | [_, _, _x] => {} | -- value moved here @@ -120,7 +120,7 @@ LL | a[2] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:133:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:131:5 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -131,7 +131,7 @@ LL | a[2].1 = Default::default(); = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:141:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:139:5 | LL | [_, _, _x @ ..] => {} | ------- value moved here @@ -142,7 +142,7 @@ LL | a[0] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:149:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:147:5 | LL | [_, _, _x @ ..] => {} | ------- value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs index 79fe593009652..5afd6835dcfb6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs @@ -3,8 +3,6 @@ // Once the bug is fixed, the test, which is derived from a // passing test for `let` statements, should become check-pass. -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr index 43ba2b664a1e1..a4042ce7db336 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:19:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:17:11 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:30:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:28:11 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:43:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:41:11 | LL | [_x, _, _] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:54:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:52:11 | LL | [.., _x] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:65:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:63:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:76:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:74:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:87:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} | ------- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:98:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:111:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs index 57ce2417570b0..e3498cef37719 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs index 778beefbf2c85..ad08367a3b5b3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr index 2a7b89132c1b7..7ad4116645e93 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:12:14 + --> $DIR/borrowck-move-out-from-array-use.rs:10:14 | LL | let [_, _, _x] = a; | -- value moved here @@ -9,7 +9,7 @@ LL | let [.., ref _y] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:18:14 + --> $DIR/borrowck-move-out-from-array-use.rs:16:14 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -19,7 +19,7 @@ LL | let [.., ref _y] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-use.rs:24:15 + --> $DIR/borrowck-move-out-from-array-use.rs:22:15 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -29,7 +29,7 @@ LL | let [.., (ref _y, _)] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:32:10 + --> $DIR/borrowck-move-out-from-array-use.rs:30:10 | LL | let [_x, _, _] = a; | -- value moved here @@ -39,7 +39,7 @@ LL | let [ref _y @ .., _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:38:16 + --> $DIR/borrowck-move-out-from-array-use.rs:36:16 | LL | let [.., _x] = a; | -- value moved here @@ -49,7 +49,7 @@ LL | let [_, _, ref _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:44:10 + --> $DIR/borrowck-move-out-from-array-use.rs:42:10 | LL | let [(_x, _), _, _] = a; | -- value moved here @@ -59,7 +59,7 @@ LL | let [ref _y @ .., _, _] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:50:16 + --> $DIR/borrowck-move-out-from-array-use.rs:48:16 | LL | let [.., (_x, _)] = a; | -- value moved here @@ -69,7 +69,7 @@ LL | let [_, _, ref _y @ ..] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:56:11 + --> $DIR/borrowck-move-out-from-array-use.rs:54:11 | LL | let [_y @ .., _, _] = a; | ------- value moved here @@ -79,7 +79,7 @@ LL | let [(ref _x, _), _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:62:15 + --> $DIR/borrowck-move-out-from-array-use.rs:60:15 | LL | let [_, _, _y @ ..] = a; | ------- value moved here @@ -89,7 +89,7 @@ LL | let [.., (ref _x, _)] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:70:13 + --> $DIR/borrowck-move-out-from-array-use.rs:68:13 | LL | let [x @ .., _] = a; | ------ value moved here @@ -99,7 +99,7 @@ LL | let [_, ref _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:78:5 + --> $DIR/borrowck-move-out-from-array-use.rs:76:5 | LL | let [_, _, _x] = a; | -- value moved here @@ -109,7 +109,7 @@ LL | a[2] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:84:5 + --> $DIR/borrowck-move-out-from-array-use.rs:82:5 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -119,7 +119,7 @@ LL | a[2].1 = Default::default(); = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:90:5 + --> $DIR/borrowck-move-out-from-array-use.rs:88:5 | LL | let [_, _, _x @ ..] = a; | ------- value moved here @@ -129,7 +129,7 @@ LL | a[0] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:96:5 + --> $DIR/borrowck-move-out-from-array-use.rs:94:5 | LL | let [_, _, _x @ ..] = a; | ------- value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs index f9d3f6f2c0724..83755812f4b32 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr index 08134a2a323e7..b7babd93ed7a6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array.rs:12:14 + --> $DIR/borrowck-move-out-from-array.rs:10:14 | LL | let [_, _, _x] = a; | -- value moved here @@ -9,7 +9,7 @@ LL | let [.., _y] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array.rs:18:14 + --> $DIR/borrowck-move-out-from-array.rs:16:14 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -19,7 +19,7 @@ LL | let [.., _y] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:24:15 + --> $DIR/borrowck-move-out-from-array.rs:22:15 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -29,7 +29,7 @@ LL | let [.., (_y, _)] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:32:10 + --> $DIR/borrowck-move-out-from-array.rs:30:10 | LL | let [_x, _, _] = a; | -- value moved here @@ -39,7 +39,7 @@ LL | let [_y @ .., _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:38:16 + --> $DIR/borrowck-move-out-from-array.rs:36:16 | LL | let [.., _x] = a; | -- value moved here @@ -49,7 +49,7 @@ LL | let [_, _, _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:44:10 + --> $DIR/borrowck-move-out-from-array.rs:42:10 | LL | let [(_x, _), _, _] = a; | -- value moved here @@ -59,7 +59,7 @@ LL | let [_y @ .., _, _] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:50:16 + --> $DIR/borrowck-move-out-from-array.rs:48:16 | LL | let [.., (_x, _)] = a; | -- value moved here @@ -69,7 +69,7 @@ LL | let [_, _, _y @ ..] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:56:11 + --> $DIR/borrowck-move-out-from-array.rs:54:11 | LL | let [_y @ .., _, _] = a; | ------- value moved here @@ -79,7 +79,7 @@ LL | let [(_x, _), _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:62:15 + --> $DIR/borrowck-move-out-from-array.rs:60:15 | LL | let [_, _, _y @ ..] = a; | ------- value moved here @@ -89,7 +89,7 @@ LL | let [.., (_x, _)] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:70:13 + --> $DIR/borrowck-move-out-from-array.rs:68:13 | LL | let [x @ .., _] = a; | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs index fa9a3c217db77..8ece81a3c845e 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs @@ -1,7 +1,5 @@ // Test that we do not permit moves from &[] matched by a vec pattern. -#![feature(slice_patterns)] - #[derive(Clone, Debug)] struct Foo { string: String diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr index 8fb4c062c0363..a345c1238f02c 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[Foo]`, a non-copy slice - --> $DIR/borrowck-move-out-of-vec-tail.rs:19:19 + --> $DIR/borrowck-move-out-of-vec-tail.rs:17:19 | LL | match tail { | ^^^^ cannot move out of here diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs index 7d91a21264723..a8e56f648e2e5 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs index f03a2ab8fa8e4..6b210d73228f8 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr index e50e7eb3e2230..0432aaf51d29f 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:8:13 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:6:13 | LL | let [ref first, ref second, ..] = *s; | ---------- immutable borrow occurs here @@ -9,7 +9,7 @@ LL | nop(&[first, second, second2, third]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:14:14 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:12:14 | LL | let [.., ref fourth, ref third, _, ref first] = *s; | --------- immutable borrow occurs here @@ -19,7 +19,7 @@ LL | nop(&[first, third, third2, fourth]); | ----- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:16 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:19:16 | LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; | ------------- immutable borrow occurs here @@ -30,7 +30,7 @@ LL | nop(&[from_begin2, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:23:19 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:19 | LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; | ------------- immutable borrow occurs here @@ -41,7 +41,7 @@ LL | nop(&[from_begin3, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:28:14 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:26:14 | LL | let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s; | --------------- immutable borrow occurs here @@ -52,7 +52,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end3]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:34:13 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:32:13 | LL | let [ref first, ref second, ..] = *s; | ---------- immutable borrow occurs here @@ -62,7 +62,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:41:10 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:39:10 | LL | let [.., ref second, ref first] = *s; | ---------- immutable borrow occurs here @@ -72,7 +72,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:48:10 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:46:10 | LL | let [_, ref s1 @ ..] = *s; | ----------- immutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 048813b2b93e6..1c9c052970f9a 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -1,7 +1,5 @@ // run-pass -//compile-flags: -Z borrowck=mir - -#![feature(slice_patterns)] +// compile-flags: -Z borrowck=mir fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs index e69071f87720b..6390dc3a91a0d 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs index 2ef98741dc35a..0e1c90a1cd83d 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr index b6f5ac64b2061..d3388e071aa53 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:8:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:6:20 | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here @@ -9,7 +9,7 @@ LL | nop(&[first, second, second2, third]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:16:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:14:21 | LL | if let [.., ref fourth, ref third, _, ref first] = *s { | --------- immutable borrow occurs here @@ -19,7 +19,7 @@ LL | nop(&[first, third, third2, fourth]); | ----- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:24:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:22:20 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -29,7 +29,7 @@ LL | nop(&[from_begin1, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:27:23 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:25:23 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -40,7 +40,7 @@ LL | nop(&[from_begin2, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:30:26 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:28:26 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -51,7 +51,7 @@ LL | nop(&[from_begin3, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:35:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:33:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -61,7 +61,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end2]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:38:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:36:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -72,7 +72,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end3]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:41:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:39:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -83,7 +83,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end4]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:49:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:47:20 | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here @@ -93,7 +93,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:58:17 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:56:17 | LL | if let [.., ref second, ref first] = *s { | ---------- immutable borrow occurs here @@ -103,7 +103,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:67:17 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:65:17 | LL | if let [_, _, _, ref s1 @ ..] = *s { | ----------- immutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs index 53a9bcef74a22..cd853b83363ab 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr index da6d9293b408a..170982b1693fb 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:10:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:8:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here @@ -8,7 +8,7 @@ LL | tail | ^^^^ returns a value referencing data owned by the current function error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:20:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:18:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here @@ -17,7 +17,7 @@ LL | init | ^^^^ returns a value referencing data owned by the current function error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:30:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:28:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs index dd9023f6d9f79..05859c95d174d 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a() { let mut v = vec![1, 2, 3]; let vb: &mut [isize] = &mut v; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr index 251f44592905d..5141fcc1bb261 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time - --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:8:13 + --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:6:13 | LL | let vb: &mut [isize] = &mut v; | ------ first mutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs index 420223009a45b..9b8ba2ea8adc5 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs @@ -1,7 +1,3 @@ -// http://rust-lang.org/COPYRIGHT. - -#![feature(slice_patterns)] - fn main() { let mut a = [1, 2, 3, 4]; let t = match a { diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr index 9f8e6fe3b6898..ff70ba9fcca8b 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5 + --> $DIR/borrowck-vec-pattern-move-tail.rs:8:5 | LL | [1, 2, ref tail @ ..] => tail, | ------------- borrow of `a[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs index e274d105e0503..67b6c12ba803a 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -1,6 +1,5 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(slice_patterns)] fn a() { let mut vec = [box 1, box 2, box 3]; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index a3324f25d0bb5..e2c0852dd83c6 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:10:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:9:13 | LL | [box ref _a, _, _] => { | ------ borrow of `vec[_]` occurs here @@ -11,7 +11,7 @@ LL | _a.use_ref(); | -- borrow later used here error[E0506]: cannot assign to `vec[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:24:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:23:13 | LL | &mut [ref _b @ ..] => { | ----------- borrow of `vec[_]` occurs here @@ -23,7 +23,7 @@ LL | _b.use_ref(); | -- borrow later used here error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:35:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:34:11 | LL | match vec { | ^^^ cannot move out of here @@ -45,7 +45,7 @@ LL | ] => { | error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:47:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:46:13 | LL | let a = vec[0]; | ^^^^^^ @@ -55,7 +55,7 @@ LL | let a = vec[0]; | help: consider borrowing here: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:56:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:55:11 | LL | match vec { | ^^^ cannot move out of here @@ -74,7 +74,7 @@ LL | _b] => {} | error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:66:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:65:13 | LL | let a = vec[0]; | ^^^^^^ @@ -84,7 +84,7 @@ LL | let a = vec[0]; | help: consider borrowing here: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:75:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:74:11 | LL | match vec { | ^^^ cannot move out of here @@ -100,7 +100,7 @@ LL | &mut [_a, _b, _c] => {} = note: move occurs because these variables have types that don't implement the `Copy` trait error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:86:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:85:13 | LL | let a = vec[0]; | ^^^^^^ diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs index c35be2f6be62c..39872825cd2a4 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a<'a>() -> &'a isize { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr index c1290a6f63f33..7e21c55f21b5f 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:10:5 + --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:8:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here diff --git a/src/test/ui/consts/const_prop_slice_pat_ice.rs b/src/test/ui/consts/const_prop_slice_pat_ice.rs index 5fec36e44bd8c..60b06a497d6de 100644 --- a/src/test/ui/consts/const_prop_slice_pat_ice.rs +++ b/src/test/ui/consts/const_prop_slice_pat_ice.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn main() { match &[0, 1] as &[i32] { diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 91063edf0f6c4..30a8960594493 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -7,7 +7,6 @@ // edition:2018 // ignore-wasm32-bare compiled with panic=abort by default -#![feature(slice_patterns)] #![allow(unused)] use std::{ diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index 0f0ec0ba460c8..b4406204a5db9 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -1,11 +1,10 @@ // run-pass -#![allow(unused_assignments)] -#![allow(unused_variables)] - // ignore-wasm32-bare compiled with panic=abort by default #![feature(generators, generator_trait, untagged_unions)] -#![feature(slice_patterns)] + +#![allow(unused_assignments)] +#![allow(unused_variables)] use std::cell::{Cell, RefCell}; use std::mem::ManuallyDrop; diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs index 17d03b14fc6e1..0a337c9611c8b 100644 --- a/src/test/ui/error-codes/E0528.rs +++ b/src/test/ui/error-codes/E0528.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { let r = &[1, 2]; match r { diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr index 0f566091145bf..21615f954c363 100644 --- a/src/test/ui/error-codes/E0528.stderr +++ b/src/test/ui/error-codes/E0528.stderr @@ -1,5 +1,5 @@ error[E0528]: pattern requires at least 3 elements but array has 2 - --> $DIR/E0528.rs:6:10 + --> $DIR/E0528.rs:4:10 | LL | &[a, b, c, rest @ ..] => { | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs index 8c046a289fad2..ab90a69ce6f06 100644 --- a/src/test/ui/ignore-all-the-things.rs +++ b/src/test/ui/ignore-all-the-things.rs @@ -1,11 +1,9 @@ // run-pass +// pretty-expanded FIXME #23616 #![allow(non_shorthand_field_patterns)] #![allow(dead_code)] #![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -#![feature(slice_patterns)] struct Foo(isize, isize, isize, isize); struct Bar{a: isize, b: isize, c: isize, d: isize} diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs index 0866131807463..0481c1fd9e1bb 100644 --- a/src/test/ui/issues/issue-12369.rs +++ b/src/test/ui/issues/issue-12369.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr index f27425e28c61d..754b94bab75eb 100644 --- a/src/test/ui/issues/issue-12369.stderr +++ b/src/test/ui/issues/issue-12369.stderr @@ -1,11 +1,11 @@ error: unreachable pattern - --> $DIR/issue-12369.rs:10:9 + --> $DIR/issue-12369.rs:9:9 | LL | &[10,a, ref rest @ ..] => 10 | ^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-12369.rs:2:9 + --> $DIR/issue-12369.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-12567.rs b/src/test/ui/issues/issue-12567.rs index 643d9a2fc69e9..1b2a37de47539 100644 --- a/src/test/ui/issues/issue-12567.rs +++ b/src/test/ui/issues/issue-12567.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) { match (l1, l2) { //~^ ERROR: cannot move out of type `[T]`, a non-copy slice diff --git a/src/test/ui/issues/issue-12567.stderr b/src/test/ui/issues/issue-12567.stderr index 9d9a88f4f9b06..2a88d8f0524ac 100644 --- a/src/test/ui/issues/issue-12567.stderr +++ b/src/test/ui/issues/issue-12567.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[T]`, a non-copy slice - --> $DIR/issue-12567.rs:4:11 + --> $DIR/issue-12567.rs:2:11 | LL | match (l1, l2) { | ^^^^^^^^ cannot move out of here @@ -13,7 +13,7 @@ LL | (&[hd1, ..], &[hd2, ..]) = note: move occurs because these variables have types that don't implement the `Copy` trait error[E0508]: cannot move out of type `[T]`, a non-copy slice - --> $DIR/issue-12567.rs:4:11 + --> $DIR/issue-12567.rs:2:11 | LL | match (l1, l2) { | ^^^^^^^^ cannot move out of here diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs index b11b1cda38ae1..4dd6981d448e5 100644 --- a/src/test/ui/issues/issue-15080.rs +++ b/src/test/ui/issues/issue-15080.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let mut x: &[_] = &[1, 2, 3, 4]; diff --git a/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs index ee977541137db..47b207ea9cbf5 100644 --- a/src/test/ui/issues/issue-15104.rs +++ b/src/test/ui/issues/issue-15104.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { assert_eq!(count_members(&[1, 2, 3, 4]), 4); diff --git a/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs index fefa3f2f87304..126e01de5ee3f 100644 --- a/src/test/ui/issues/issue-17877.rs +++ b/src/test/ui/issues/issue-17877.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { assert_eq!(match [0u8; 1024] { diff --git a/src/test/ui/issues/issue-23311.rs b/src/test/ui/issues/issue-23311.rs index f275c6338b194..62c96840b3bc4 100644 --- a/src/test/ui/issues/issue-23311.rs +++ b/src/test/ui/issues/issue-23311.rs @@ -1,7 +1,6 @@ // run-pass -// Test that we do not ICE when pattern matching an array against a slice. -#![feature(slice_patterns)] +// Test that we do not ICE when pattern matching an array against a slice. fn main() { match "foo".as_bytes() { diff --git a/src/test/ui/issues/issue-26619.rs b/src/test/ui/issues/issue-26619.rs index 00e09f3f07764..b9d34b0555aee 100644 --- a/src/test/ui/issues/issue-26619.rs +++ b/src/test/ui/issues/issue-26619.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - pub struct History<'a> { pub _s: &'a str } impl<'a> History<'a> { diff --git a/src/test/ui/issues/issue-26619.stderr b/src/test/ui/issues/issue-26619.stderr index d1157cda92bf8..1282fd7d3c238 100644 --- a/src/test/ui/issues/issue-26619.stderr +++ b/src/test/ui/issues/issue-26619.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing function parameter - --> $DIR/issue-26619.rs:7:76 + --> $DIR/issue-26619.rs:5:76 | LL | for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { | -------- ^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs index 31b3aba6bc204..458e999c3faa2 100644 --- a/src/test/ui/issues/issue-37598.rs +++ b/src/test/ui/issues/issue-37598.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn check(list: &[u8]) { match list { diff --git a/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs index 5b70bd6e5ff54..b7323f09daff2 100644 --- a/src/test/ui/issues/issue-7784.rs +++ b/src/test/ui/issues/issue-7784.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] use std::ops::Add; diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/match/match-vec-mismatch.rs index a0ef92743ac5a..34adb42a32f96 100644 --- a/src/test/ui/match/match-vec-mismatch.rs +++ b/src/test/ui/match/match-vec-mismatch.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { match "foo".to_string() { ['f', 'o', ..] => {} diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr index a3523bb689e6b..4b0e429e51ca5 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/match/match-vec-mismatch.stderr @@ -1,29 +1,29 @@ error[E0425]: cannot find value `does_not_exist` in this scope - --> $DIR/match-vec-mismatch.rs:28:11 + --> $DIR/match-vec-mismatch.rs:26:11 | LL | match does_not_exist { | ^^^^^^^^^^^^^^ not found in this scope error[E0529]: expected an array or slice, found `std::string::String` - --> $DIR/match-vec-mismatch.rs:5:9 + --> $DIR/match-vec-mismatch.rs:3:9 | LL | ['f', 'o', ..] => {} | ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String` error[E0527]: pattern requires 1 element but array has 3 - --> $DIR/match-vec-mismatch.rs:20:9 + --> $DIR/match-vec-mismatch.rs:18:9 | LL | [0] => {}, | ^^^ expected 3 elements error[E0528]: pattern requires at least 4 elements but array has 3 - --> $DIR/match-vec-mismatch.rs:25:9 + --> $DIR/match-vec-mismatch.rs:23:9 | LL | [0, 1, 2, 3, x @ ..] => {} | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed - --> $DIR/match-vec-mismatch.rs:36:9 + --> $DIR/match-vec-mismatch.rs:34:9 | LL | [] => {} | ^^ cannot infer type diff --git a/src/test/ui/moves/move-out-of-array-ref.rs b/src/test/ui/moves/move-out-of-array-ref.rs index 4ca60ddfec27c..343f00ff29181 100644 --- a/src/test/ui/moves/move-out-of-array-ref.rs +++ b/src/test/ui/moves/move-out-of-array-ref.rs @@ -1,7 +1,5 @@ // Ensure that we cannot move out of a reference to a fixed-size array -#![feature(slice_patterns)] - struct D { _x: u8 } impl Drop for D { fn drop(&mut self) { } } diff --git a/src/test/ui/moves/move-out-of-array-ref.stderr b/src/test/ui/moves/move-out-of-array-ref.stderr index ae3d2f5f2826a..fd682e56ae1de 100644 --- a/src/test/ui/moves/move-out-of-array-ref.stderr +++ b/src/test/ui/moves/move-out-of-array-ref.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:10:24 + --> $DIR/move-out-of-array-ref.rs:8:24 | LL | let [_, e, _, _] = *a; | - ^^ @@ -10,7 +10,7 @@ LL | let [_, e, _, _] = *a; | move occurs because `e` has type `D`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:15:27 + --> $DIR/move-out-of-array-ref.rs:13:27 | LL | let [_, s @ .. , _] = *a; | ------ ^^ @@ -21,7 +21,7 @@ LL | let [_, s @ .. , _] = *a; | move occurs because `s` has type `[D; 2]`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:20:24 + --> $DIR/move-out-of-array-ref.rs:18:24 | LL | let [_, e, _, _] = *a; | - ^^ @@ -32,7 +32,7 @@ LL | let [_, e, _, _] = *a; | move occurs because `e` has type `D`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:25:27 + --> $DIR/move-out-of-array-ref.rs:23:27 | LL | let [_, s @ .. , _] = *a; | ------ ^^ diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs index d7c191bb5a28d..8b0be2e7a66b4 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.rs b/src/test/ui/or-patterns/exhaustiveness-pass.rs index ce0fe6fc2a375..f0dc3447f3154 100644 --- a/src/test/ui/or-patterns/exhaustiveness-pass.rs +++ b/src/test/ui/or-patterns/exhaustiveness-pass.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 860c7a1bde5fb..81bc1176f572e 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index 00f4374b256d2..97e33624bf6de 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -3,8 +3,6 @@ fn main() { match a { [1, tail @ .., tail @ ..] => {}, //~^ ERROR identifier `tail` is bound more than once in the same pattern - //~| ERROR subslice patterns are unstable - //~| ERROR subslice patterns are unstable //~| ERROR `..` can only be used once per slice pattern _ => () } diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index 58343e86d7b2d..1dc11c31905c4 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -4,24 +4,6 @@ error[E0416]: identifier `tail` is bound more than once in the same pattern LL | [1, tail @ .., tail @ ..] => {}, | ^^^^ used in a pattern more than once -error[E0658]: subslice patterns are unstable - --> $DIR/match-vec-invalid.rs:4:13 - | -LL | [1, tail @ .., tail @ ..] => {}, - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/match-vec-invalid.rs:4:24 - | -LL | [1, tail @ .., tail @ ..] => {}, - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - error: `..` can only be used once per slice pattern --> $DIR/match-vec-invalid.rs:4:31 | @@ -31,12 +13,12 @@ LL | [1, tail @ .., tail @ ..] => {}, | previously used here error[E0308]: mismatched types - --> $DIR/match-vec-invalid.rs:13:30 + --> $DIR/match-vec-invalid.rs:11:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0308, E0416, E0658. +Some errors have detailed explanations: E0308, E0416. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs index f27caa5d78c8e..7becffa9fe2f7 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.rs +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -4,7 +4,6 @@ fn main() { let Test(&desc[..]) = x; //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[` - //~^^ ERROR subslice patterns are unstable } const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index fe9603cb57f1f..035d0dbfe06d6 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -7,22 +7,12 @@ LL | let Test(&desc[..]) = x; | expected one of `)`, `,`, `@`, or `|` | help: missing `,` -error[E0658]: subslice patterns are unstable - --> $DIR/pat-lt-bracket-6.rs:5:20 - | -LL | let Test(&desc[..]) = x; - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - error[E0308]: mismatched types - --> $DIR/pat-lt-bracket-6.rs:10:30 + --> $DIR/pat-lt-bracket-6.rs:9:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs index 1d9f341c5146a..2cd375da9a56f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -1,7 +1,6 @@ // Test that moving on both sides of an `@` pattern is not allowed. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; // Not copy! diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index f3f8fd655ce0c..12ebcb72af11c 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -1,53 +1,53 @@ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:12:9 + --> $DIR/borrowck-move-and-move.rs:11:9 | LL | let a @ b = U; | ^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:16:9 + --> $DIR/borrowck-move-and-move.rs:15:9 | LL | let a @ (b, c) = (U, U); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:20:9 + --> $DIR/borrowck-move-and-move.rs:19:9 | LL | let a @ (b, c) = (u(), u()); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:25:9 + --> $DIR/borrowck-move-and-move.rs:24:9 | LL | a @ Ok(b) | a @ Err(b) => {} | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:25:21 + --> $DIR/borrowck-move-and-move.rs:24:21 | LL | a @ Ok(b) | a @ Err(b) => {} | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:37:9 + --> $DIR/borrowck-move-and-move.rs:36:9 | LL | xs @ [a, .., b] => {} | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:43:9 + --> $DIR/borrowck-move-and-move.rs:42:9 | LL | xs @ [_, ys @ .., _] => {} | ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:32:12 + --> $DIR/borrowck-move-and-move.rs:31:12 | LL | fn fun(a @ b: U) {} | ^^^^^ binds an already bound by-move value by moving it error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:12:13 + --> $DIR/borrowck-move-and-move.rs:11:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -56,7 +56,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:16:17 + --> $DIR/borrowck-move-and-move.rs:15:17 | LL | let a @ (b, c) = (U, U); | --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -65,7 +65,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:20:17 + --> $DIR/borrowck-move-and-move.rs:19:17 | LL | let a @ (b, c) = (u(), u()); | --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -74,7 +74,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:16 + --> $DIR/borrowck-move-and-move.rs:24:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -85,7 +85,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:29 + --> $DIR/borrowck-move-and-move.rs:24:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -96,7 +96,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:37:22 + --> $DIR/borrowck-move-and-move.rs:36:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -107,7 +107,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:43:18 + --> $DIR/borrowck-move-and-move.rs:42:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -118,7 +118,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:32:16 + --> $DIR/borrowck-move-and-move.rs:31:16 | LL | fn fun(a @ b: U) {} | ----^ diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index afac8d990b474..092bd1133dd62 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -4,7 +4,6 @@ #![feature(bindings_after_at)] #![feature(box_patterns)] -#![feature(slice_patterns)] #[derive(Copy, Clone)] struct C; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index fce31409e16c4..3b2f598dc0157 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -2,7 +2,6 @@ #![feature(bindings_after_at)] #![feature(box_patterns)] -#![feature(slice_patterns)] #[derive(Copy, Clone)] struct C; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 5772fadd1e741..e96c15b0fa7dd 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,23 +1,23 @@ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:17:9 + --> $DIR/borrowck-pat-at-and-box.rs:16:9 | LL | let a @ box &b = Box::new(&C); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:21:9 + --> $DIR/borrowck-pat-at-and-box.rs:20:9 | LL | let a @ box b = Box::new(C); | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:33:25 + --> $DIR/borrowck-pat-at-and-box.rs:32:25 | LL | match Box::new(C) { a @ box b => {} } | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:37:21 + --> $DIR/borrowck-pat-at-and-box.rs:36:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -26,7 +26,7 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:39:9 + --> $DIR/borrowck-pat-at-and-box.rs:38:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -35,7 +35,7 @@ LL | let ref a @ box ref mut b = Box::new(nc()); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:41:9 + --> $DIR/borrowck-pat-at-and-box.rs:40:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -44,7 +44,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:43:9 + --> $DIR/borrowck-pat-at-and-box.rs:42:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -53,7 +53,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:46:9 + --> $DIR/borrowck-pat-at-and-box.rs:45:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -62,7 +62,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:52:9 + --> $DIR/borrowck-pat-at-and-box.rs:51:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -71,7 +71,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:66:9 + --> $DIR/borrowck-pat-at-and-box.rs:65:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- @@ -80,7 +80,7 @@ LL | ref mut a @ box ref b => { | mutable borrow occurs here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:75:38 + --> $DIR/borrowck-pat-at-and-box.rs:74:38 | LL | box [Ok(a), ref xs @ .., Err(b)] => {} | ----------- ^ by-move pattern here @@ -88,7 +88,7 @@ LL | box [Ok(a), ref xs @ .., Err(b)] => {} | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:81:46 + --> $DIR/borrowck-pat-at-and-box.rs:80:46 | LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | ----- ----------- ^ --------- by-ref pattern here @@ -98,19 +98,19 @@ LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | by-ref pattern here error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:25:11 + --> $DIR/borrowck-pat-at-and-box.rs:24:11 | LL | fn f1(a @ box &b: Box<&C>) {} | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:29:11 + --> $DIR/borrowck-pat-at-and-box.rs:28:11 | LL | fn f2(a @ box b: Box) {} | ^^^^^^^^^ binds an already bound by-move value by moving it error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:58:11 + --> $DIR/borrowck-pat-at-and-box.rs:57:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -119,7 +119,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { | mutable borrow occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:17:18 + --> $DIR/borrowck-pat-at-and-box.rs:16:18 | LL | let a @ box &b = Box::new(&C); | ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait @@ -128,7 +128,7 @@ LL | let a @ box &b = Box::new(&C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:21:17 + --> $DIR/borrowck-pat-at-and-box.rs:20:17 | LL | let a @ box b = Box::new(C); | --------^ ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -137,7 +137,7 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:33:33 + --> $DIR/borrowck-pat-at-and-box.rs:32:33 | LL | match Box::new(C) { a @ box b => {} } | ----------- --------^ @@ -147,7 +147,7 @@ LL | match Box::new(C) { a @ box b => {} } | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:46:21 + --> $DIR/borrowck-pat-at-and-box.rs:45:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -159,7 +159,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:52:25 + --> $DIR/borrowck-pat-at-and-box.rs:51:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -171,7 +171,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:66:25 + --> $DIR/borrowck-pat-at-and-box.rs:65:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -183,7 +183,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:25:20 + --> $DIR/borrowck-pat-at-and-box.rs:24:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -193,7 +193,7 @@ LL | fn f1(a @ box &b: Box<&C>) {} | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:29:19 + --> $DIR/borrowck-pat-at-and-box.rs:28:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -203,7 +203,7 @@ LL | fn f2(a @ box b: Box) {} | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:58:27 + --> $DIR/borrowck-pat-at-and-box.rs:57:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index be19e5f2a85ca..c4ce50c8b9a16 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -2,7 +2,6 @@ // Test `Copy` bindings in the rhs of `@` patterns. -#![feature(slice_patterns)] #![feature(bindings_after_at)] #[derive(Copy, Clone)] diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs index edf9fb3145890..fb243016a1185 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -4,7 +4,6 @@ // of an `@` pattern according to NLL borrowck. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; // Not copy! diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index 559925c282f9a..e8510dfa64999 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -1,5 +1,4 @@ #![feature(bindings_after_at)] -#![feature(slice_patterns)] enum Option { None, diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index b5c26a1fa0399..0d7b703f1816b 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,5 +1,5 @@ error: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ @@ -8,7 +8,7 @@ LL | ref mut z @ &mut Some(ref a) => { | mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ @@ -18,7 +18,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | first mutable borrow occurs here error: cannot borrow `b` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:22 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- @@ -27,7 +27,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:36:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -36,7 +36,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:38:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -45,7 +45,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:40:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -55,7 +55,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:42:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -65,7 +65,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -74,7 +74,7 @@ LL | let ref mut a @ ref b = u(); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -83,7 +83,7 @@ LL | let ref a @ ref mut b = u(); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:56:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -92,7 +92,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:60:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -101,7 +101,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -110,7 +110,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -119,7 +119,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -128,7 +128,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -137,7 +137,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -146,7 +146,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -155,7 +155,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -164,7 +164,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -173,7 +173,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ @@ -182,7 +182,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ @@ -191,7 +191,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -200,7 +200,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -209,7 +209,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:116:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -219,7 +219,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -229,7 +229,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -239,7 +239,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -249,7 +249,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- @@ -258,7 +258,7 @@ LL | fn f1(ref a @ ref mut b: U) {} | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- @@ -267,7 +267,7 @@ LL | fn f2(ref mut a @ ref b: U) {} | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ @@ -276,7 +276,7 @@ LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | immutable borrow occurs here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -288,7 +288,7 @@ LL | **z = None; | ---------- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -300,7 +300,7 @@ LL | *a = u(); | -------- mutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -312,7 +312,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -324,7 +324,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -336,7 +336,7 @@ LL | drop(a); | - immutable borrow later used here error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -344,7 +344,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } = note: variables bound in patterns are immutable until the end of the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -352,7 +352,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa = note: variables bound in patterns are immutable until the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -360,7 +360,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -368,7 +368,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -376,7 +376,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -384,7 +384,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -396,7 +396,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -408,7 +408,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -420,7 +420,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index 6b8b7545e687d..f425b35630d17 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -1,7 +1,6 @@ // Test that `ref mut x @ ref mut y` and varieties of that are not allowed. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 1b5e6c7411703..d07ad140cc23a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,5 +1,5 @@ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -8,7 +8,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -17,7 +17,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -26,7 +26,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -35,7 +35,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -44,7 +44,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:43:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ( | ^-------- @@ -66,7 +66,7 @@ LL | | ) = (U, [U, U, U]); | |_____^ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:53:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 | LL | let ref mut a @ ( | ^-------- @@ -88,31 +88,31 @@ LL | | ) = (u(), [u(), u(), u()]); | |_________^ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:63:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:67:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:71:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ &mut ref mut b = &mut U; | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:79:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -121,7 +121,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:79:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -130,7 +130,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:85:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -139,7 +139,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:85:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -148,7 +148,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -157,7 +157,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -166,7 +166,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -175,7 +175,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -184,7 +184,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -193,7 +193,7 @@ LL | fn f1(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -202,7 +202,7 @@ LL | fn f2(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9 | LL | ref mut a @ [ | ^-------- @@ -220,7 +220,7 @@ LL | | ] : [[U; 4]; 5] | |_________^ error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:25:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -232,7 +232,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:35:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -244,7 +244,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:63:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -253,7 +253,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:67:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait @@ -262,7 +262,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:71:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18 | LL | let a @ &mut ref mut b = &mut U; | ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait @@ -271,7 +271,7 @@ LL | let a @ &mut ref mut b = &mut U; | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:74:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait @@ -280,7 +280,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | value moved here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -292,7 +292,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -304,7 +304,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -316,7 +316,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs index c910cded96be4..1249329206112 100644 --- a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs +++ b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs @@ -2,8 +2,6 @@ // This used to cause a stack overflow in the compiler. -#![feature(slice_patterns)] - fn main() { const LARGE_SIZE: usize = 1024 * 1024; let [..] = [0u8; LARGE_SIZE]; diff --git a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs b/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs index 6c54c938bf110..54dfa889ee35a 100644 --- a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs +++ b/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(slice_patterns)] + #![deny(unreachable_patterns)] const C0: &'static [u8] = b"\x00"; diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs index 7541ea3e2e263..9b6c8bd5556be 100644 --- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr index b28646b50cf01..09484692fab08 100644 --- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr @@ -1,53 +1,53 @@ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:9:9 + --> $DIR/match-byte-array-patterns.rs:8:9 | LL | &[0x41, 0x41, 0x41, 0x41] => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/match-byte-array-patterns.rs:2:9 + --> $DIR/match-byte-array-patterns.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:15:9 + --> $DIR/match-byte-array-patterns.rs:14:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:21:9 + --> $DIR/match-byte-array-patterns.rs:20:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:27:9 + --> $DIR/match-byte-array-patterns.rs:26:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:35:9 + --> $DIR/match-byte-array-patterns.rs:34:9 | LL | &[0x41, 0x41, 0x41, 0x41] => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:41:9 + --> $DIR/match-byte-array-patterns.rs:40:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:47:9 + --> $DIR/match-byte-array-patterns.rs:46:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:53:9 + --> $DIR/match-byte-array-patterns.rs:52:9 | LL | b"AAAA" => {}, | ^^^^^^^ diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.rs b/src/test/ui/pattern/usefulness/match-slice-patterns.rs index af7fd53a1f1e9..92d74b8c229d6 100644 --- a/src/test/ui/pattern/usefulness/match-slice-patterns.rs +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn check(list: &[Option<()>]) { match list { //~^ ERROR `&[_, Some(_), .., None, _]` not covered diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr index 72ae5d5fe3b33..977a112808190 100644 --- a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered - --> $DIR/match-slice-patterns.rs:4:11 + --> $DIR/match-slice-patterns.rs:2:11 | LL | match list { | ^^^^ pattern `&[_, Some(_), .., None, _]` not covered diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs index 78810525bad0f..3342389be6e4c 100644 --- a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr index 415c24ae77ef5..e9a751074c2e1 100644 --- a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr @@ -1,23 +1,23 @@ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:9:9 + --> $DIR/match-vec-unreachable.rs:8:9 | LL | [(1, 2), (2, 3), b] => (), | ^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/match-vec-unreachable.rs:2:9 + --> $DIR/match-vec-unreachable.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:19:9 + --> $DIR/match-vec-unreachable.rs:18:9 | LL | [_, _, _, _, _] => { } | ^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:27:9 + --> $DIR/match-vec-unreachable.rs:26:9 | LL | ['a', 'b', 'c'] => {} | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs index 9423a2891a620..d198144790be1 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - enum T { A(U), B } enum U { C, D } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr index 67c818e19cbda..72b4b522198e0 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered - --> $DIR/non-exhaustive-match-nested.rs:7:11 + --> $DIR/non-exhaustive-match-nested.rs:5:11 | LL | match (l1, l2) { | ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered @@ -7,7 +7,7 @@ LL | match (l1, l2) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `A(C)` not covered - --> $DIR/non-exhaustive-match-nested.rs:17:11 + --> $DIR/non-exhaustive-match-nested.rs:15:11 | LL | enum T { A(U), B } | ------------------ diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs index bfca5352353a7..9947989dc1211 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![allow(illegal_floating_point_literal_pattern)] enum T { A, B } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index 577867e4e7122..a06ad5788515c 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `A` not covered - --> $DIR/non-exhaustive-match.rs:8:11 + --> $DIR/non-exhaustive-match.rs:7:11 | LL | enum T { A, B } | --------------- @@ -13,7 +13,7 @@ LL | match x { T::B => { } } = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `false` not covered - --> $DIR/non-exhaustive-match.rs:9:11 + --> $DIR/non-exhaustive-match.rs:8:11 | LL | match true { | ^^^^ pattern `false` not covered @@ -21,7 +21,7 @@ LL | match true { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/non-exhaustive-match.rs:12:11 + --> $DIR/non-exhaustive-match.rs:11:11 | LL | match Some(10) { | ^^^^^^^^ pattern `Some(_)` not covered @@ -29,7 +29,7 @@ LL | match Some(10) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered - --> $DIR/non-exhaustive-match.rs:15:11 + --> $DIR/non-exhaustive-match.rs:14:11 | LL | match (2, 3, 4) { | ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered @@ -37,7 +37,7 @@ LL | match (2, 3, 4) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(A, A)` not covered - --> $DIR/non-exhaustive-match.rs:19:11 + --> $DIR/non-exhaustive-match.rs:18:11 | LL | match (T::A, T::A) { | ^^^^^^^^^^^^ pattern `(A, A)` not covered @@ -45,7 +45,7 @@ LL | match (T::A, T::A) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `B` not covered - --> $DIR/non-exhaustive-match.rs:23:11 + --> $DIR/non-exhaustive-match.rs:22:11 | LL | enum T { A, B } | --------------- @@ -59,7 +59,7 @@ LL | match T::A { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/non-exhaustive-match.rs:34:11 + --> $DIR/non-exhaustive-match.rs:33:11 | LL | match *vec { | ^^^^ pattern `[]` not covered @@ -67,7 +67,7 @@ LL | match *vec { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered - --> $DIR/non-exhaustive-match.rs:47:11 + --> $DIR/non-exhaustive-match.rs:46:11 | LL | match *vec { | ^^^^ pattern `[_, _, _, _, ..]` not covered diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs index 4ca1cbcebccf5..abb4ea8daf57b 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - struct Foo { first: bool, second: Option<[usize; 4]> diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr index a0b497dd4c0ba..2a9fa07d22fe7 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:9:11 + --> $DIR/non-exhaustive-pattern-witness.rs:7:11 | LL | / struct Foo { LL | | first: bool, @@ -13,7 +13,7 @@ LL | match (Foo { first: true, second: None }) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Red` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:25:11 + --> $DIR/non-exhaustive-pattern-witness.rs:23:11 | LL | / enum Color { LL | | Red, @@ -29,7 +29,7 @@ LL | match Color::Red { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:37:11 + --> $DIR/non-exhaustive-pattern-witness.rs:35:11 | LL | / enum Direction { LL | | North, East, South, West @@ -46,7 +46,7 @@ LL | match Direction::North { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered - --> $DIR/non-exhaustive-pattern-witness.rs:48:11 + --> $DIR/non-exhaustive-pattern-witness.rs:46:11 | LL | / enum ExcessiveEnum { LL | | First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth @@ -59,7 +59,7 @@ LL | match ExcessiveEnum::First { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:56:11 + --> $DIR/non-exhaustive-pattern-witness.rs:54:11 | LL | / enum Color { LL | | Red, @@ -75,7 +75,7 @@ LL | match Color::Red { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:72:11 + --> $DIR/non-exhaustive-pattern-witness.rs:70:11 | LL | match *x { | ^^ pattern `[Second(true), Second(false)]` not covered @@ -83,7 +83,7 @@ LL | match *x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((), false)` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:85:11 + --> $DIR/non-exhaustive-pattern-witness.rs:83:11 | LL | match ((), false) { | ^^^^^^^^^^^ pattern `((), false)` not covered diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs index 41ba2cc4501c0..52d1320dad153 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { let s: &[bool] = &[true; 0]; let s1: &[bool; 1] = &[false; 1]; diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr index 8cb342f33dfa0..b3701efef3de2 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr +++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[false, _]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:10:11 + --> $DIR/slice-patterns-exhaustiveness.rs:8:11 | LL | match s2 { | ^^ pattern `&[false, _]` not covered @@ -7,7 +7,7 @@ LL | match s2 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:14:11 + --> $DIR/slice-patterns-exhaustiveness.rs:12:11 | LL | match s3 { | ^^ pattern `&[false, ..]` not covered @@ -15,7 +15,7 @@ LL | match s3 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:18:11 + --> $DIR/slice-patterns-exhaustiveness.rs:16:11 | LL | match s10 { | ^^^ pattern `&[false, ..]` not covered @@ -23,7 +23,7 @@ LL | match s10 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:27:11 + --> $DIR/slice-patterns-exhaustiveness.rs:25:11 | LL | match s2 { | ^^ pattern `&[false, true]` not covered @@ -31,7 +31,7 @@ LL | match s2 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:32:11 + --> $DIR/slice-patterns-exhaustiveness.rs:30:11 | LL | match s3 { | ^^ pattern `&[false, .., true]` not covered @@ -39,7 +39,7 @@ LL | match s3 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:37:11 + --> $DIR/slice-patterns-exhaustiveness.rs:35:11 | LL | match s { | ^ pattern `&[false, .., true]` not covered @@ -47,7 +47,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:44:11 + --> $DIR/slice-patterns-exhaustiveness.rs:42:11 | LL | match s { | ^ pattern `&[_, ..]` not covered @@ -55,7 +55,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:48:11 + --> $DIR/slice-patterns-exhaustiveness.rs:46:11 | LL | match s { | ^ pattern `&[_, _, ..]` not covered @@ -63,7 +63,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:53:11 + --> $DIR/slice-patterns-exhaustiveness.rs:51:11 | LL | match s { | ^ pattern `&[false, ..]` not covered @@ -71,7 +71,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:58:11 + --> $DIR/slice-patterns-exhaustiveness.rs:56:11 | LL | match s { | ^ pattern `&[false, _, ..]` not covered @@ -79,7 +79,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:64:11 + --> $DIR/slice-patterns-exhaustiveness.rs:62:11 | LL | match s { | ^ pattern `&[_, .., false]` not covered @@ -87,7 +87,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:71:11 + --> $DIR/slice-patterns-exhaustiveness.rs:69:11 | LL | match s { | ^ pattern `&[_, _, .., true]` not covered @@ -95,7 +95,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:78:11 + --> $DIR/slice-patterns-exhaustiveness.rs:76:11 | LL | match s { | ^ pattern `&[true, _, .., _]` not covered @@ -103,7 +103,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:87:11 + --> $DIR/slice-patterns-exhaustiveness.rs:85:11 | LL | match s { | ^ pattern `&[..]` not covered @@ -111,7 +111,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:91:11 + --> $DIR/slice-patterns-exhaustiveness.rs:89:11 | LL | match s { | ^ pattern `&[true]` not covered @@ -119,7 +119,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:99:11 + --> $DIR/slice-patterns-exhaustiveness.rs:97:11 | LL | match s1 { | ^^ pattern `&[false]` not covered diff --git a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs index 3b716bae77209..cbf64e2c53d02 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn main() { let s: &[bool] = &[true; 0]; diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs index cd229a0fcbee4..7c747b5e0b9d3 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr index 333ce170283ea..e24d10281170d 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr +++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr @@ -1,41 +1,41 @@ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:9:9 + --> $DIR/slice-patterns-reachability.rs:8:9 | LL | [true, ..] => {} | ^^^^^^^^^^ | note: lint level defined here - --> $DIR/slice-patterns-reachability.rs:2:9 + --> $DIR/slice-patterns-reachability.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:10:9 + --> $DIR/slice-patterns-reachability.rs:9:9 | LL | [true] => {} | ^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:15:9 + --> $DIR/slice-patterns-reachability.rs:14:9 | LL | [.., true] => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:16:9 + --> $DIR/slice-patterns-reachability.rs:15:9 | LL | [true] => {} | ^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:21:9 + --> $DIR/slice-patterns-reachability.rs:20:9 | LL | [false, .., true] => {} | ^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:22:9 + --> $DIR/slice-patterns-reachability.rs:21:9 | LL | [false, true] => {} | ^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index 1484b8c4a1f13..363a0e3e649d9 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - pub fn main() { let sl: &[u8] = b"foo"; diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index f1e91a05f082f..c234fdf46ed2d 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/slice.rs:6:11 + --> $DIR/slice.rs:4:11 | LL | match sl { | ^^ pattern `&[]` not covered diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs index 38b0941aad0a6..33229a205f4d8 100644 --- a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn slice_pat() { let sl: &[u8] = b"foo"; diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs index 929c35a9e1122..97006ae50a0bf 100644 --- a/src/test/ui/trailing-comma.rs +++ b/src/test/ui/trailing-comma.rs @@ -1,8 +1,6 @@ // run-pass // pretty-expanded FIXME #23616 -#![feature(slice_patterns)] - fn f(_: T,) {} struct Foo(T); diff --git a/src/test/ui/uninhabited/uninhabited-patterns.rs b/src/test/ui/uninhabited/uninhabited-patterns.rs index 1bf01184a08e7..58c726d2185c4 100644 --- a/src/test/ui/uninhabited/uninhabited-patterns.rs +++ b/src/test/ui/uninhabited/uninhabited-patterns.rs @@ -2,7 +2,7 @@ #![feature(box_syntax)] #![feature(never_type)] #![feature(exhaustive_patterns)] -#![feature(slice_patterns)] + #![deny(unreachable_patterns)] mod foo { From e3c2f8fc57e718f4ba1d7f52405eb2c1cb434559 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:37:14 +0100 Subject: [PATCH 0471/1253] slice_patterns: organize some tests --- .../slice-pat-type-mismatches.rs} | 0 .../slice-pat-type-mismatches.stderr} | 10 +++++----- .../subslice-only-once-semantic-restriction.rs} | 0 .../subslice-only-once-semantic-restriction.stderr} | 6 +++--- .../issue-53820-slice-pattern-large-array.rs | 2 +- ...issue-65413-constants-and-slices-exhaustiveness.rs} | 0 6 files changed, 9 insertions(+), 9 deletions(-) rename src/test/ui/{match/match-vec-mismatch.rs => array-slice-vec/slice-pat-type-mismatches.rs} (100%) rename src/test/ui/{match/match-vec-mismatch.stderr => array-slice-vec/slice-pat-type-mismatches.stderr} (81%) rename src/test/ui/{parser/match-vec-invalid.rs => array-slice-vec/subslice-only-once-semantic-restriction.rs} (100%) rename src/test/ui/{parser/match-vec-invalid.stderr => array-slice-vec/subslice-only-once-semantic-restriction.stderr} (80%) rename src/test/ui/pattern/{ => usefulness}/issue-53820-slice-pattern-large-array.rs (65%) rename src/test/ui/pattern/usefulness/{65413-constants-and-slices-exhaustiveness.rs => issue-65413-constants-and-slices-exhaustiveness.rs} (100%) diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs similarity index 100% rename from src/test/ui/match/match-vec-mismatch.rs rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr similarity index 81% rename from src/test/ui/match/match-vec-mismatch.stderr rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr index 4b0e429e51ca5..c4548142c13ef 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr @@ -1,29 +1,29 @@ error[E0425]: cannot find value `does_not_exist` in this scope - --> $DIR/match-vec-mismatch.rs:26:11 + --> $DIR/slice-pat-type-mismatches.rs:26:11 | LL | match does_not_exist { | ^^^^^^^^^^^^^^ not found in this scope error[E0529]: expected an array or slice, found `std::string::String` - --> $DIR/match-vec-mismatch.rs:3:9 + --> $DIR/slice-pat-type-mismatches.rs:3:9 | LL | ['f', 'o', ..] => {} | ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String` error[E0527]: pattern requires 1 element but array has 3 - --> $DIR/match-vec-mismatch.rs:18:9 + --> $DIR/slice-pat-type-mismatches.rs:18:9 | LL | [0] => {}, | ^^^ expected 3 elements error[E0528]: pattern requires at least 4 elements but array has 3 - --> $DIR/match-vec-mismatch.rs:23:9 + --> $DIR/slice-pat-type-mismatches.rs:23:9 | LL | [0, 1, 2, 3, x @ ..] => {} | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed - --> $DIR/match-vec-mismatch.rs:34:9 + --> $DIR/slice-pat-type-mismatches.rs:34:9 | LL | [] => {} | ^^ cannot infer type diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs similarity index 100% rename from src/test/ui/parser/match-vec-invalid.rs rename to src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr similarity index 80% rename from src/test/ui/parser/match-vec-invalid.stderr rename to src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr index 1dc11c31905c4..4d6078788b228 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr @@ -1,11 +1,11 @@ error[E0416]: identifier `tail` is bound more than once in the same pattern - --> $DIR/match-vec-invalid.rs:4:24 + --> $DIR/subslice-only-once-semantic-restriction.rs:4:24 | LL | [1, tail @ .., tail @ ..] => {}, | ^^^^ used in a pattern more than once error: `..` can only be used once per slice pattern - --> $DIR/match-vec-invalid.rs:4:31 + --> $DIR/subslice-only-once-semantic-restriction.rs:4:31 | LL | [1, tail @ .., tail @ ..] => {}, | -- ^^ can only be used once per slice pattern @@ -13,7 +13,7 @@ LL | [1, tail @ .., tail @ ..] => {}, | previously used here error[E0308]: mismatched types - --> $DIR/match-vec-invalid.rs:11:30 + --> $DIR/subslice-only-once-semantic-restriction.rs:11:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs similarity index 65% rename from src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs rename to src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs index 1249329206112..5b0482de2200e 100644 --- a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs +++ b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs @@ -1,6 +1,6 @@ // check-pass -// This used to cause a stack overflow in the compiler. +// This used to cause a stack overflow during exhaustiveness checking in the compiler. fn main() { const LARGE_SIZE: usize = 1024 * 1024; diff --git a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs b/src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs similarity index 100% rename from src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs rename to src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs From 120e98c3c7d28b1667576d0fa32fa94751968699 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:53:22 +0100 Subject: [PATCH 0472/1253] slice_patterns: remove from unstable book --- .../src/language-features/slice-patterns.md | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/slice-patterns.md diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md deleted file mode 100644 index cdb74495884a8..0000000000000 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ /dev/null @@ -1,32 +0,0 @@ -# `slice_patterns` - -The tracking issue for this feature is: [#62254] - -[#62254]: https://github.com/rust-lang/rust/issues/62254 - ------------------------- - -The `slice_patterns` feature gate lets you use `..` to indicate any number of -elements inside a pattern matching a slice. This wildcard can only be used once -for a given array. If there's an pattern before the `..`, the subslice will be -matched against that pattern. For example: - -```rust -#![feature(slice_patterns)] - -fn is_symmetric(list: &[u32]) -> bool { - match list { - &[] | &[_] => true, - &[x, ref inside @ .., y] if x == y => is_symmetric(inside), - &[..] => false, - } -} - -fn main() { - let sym = &[0, 1, 4, 2, 4, 1, 0]; - assert!(is_symmetric(sym)); - - let not_sym = &[0, 1, 7, 2, 4, 1, 0]; - assert!(!is_symmetric(not_sym)); -} -``` From 57b6843100b247b6065b71e4485572dda4bfccc6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 22:18:34 +0100 Subject: [PATCH 0473/1253] slice_patterns: address review comments --- .../ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs | 1 - src/test/ui/ignore-all-the-things.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 1c9c052970f9a..4367596c6ea88 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -1,5 +1,4 @@ // run-pass -// compile-flags: -Z borrowck=mir fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs index ab90a69ce6f06..5980e1a857f26 100644 --- a/src/test/ui/ignore-all-the-things.rs +++ b/src/test/ui/ignore-all-the-things.rs @@ -1,5 +1,4 @@ // run-pass -// pretty-expanded FIXME #23616 #![allow(non_shorthand_field_patterns)] #![allow(dead_code)] From de6046fa0ff6e57afa50174c001d1668ee7f3cf6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 18 Jan 2020 21:53:53 +0100 Subject: [PATCH 0474/1253] remove rustc_error_codes deps except in rustc_driver --- Cargo.lock | 17 ----------------- src/librustc/Cargo.toml | 1 - src/librustc/hir/check_attr.rs | 1 - src/librustc/infer/error_reporting/mod.rs | 1 - .../infer/error_reporting/need_type_info.rs | 2 -- .../nice_region_error/different_lifetimes.rs | 1 - .../nice_region_error/named_anon_conflict.rs | 2 -- src/librustc/infer/error_reporting/note.rs | 2 -- src/librustc/infer/opaque_types/mod.rs | 2 -- src/librustc/middle/lang_items.rs | 2 -- src/librustc/middle/weak_lang_items.rs | 2 -- src/librustc/mir/interpret/error.rs | 2 -- src/librustc/traits/error_reporting/mod.rs | 2 -- .../traits/error_reporting/suggestions.rs | 2 -- src/librustc/traits/on_unimplemented.rs | 2 -- src/librustc/traits/query/dropck_outlives.rs | 2 -- src/librustc/traits/specialize/mod.rs | 2 -- src/librustc/ty/query/plumbing.rs | 2 -- src/librustc_ast_lowering/Cargo.toml | 1 - src/librustc_ast_lowering/expr.rs | 1 - src/librustc_ast_lowering/item.rs | 1 - src/librustc_ast_lowering/lib.rs | 1 - src/librustc_ast_lowering/path.rs | 1 - src/librustc_ast_passes/Cargo.toml | 1 - src/librustc_ast_passes/ast_validation.rs | 2 -- src/librustc_ast_passes/feature_gate.rs | 1 - src/librustc_builtin_macros/Cargo.toml | 1 - src/librustc_builtin_macros/asm.rs | 2 -- src/librustc_builtin_macros/deriving/default.rs | 2 -- src/librustc_codegen_ssa/Cargo.toml | 1 - src/librustc_codegen_ssa/common.rs | 2 -- src/librustc_codegen_ssa/mir/statement.rs | 2 -- src/librustc_error_codes/lib.rs | 10 +--------- src/librustc_errors/diagnostic_builder.rs | 5 +---- src/librustc_lint/Cargo.toml | 1 - src/librustc_lint/context.rs | 1 - src/librustc_lint/levels.rs | 1 - src/librustc_metadata/Cargo.toml | 1 - src/librustc_metadata/creader.rs | 1 - src/librustc_metadata/locator.rs | 2 -- src/librustc_metadata/native_libs.rs | 1 - src/librustc_mir/Cargo.toml | 1 - src/librustc_mir/borrow_check/type_check/mod.rs | 1 - src/librustc_mir/transform/check_consts/ops.rs | 2 -- .../transform/check_consts/validation.rs | 1 - src/librustc_mir/transform/check_unsafety.rs | 2 -- src/librustc_mir/util/borrowck_errors.rs | 1 - src/librustc_mir_build/Cargo.toml | 1 - .../hair/pattern/check_match.rs | 1 - src/librustc_mir_build/hair/pattern/mod.rs | 2 -- src/librustc_parse/Cargo.toml | 1 - src/librustc_parse/config.rs | 1 - src/librustc_parse/parser/diagnostics.rs | 1 - src/librustc_parse/parser/item.rs | 1 - src/librustc_parse/parser/mod.rs | 2 -- src/librustc_parse/parser/pat.rs | 1 - src/librustc_parse/parser/ty.rs | 1 - src/librustc_passes/Cargo.toml | 1 - src/librustc_passes/check_const.rs | 1 - src/librustc_passes/entry.rs | 2 -- src/librustc_passes/intrinsicck.rs | 2 -- src/librustc_passes/lib_features.rs | 2 -- src/librustc_passes/loops.rs | 5 +---- src/librustc_passes/stability.rs | 2 -- src/librustc_plugin_impl/Cargo.toml | 1 - src/librustc_plugin_impl/load.rs | 1 - src/librustc_privacy/Cargo.toml | 1 - src/librustc_privacy/lib.rs | 2 -- src/librustc_resolve/Cargo.toml | 1 - src/librustc_resolve/build_reduced_graph.rs | 1 - src/librustc_resolve/diagnostics.rs | 2 -- src/librustc_resolve/imports.rs | 2 -- src/librustc_resolve/late.rs | 2 -- src/librustc_resolve/late/diagnostics.rs | 1 - src/librustc_resolve/lib.rs | 2 -- src/librustc_resolve/lifetimes.rs | 2 -- src/librustc_session/Cargo.toml | 1 - src/librustc_session/parse.rs | 1 - src/librustc_typeck/Cargo.toml | 1 - src/librustc_typeck/astconv.rs | 1 - src/librustc_typeck/check/autoderef.rs | 2 -- src/librustc_typeck/check/callee.rs | 1 - src/librustc_typeck/check/cast.rs | 2 -- src/librustc_typeck/check/coercion.rs | 1 - src/librustc_typeck/check/compare_method.rs | 2 -- src/librustc_typeck/check/dropck.rs | 2 -- src/librustc_typeck/check/expr.rs | 2 -- src/librustc_typeck/check/intrinsic.rs | 1 - src/librustc_typeck/check/method/probe.rs | 2 -- src/librustc_typeck/check/method/suggest.rs | 2 -- src/librustc_typeck/check/mod.rs | 2 -- src/librustc_typeck/check/op.rs | 2 -- src/librustc_typeck/check/pat.rs | 2 -- src/librustc_typeck/check/wfcheck.rs | 2 -- src/librustc_typeck/coherence/builtin.rs | 1 - src/librustc_typeck/coherence/inherent_impls.rs | 2 -- .../coherence/inherent_impls_overlap.rs | 2 -- src/librustc_typeck/coherence/mod.rs | 1 - src/librustc_typeck/coherence/orphan.rs | 2 -- src/librustc_typeck/coherence/unsafety.rs | 2 -- src/librustc_typeck/collect.rs | 2 -- src/librustc_typeck/impl_wf_check.rs | 2 -- src/librustc_typeck/lib.rs | 2 -- src/librustc_typeck/outlives/test.rs | 2 -- src/librustc_typeck/structured_errors.rs | 2 -- src/librustc_typeck/variance/test.rs | 2 -- src/librustdoc/lib.rs | 1 - src/libsyntax/Cargo.toml | 1 - src/libsyntax/attr/builtin.rs | 2 -- 109 files changed, 3 insertions(+), 194 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f33d7ff12febf..48bc269ebb654 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3092,7 +3092,6 @@ dependencies = [ "rustc-rayon-core", "rustc_apfloat", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_hir", @@ -3358,7 +3357,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_index", @@ -3375,7 +3373,6 @@ version = "0.0.0" dependencies = [ "log", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_parse", @@ -3391,7 +3388,6 @@ dependencies = [ "fmt_macros", "log", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_expand", "rustc_feature", @@ -3445,7 +3441,6 @@ dependencies = [ "rustc_apfloat", "rustc_codegen_utils", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_fs_util", "rustc_hir", @@ -3675,7 +3670,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_hir", @@ -3716,7 +3710,6 @@ dependencies = [ "memmap", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_expand", "rustc_hir", @@ -3744,7 +3737,6 @@ dependencies = [ "rustc", "rustc_apfloat", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_index", @@ -3767,7 +3759,6 @@ dependencies = [ "rustc", "rustc_apfloat", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_index", @@ -3786,7 +3777,6 @@ dependencies = [ "bitflags", "log", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_lexer", @@ -3804,7 +3794,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_hir", @@ -3820,7 +3809,6 @@ name = "rustc_plugin_impl" version = "0.0.0" dependencies = [ "rustc", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_lint", @@ -3836,7 +3824,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_span", @@ -3854,7 +3841,6 @@ dependencies = [ "rustc", "rustc_ast_lowering", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_expand", "rustc_feature", @@ -3890,7 +3876,6 @@ dependencies = [ "log", "num_cpus", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_fs_util", @@ -3973,7 +3958,6 @@ dependencies = [ "log", "rustc", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_index", @@ -4493,7 +4477,6 @@ version = "0.0.0" dependencies = [ "log", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_feature", "rustc_index", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 323ce3b6cbb6d..b65635be54a3f 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -37,5 +37,4 @@ byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" -rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 5a4d7ceea2734..86eab3d92d366 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -8,7 +8,6 @@ use crate::hir::map::Map; use crate::ty::query::Providers; use crate::ty::TyCtxt; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a2009461fa568..77182b97fd450 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -65,7 +65,6 @@ use crate::ty::{ Region, Ty, TyCtxt, TypeFoldable, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_error_codes::*; use rustc_errors::{pluralize, struct_span_err}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_hir as hir; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 70f7987faf4cc..9947dea234096 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -13,8 +13,6 @@ use rustc_span::symbol::kw; use rustc_span::Span; use std::borrow::Cow; -use rustc_error_codes::*; - struct FindLocalByTypeVisitor<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, target_ty: Ty<'tcx>, diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index d6e50209f72dd..8f4c643992001 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -5,7 +5,6 @@ use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::util::common::ErrorReported; -use rustc_error_codes::*; use rustc_errors::struct_span_err; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 2344d408a43a5..df37f53606b37 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -5,8 +5,6 @@ use crate::ty; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::{FunctionRetTy, TyKind}; -use rustc_error_codes::*; - impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// When given a `ConcreteFailure` for a function with parameters containing a named region and /// an anonymous region, emit an descriptive diagnostic error. diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 6303104e39dd3..11dda71b8cb89 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -5,8 +5,6 @@ use crate::ty::error::TypeError; use crate::ty::{self, Region}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; -use rustc_error_codes::*; - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub(super) fn note_region_origin( &self, diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index ee214bea7b8fc..fe3a5d149f676 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -15,8 +15,6 @@ use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_hir::Node; use rustc_span::Span; -use rustc_error_codes::*; - pub type OpaqueTypeMap<'tcx> = DefIdMap>; /// Information about the opaque types whose values we diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 643359f098b4d..27b769742a9fc 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -24,8 +24,6 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast; -use rustc_error_codes::*; - // The actual lang items defined come at the end of this file in one handy table. // So you probably just want to nip down to the end. macro_rules! language_item_table { diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index fdffd1251ce8f..5571f8f2313d5 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -15,8 +15,6 @@ use rustc_span::Span; use rustc_target::spec::PanicStrategy; use syntax::ast; -use rustc_error_codes::*; - macro_rules! weak_lang_items { ($($name:ident, $item:ident, $sym:ident;)*) => ( diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 42d896af8014d..349dbd74ad1c9 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -16,8 +16,6 @@ use rustc_span::{Pos, Span}; use rustc_target::spec::abi::Abi; use std::{any::Any, env, fmt}; -use rustc_error_codes::*; - #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)] pub enum ErrorHandled { /// Already reported a lint or an error for this evaluation. diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index db3173989ac60..646cb80bffd94 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -30,8 +30,6 @@ use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; use syntax::ast; -use rustc_error_codes::*; - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_fulfillment_errors( &self, diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c09fd3079731c..c18e17581ceb6 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -20,8 +20,6 @@ use rustc_span::symbol::{kw, sym}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use std::fmt; -use rustc_error_codes::*; - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { crate fn suggest_restricting_param_bound( &self, diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 1afe153bb1361..669ec5ccc9b98 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -11,8 +11,6 @@ use rustc_span::Span; use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; -use rustc_error_codes::*; - #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString(Symbol); diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 34866b684de01..2e5ef5adcd30e 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -6,8 +6,6 @@ use crate::ty::{self, Ty, TyCtxt}; use rustc_span::source_map::Span; use std::iter::FromIterator; -use rustc_error_codes::*; - impl<'cx, 'tcx> At<'cx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set /// of "kinds" (types, regions) that must be outlive the execution diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index f5199dbdabb2f..e559ea391cde0 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -25,8 +25,6 @@ use rustc_span::DUMMY_SP; use super::util::impl_trait_ref_and_oblig; use super::{FulfillmentContext, SelectionContext}; -use rustc_error_codes::*; - /// Information pertinent to an overlapping impl error. #[derive(Debug)] pub struct OverlapError { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 84efbe21f10aa..117a38c655eaa 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -25,8 +25,6 @@ use std::hash::{Hash, Hasher}; use std::mem; use std::ptr; -use rustc_error_codes::*; - pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> { pub(super) results: FxHashMap>, pub(super) active: FxHashMap>, diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml index 408e9a75d93dd..4b786d6245fc4 100644 --- a/src/librustc_ast_lowering/Cargo.toml +++ b/src/librustc_ast_lowering/Cargo.toml @@ -17,7 +17,6 @@ rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } rustc_span = { path = "../librustc_span" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_errors = { path = "../librustc_errors" } rustc_session = { path = "../librustc_session" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 2866a1624de5b..a24bb52150a72 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -2,7 +2,6 @@ use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericAr use rustc::bug; use rustc_data_structures::thin_vec::ThinVec; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 6da2d457f3c3b..bcc40b0c9c9c9 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -3,7 +3,6 @@ use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor}; use rustc::arena::Arena; use rustc::bug; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 76a0889c376a2..2cd4a6eb7e21b 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -41,7 +41,6 @@ use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 65347d379bd6a..e5f7df6dbf9e4 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -3,7 +3,6 @@ use super::{GenericArgsCtor, ParenthesizedGenericArgs}; use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS; use rustc::span_bug; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index 2d45e28044495..25b1acebd2a08 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -12,7 +12,6 @@ path = "lib.rs" log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_feature = { path = "../librustc_feature" } rustc_parse = { path = "../librustc_parse" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 23701459025ae..bc02406aa2158 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -23,8 +23,6 @@ use syntax::print::pprust; use syntax::visit::{self, Visitor}; use syntax::walk_list; -use rustc_error_codes::*; - /// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`). #[derive(Clone, Copy)] enum BoundContext { diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 71cd66ddef409..d3f7eaa1fe3b8 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -1,4 +1,3 @@ -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Handler}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Features, GateIssue, UnstableFeatures}; diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index f291eaf93580b..3ce7f5d770ed1 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -22,4 +22,3 @@ smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } rustc_expand = { path = "../librustc_expand" } rustc_span = { path = "../librustc_span" } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs index a6b45e0567c72..4723544316faf 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/src/librustc_builtin_macros/asm.rs @@ -12,8 +12,6 @@ use syntax::ptr::P; use syntax::token::{self, Token}; use syntax::tokenstream::{self, TokenStream}; -use rustc_error_codes::*; - enum State { Asm, Outputs, diff --git a/src/librustc_builtin_macros/deriving/default.rs b/src/librustc_builtin_macros/deriving/default.rs index 72c41ad9745c1..b4f059e94c15e 100644 --- a/src/librustc_builtin_macros/deriving/default.rs +++ b/src/librustc_builtin_macros/deriving/default.rs @@ -9,8 +9,6 @@ use rustc_span::Span; use syntax::ast::{Expr, MetaItem}; use syntax::ptr::P; -use rustc_error_codes::*; - pub fn expand_deriving_default( cx: &mut ExtCtxt<'_>, span: Span, diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index eb192b27405e9..9f8b4e72a9cbf 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -32,5 +32,4 @@ rustc_hir = { path = "../librustc_hir" } rustc_incremental = { path = "../librustc_incremental" } rustc_index = { path = "../librustc_index" } rustc_target = { path = "../librustc_target" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index e4531a77656a3..28b61e0b36d64 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -13,8 +13,6 @@ use rustc_hir::def_id::DefId; use crate::traits::BuilderMethods; use rustc_hir as hir; -use rustc_error_codes::*; - pub enum IntPredicate { IntEQ, IntNE, diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 574c06d9ceb41..8422c625d634e 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -7,8 +7,6 @@ use super::OperandValue; use crate::traits::BuilderMethods; use crate::traits::*; -use rustc_error_codes::*; - impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>) -> Bx { debug!("codegen_statement(statement={:?})", statement); diff --git a/src/librustc_error_codes/lib.rs b/src/librustc_error_codes/lib.rs index 14210fd69ad51..f051fdd11b807 100644 --- a/src/librustc_error_codes/lib.rs +++ b/src/librustc_error_codes/lib.rs @@ -6,16 +6,8 @@ macro_rules! register_diagnostics { pub static DIAGNOSTICS: &[(&str, &str)] = &[ $( (stringify!($ecode), $message), )* ]; - - $( - pub const $ecode: () = (); - )* - $( - pub const $code: () = (); - )* ) } mod error_codes; - -pub use error_codes::*; +pub use error_codes::DIAGNOSTICS; diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 73f66d5503740..3c217c1d64373 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -399,8 +399,5 @@ macro_rules! struct_span_err { #[macro_export] macro_rules! error_code { - ($code:ident) => {{ - let _ = $code; - $crate::DiagnosticId::Error(stringify!($code).to_owned()) - }}; + ($code:ident) => {{ $crate::DiagnosticId::Error(stringify!($code).to_owned()) }}; } diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index abf9f96e6475b..7e23e70577975 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -13,7 +13,6 @@ log = "0.4" unicode-security = "0.0.2" rustc = { path = "../librustc" } rustc_errors = { path = "../librustc_errors" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 42ec8787cb287..3b8cce5635d07 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -26,7 +26,6 @@ use rustc::ty::layout::{LayoutError, LayoutOf, TyLayout}; use rustc::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index bbc3e57f5dd01..d5bbdc53160f6 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -6,7 +6,6 @@ use rustc::lint::{LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 0a0bcb190bea7..6da584733aea0 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -26,7 +26,6 @@ syntax = { path = "../libsyntax" } rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } rustc_span = { path = "../librustc_span" } -rustc_error_codes = { path = "../librustc_error_codes" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 181f872154c51..351e72d4678f2 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,7 +12,6 @@ use rustc::session::{CrateDisambiguator, Session}; use rustc::ty::TyCtxt; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 4745ad02a3aa4..578216454f9dc 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -241,8 +241,6 @@ use rustc_data_structures::owning_ref::OwningRef; use log::{debug, info, warn}; -use rustc_error_codes::*; - #[derive(Clone)] struct CrateMismatch { path: PathBuf, diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 9426d5e26f5e5..bbf6973be51a7 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -3,7 +3,6 @@ use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashSet; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index f9b61b9e2c9d8..00881e3ea6f19 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -29,4 +29,3 @@ syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } rustc_apfloat = { path = "../librustc_apfloat" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 947bbef4379f5..a92abc98cf4c1 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -27,7 +27,6 @@ use rustc::ty::{ TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index edb4eb4d7c344..3263905eadb81 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -10,8 +10,6 @@ use rustc_span::{Span, Symbol}; use super::{ConstKind, Item}; -use rustc_error_codes::*; - /// An operation that is not *always* allowed in a const context. pub trait NonConstOp: std::fmt::Debug { /// Whether this operation can be evaluated by miri. diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 10a4b7d92b764..1d5fb33ee8e81 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -6,7 +6,6 @@ use rustc::mir::*; use rustc::traits::{self, TraitEngine}; use rustc::ty::cast::CastTy; use rustc::ty::{self, TyCtxt}; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir::{def_id::DefId, HirId}; use rustc_index::bit_set::BitSet; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 072cdf2ebba3a..4e943547f07f5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -18,8 +18,6 @@ use std::ops::Bound; use crate::const_eval::{is_const_fn, is_min_const_fn}; use crate::util; -use rustc_error_codes::*; - pub struct UnsafetyChecker<'a, 'tcx> { body: &'a Body<'tcx>, const_context: bool, diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index c275eecfb33b6..d8ee059f1a6b6 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -1,5 +1,4 @@ use rustc::ty::{self, Ty, TyCtxt}; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId}; use rustc_span::{MultiSpan, Span}; diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml index 79c7303275597..f0d1d4c6515ce 100644 --- a/src/librustc_mir_build/Cargo.toml +++ b/src/librustc_mir_build/Cargo.toml @@ -25,4 +25,3 @@ rustc_span = { path = "../librustc_span" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 84d57a89c983e..eac52da7ba4ae 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -9,7 +9,6 @@ use rustc::lint; use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; -use rustc_error_codes::*; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::*; diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 205e25f7f8f0c..2657050583071 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -28,8 +28,6 @@ use syntax::ast; use std::cmp::Ordering; use std::fmt; -use rustc_error_codes::*; - #[derive(Clone, Debug)] crate enum PatternError { AssocConstInPattern(Span), diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index aa159c55ff284..8071bc6312b36 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -16,7 +16,6 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } rustc_errors = { path = "../librustc_errors" } -rustc_error_codes = { path = "../librustc_error_codes" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index 8467acc759c2b..bf696faf2f3f4 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -10,7 +10,6 @@ use crate::{parse_in, validate_attr}; use rustc_data_structures::fx::FxHashMap; -use rustc_error_codes::*; use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 6a18c63017ed6..80bc5c158a64f 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,7 +1,6 @@ use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType}; use rustc_data_structures::fx::FxHashSet; -use rustc_error_codes::*; use rustc_errors::{pluralize, struct_span_err}; use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult}; use rustc_span::source_map::Spanned; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 1921a6c850689..5076aafe4ebd5 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -3,7 +3,6 @@ use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey}; use rustc_span::source_map::{self, respan, Span, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 1368230168e07..4a9016394d258 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -33,8 +33,6 @@ use std::borrow::Cow; use std::path::PathBuf; use std::{cmp, mem, slice}; -use rustc_error_codes::*; - bitflags::bitflags! { struct Restrictions: u8 { const STMT_EXPR = 1 << 0; diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 549acf67d3824..edb9044df9206 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -659,7 +659,6 @@ impl<'a> Parser<'a> { } pub(super) fn error_inclusive_range_with_no_end(&self, span: Span) { - use rustc_error_codes::E0586; struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end") .span_suggestion_short( span, diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 065a3b14428c7..d1875a6c940b1 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -3,7 +3,6 @@ use super::{Parser, PathStyle, PrevTokenKind, TokenType}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; -use rustc_error_codes::*; use rustc_errors::{pluralize, struct_span_err, Applicability, PResult}; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym}; diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 639d8639c4bb2..338808f6d4a0f 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -20,4 +20,3 @@ rustc_session = { path = "../librustc_session" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index 39ba2fbc63b43..faa85f68fab86 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -12,7 +12,6 @@ use rustc::session::config::nightly_options; use rustc::session::parse::feature_err; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs index 028d7c662758a..d36114fd3b5b5 100644 --- a/src/librustc_passes/entry.rs +++ b/src/librustc_passes/entry.rs @@ -12,8 +12,6 @@ use rustc_span::{Span, DUMMY_SP}; use syntax::attr; use syntax::entry::EntryPointType; -use rustc_error_codes::*; - struct EntryContext<'a, 'tcx> { session: &'a Session, diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs index 2c26707a51850..782199003c72a 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -11,8 +11,6 @@ use rustc_index::vec::Idx; use rustc_span::{sym, Span}; use rustc_target::spec::abi::Abi::RustIntrinsic; -use rustc_error_codes::*; - fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut ItemVisitor { tcx }.as_deep_visitor()); } diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs index 8ae7291289786..2e306a1b4f2a1 100644 --- a/src/librustc_passes/lib_features.rs +++ b/src/librustc_passes/lib_features.rs @@ -15,8 +15,6 @@ use rustc_span::symbol::Symbol; use rustc_span::{sym, Span}; use syntax::ast::{Attribute, MetaItem, MetaItemKind}; -use rustc_error_codes::*; - fn new_lib_features() -> LibFeatures { LibFeatures { stable: Default::default(), unstable: Default::default() } } diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 5ad5795c777d4..69d6b38005c4c 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -1,7 +1,5 @@ use Context::*; -use rustc::session::Session; - use rustc::hir::map::Map; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; @@ -10,10 +8,9 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{Destination, Movability, Node}; +use rustc_session::Session; use rustc_span::Span; -use rustc_error_codes::*; - #[derive(Clone, Copy, Debug, PartialEq)] enum Context { Normal, diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index b649f36f2fc58..320b433190e5e 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -26,8 +26,6 @@ use std::cmp::Ordering; use std::mem::replace; use std::num::NonZeroU32; -use rustc_error_codes::*; - #[derive(PartialEq)] enum AnnotationKind { // Annotation is required if not inherited from unstable parents diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml index 41e6c699c340e..2214838c84683 100644 --- a/src/librustc_plugin_impl/Cargo.toml +++ b/src/librustc_plugin_impl/Cargo.toml @@ -18,4 +18,3 @@ rustc_lint = { path = "../librustc_lint" } rustc_metadata = { path = "../librustc_metadata" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs index 65661ec24f07f..84549c0dd4554 100644 --- a/src/librustc_plugin_impl/load.rs +++ b/src/librustc_plugin_impl/load.rs @@ -3,7 +3,6 @@ use crate::Registry; use rustc::middle::cstore::MetadataLoader; use rustc::session::Session; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_metadata::locator; use rustc_span::symbol::sym; diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 795b6c107fe94..4f341b545156c 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -16,5 +16,4 @@ rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_error_codes = { path = "../librustc_error_codes" } log = "0.4" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 90a422a4dcf6c..634905450d4ed 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -27,8 +27,6 @@ use syntax::attr; use std::marker::PhantomData; use std::{cmp, fmt, mem}; -use rustc_error_codes::*; - //////////////////////////////////////////////////////////////////////////////// /// Generic infrastructure used to implement specific visitors below. //////////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index af37e7b5b76ac..c4cc6b09c736e 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -23,7 +23,6 @@ rustc_expand = { path = "../librustc_expand" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_metadata = { path = "../librustc_metadata" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 40a89ef067458..7ff076268ab82 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -21,7 +21,6 @@ use rustc::hir::exports::Export; use rustc::middle::cstore::CrateStore; use rustc::ty; use rustc_data_structures::sync::Lrc; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::SyntaxExtension; use rustc_expand::expand::AstFragment; diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a433ae8ed676a..3d4384cabe204 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -25,8 +25,6 @@ use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, Modu use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment}; -use rustc_error_codes::*; - type Res = def::Res; /// A vector of spans and replacements, a message and applicability. diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 9f459834175c1..55ce51e0ff057 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -29,8 +29,6 @@ use syntax::ast::{Ident, Name, NodeId}; use syntax::unwrap_or; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_error_codes::*; - use log::*; use std::cell::Cell; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 08cd9c4d1d53a..5e08ac8e2c38a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -31,8 +31,6 @@ use log::debug; use std::collections::BTreeSet; use std::mem::replace; -use rustc_error_codes::*; - mod diagnostics; type Res = def::Res; diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 151f3e834e5de..6a98c9e59a9ce 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -6,7 +6,6 @@ use crate::{PathResult, PathSource, Segment}; use rustc::session::config::nightly_options; use rustc_data_structures::fx::FxHashSet; -use rustc_error_codes::*; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 60a0049f5da37..5d132191f9208 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -61,8 +61,6 @@ use imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver, NameReso use late::{HasGenericParams, PathSource, Rib, RibKind::*}; use macros::{LegacyBinding, LegacyScope}; -use rustc_error_codes::*; - type Res = def::Res; mod build_reduced_graph; diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 5fae8f3318743..a2ca80cf5f30a 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -30,8 +30,6 @@ use syntax::walk_list; use log::debug; -use rustc_error_codes::*; - // This counts the no of times a lifetime is used #[derive(Clone, Copy, Debug)] pub enum LifetimeUseSet<'tcx> { diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml index 377ea141ed57c..47c23bc4dcf98 100644 --- a/src/librustc_session/Cargo.toml +++ b/src/librustc_session/Cargo.toml @@ -10,7 +10,6 @@ path = "lib.rs" [dependencies] log = "0.4" -rustc_error_codes = { path = "../librustc_error_codes" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index a98cf929095ea..72c68fcb244c9 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -6,7 +6,6 @@ use crate::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc, Once}; -use rustc_error_codes::E0658; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{error_code, Applicability, DiagnosticBuilder}; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 84e5f56d9c208..4b27d86dd02a7 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -22,4 +22,3 @@ smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } rustc_index = { path = "../librustc_index" } -rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 173bb29e964d1..047c14cfbcff7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -39,7 +39,6 @@ use std::iter; use std::slice; use rustc::mir::interpret::LitToConstInput; -use rustc_error_codes::*; #[derive(Debug)] pub struct PathSeg(pub DefId, pub usize); diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 8d6b74c3015c9..3ea5de9a8375d 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -13,8 +13,6 @@ use rustc_hir as hir; use rustc_span::Span; use syntax::ast::Ident; -use rustc_error_codes::*; - use std::iter; #[derive(Copy, Clone, Debug)] diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 58f407b890278..b33cc52b238e3 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -8,7 +8,6 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoB use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::{infer, traits}; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::Res; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index cbbfe2d627895..d254a84df72ce 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -49,8 +49,6 @@ use rustc_hir as hir; use rustc_span::Span; use syntax::ast; -use rustc_error_codes::*; - /// Reifies a cast check to be checked once we have full type information for /// a function context. pub struct CastCheck<'tcx> { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a32fbff7bfe2d..8c8e0642dffce 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -65,7 +65,6 @@ use rustc::ty::fold::TypeFoldable; use rustc::ty::relate::RelateResult; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TypeAndMut}; -use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index c35661ac649fc..414f80d84b672 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -15,8 +15,6 @@ use rustc_span::Span; use super::{potentially_plural_count, FnCtxt, Inherited}; -use rustc_error_codes::*; - /// Checks that a method from an impl conforms to the signature of /// the same method as declared in the trait. /// diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 88e7a265ebbcf..f4aa53a5a9389 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -14,8 +14,6 @@ use rustc_errors::struct_span_err; use rustc_span::Span; -use rustc_error_codes::*; - /// This function confirms that the `Drop` implementation identified by /// `drop_impl_did` is not any more specialized than the type it is /// attached to (Issue #8142). diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 35342de59a082..201a09fdc63fa 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -38,8 +38,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_error_codes::*; - use std::fmt::Display; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 0441514c83c9d..3572eda5c1399 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -6,7 +6,6 @@ use crate::require_same_types; use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::subst::Subst; use rustc::ty::{self, Ty, TyCtxt}; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_span::symbol::Symbol; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index b2542cc27a551..9d8f57119ddde 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -38,8 +38,6 @@ use std::ops::Deref; use syntax::ast; use syntax::util::lev_distance::{find_best_match_for_name, lev_distance}; -use rustc_error_codes::*; - use smallvec::{smallvec, SmallVec}; use self::CandidateKind::*; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index d6c0d9c77b495..88de2654cea54 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -21,8 +21,6 @@ use rustc_span::{source_map, FileName, Span}; use syntax::ast; use syntax::util::lev_distance; -use rustc_error_codes::*; - use std::cmp::Ordering; use super::probe::Mode; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4affdc4a9d64e..f7df630fb90b1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -133,8 +133,6 @@ use syntax::ast; use syntax::attr; use syntax::util::parser::ExprPrecedence; -use rustc_error_codes::*; - use std::cell::{Cell, Ref, RefCell, RefMut}; use std::cmp; use std::collections::hash_map::Entry; diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index edf9d19dea377..91e1731ac458b 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -11,8 +11,6 @@ use rustc_hir as hir; use rustc_span::Span; use syntax::ast::Ident; -use rustc_error_codes::*; - impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Checks a `a = b` pub fn check_binop_assign( diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 1478b35a25ddc..f9dee0e477f79 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -15,8 +15,6 @@ use rustc_span::Span; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_error_codes::*; - use std::cmp; use std::collections::hash_map::Entry::{Occupied, Vacant}; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 5e91e98a7dfa5..910e680de69dc 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -18,8 +18,6 @@ use syntax::ast; use rustc_hir as hir; use rustc_hir::itemlikevisit::ParItemLikeVisitor; -use rustc_error_codes::*; - /// Helper type of a temporary returned by `.for_item(...)`. /// This is necessary because we can't write the following bound: /// diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 516dc16d46bd8..79a006a898a89 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -12,7 +12,6 @@ use rustc::traits::{self, ObligationCause, TraitEngine}; use rustc::ty::adjustment::CoerceUnsizedInfo; use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty, TyCtxt}; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d313e32fc20e0..d4c89b7e03793 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -16,8 +16,6 @@ use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::Span; use syntax::ast; -use rustc_error_codes::*; - /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index a9228c7f6bb4c..d60c3cfba9a5b 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -6,8 +6,6 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_error_codes::*; - pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fd685e77b418c..5583e3418b2a8 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -8,7 +8,6 @@ use rustc::traits; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, TypeFoldable}; -use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::HirId; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 9ba8fa4247f26..80521666476e6 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -7,8 +7,6 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_error_codes::*; - pub fn check(tcx: TyCtxt<'_>) { let mut orphan = OrphanChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut orphan); diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 48b96886d3a71..a604421740363 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -7,8 +7,6 @@ use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::Unsafety; -use rustc_error_codes::*; - pub fn check(tcx: TyCtxt<'_>) { let mut unsafety = UnsafetyChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut unsafety); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a03b9f747372e..9eee31c3a5763 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -47,8 +47,6 @@ use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr}; -use rustc_error_codes::*; - struct OnlySelfBounds(bool); /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 9ee4e7c48190d..e9c18b59da982 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -20,8 +20,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use rustc_span::Span; -use rustc_error_codes::*; - /// Checks that all the type/lifetime parameters on an impl also /// appear in the trait ref or self type (or are constrained by a /// where-clause). These rules are needed to ensure that, given a diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b951883ac195a..de8e917d0b8c7 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -109,8 +109,6 @@ use rustc_hir::Node; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; -use rustc_error_codes::*; - use std::iter; use astconv::{AstConv, Bounds}; diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index 908429c8dc48a..980d58ad939d7 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -4,8 +4,6 @@ use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::symbol::sym; -use rustc_error_codes::*; - pub fn test_inferred_outlives(tcx: TyCtxt<'_>) { tcx.hir().krate().visit_all_item_likes(&mut OutlivesTest { tcx }); } diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs index 068814723f52d..99b7b2001a9e9 100644 --- a/src/librustc_typeck/structured_errors.rs +++ b/src/librustc_typeck/structured_errors.rs @@ -3,8 +3,6 @@ use rustc::ty::{Ty, TypeFoldable}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_span::Span; -use rustc_error_codes::*; - pub trait StructuredDiagnostic<'tcx> { fn session(&self) -> &Session; diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index 2f41bee1819cd..ee94b1015a1f4 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -4,8 +4,6 @@ use rustc_hir as hir; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::symbol::sym; -use rustc_error_codes::*; - pub fn test_variance(tcx: TyCtxt<'_>) { tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx }); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1da00e3a47b82..403c8d0160d8a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -23,7 +23,6 @@ extern crate getopts; extern crate rustc; extern crate rustc_data_structures; extern crate rustc_driver; -extern crate rustc_error_codes; extern crate rustc_errors; extern crate rustc_expand; extern crate rustc_feature; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 7d9f715e9feb8..2e647d2a1e081 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -21,5 +21,4 @@ rustc_index = { path = "../librustc_index" } rustc_lexer = { path = "../librustc_lexer" } rustc_macros = { path = "../librustc_macros" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_session = { path = "../librustc_session" } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 70f4f47621a34..6cfe4f2de1e96 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -12,8 +12,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; -use rustc_error_codes::*; - pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() } From e1f70f77bf7aae099453d54a1175d8453ce4f5cb Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 18 Jan 2020 18:44:05 -0500 Subject: [PATCH 0475/1253] [const-prop] Remove useless typedef It's confusing because it conflicts with ty::Const and just isn't generally useful. --- src/librustc_mir/transform/const_prop.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 3afc7290ca9c8..2fd59f3ee1944 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -288,8 +288,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { } } -type Const<'tcx> = OpTy<'tcx>; - /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'mir, 'tcx, ConstPropMachine>, @@ -387,7 +385,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn get_const(&self, local: Local) -> Option> { + fn get_const(&self, local: Local) -> Option> { if local == RETURN_PLACE { // Try to read the return place as an immediate so that if it is representable as a // scalar, we can handle it as such, but otherwise, just return the value as is. @@ -470,7 +468,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { &mut self, c: &Constant<'tcx>, source_info: SourceInfo, - ) -> Option> { + ) -> Option> { self.ecx.tcx.span = c.span; // FIXME we need to revisit this for #67176 @@ -510,12 +508,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { + fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { trace!("eval_place(place={:?})", place); self.use_ecx(source_info, |this| this.ecx.eval_place_to_op(place, None)) } - fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { + fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { Operand::Constant(ref c) => self.eval_constant(c, source_info), Operand::Move(ref place) | Operand::Copy(ref place) => { @@ -664,7 +662,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn replace_with_const( &mut self, rval: &mut Rvalue<'tcx>, - value: Const<'tcx>, + value: OpTy<'tcx>, source_info: SourceInfo, ) { trace!("attepting to replace {:?} with {:?}", rval, value); From a957f0d7ff2c6389ec94f921d9ba4e9fade26a72 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 18 Jan 2020 18:44:22 -0500 Subject: [PATCH 0476/1253] [const-prop] Run `x.py fmt` --- src/librustc_mir/transform/const_prop.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2fd59f3ee1944..bd398c6e5b449 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -464,11 +464,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { r } - fn eval_constant( - &mut self, - c: &Constant<'tcx>, - source_info: SourceInfo, - ) -> Option> { + fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Option> { self.ecx.tcx.span = c.span; // FIXME we need to revisit this for #67176 From 17f4cbc3032f7e81f0ec0c7e3b4cd0c3da30c916 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sat, 18 Jan 2020 23:51:06 +0000 Subject: [PATCH 0477/1253] rustdoc: Fix handling of compile errors when running `rustdoc --test` * Call `abort_if_errors` so all errors actually stop rustdoc. * Don't panic with "compiler aborted in rustdoc!", instead just exit to avoid the ugly panic message. * Use rlib as the crate type when searching for doctests matching what is used for doc generation so `#[no_std]` crates don't create "no global memory allocator" errors. --- src/librustdoc/test.rs | 10 +++++++--- src/test/rustdoc-ui/test-compile-fail1.rs | 8 ++++++++ src/test/rustdoc-ui/test-compile-fail1.stderr | 14 ++++++++++++++ src/test/rustdoc-ui/test-compile-fail2.rs | 3 +++ src/test/rustdoc-ui/test-compile-fail2.stderr | 8 ++++++++ src/test/rustdoc-ui/test-compile-fail3.rs | 3 +++ src/test/rustdoc-ui/test-compile-fail3.stderr | 8 ++++++++ src/test/rustdoc-ui/test-no_std.rs | 12 ++++++++++++ src/test/rustdoc-ui/test-no_std.stdout | 6 ++++++ 9 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc-ui/test-compile-fail1.rs create mode 100644 src/test/rustdoc-ui/test-compile-fail1.stderr create mode 100644 src/test/rustdoc-ui/test-compile-fail2.rs create mode 100644 src/test/rustdoc-ui/test-compile-fail2.stderr create mode 100644 src/test/rustdoc-ui/test-compile-fail3.rs create mode 100644 src/test/rustdoc-ui/test-compile-fail3.stderr create mode 100644 src/test/rustdoc-ui/test-no_std.rs create mode 100644 src/test/rustdoc-ui/test-no_std.stdout diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f899e722a5615..1048083c9227d 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -43,7 +43,7 @@ pub fn run(options: Options) -> i32 { let crate_types = if options.proc_macro_crate { vec![config::CrateType::ProcMacro] } else { - vec![config::CrateType::Dylib] + vec![config::CrateType::Rlib] }; let sessopts = config::Options { @@ -117,12 +117,16 @@ pub fn run(options: Options) -> i32 { intravisit::walk_crate(this, krate); }); }); + compiler.session().abort_if_errors(); let ret: Result<_, ErrorReported> = Ok(collector.tests); ret }) - }) - .expect("compiler aborted in rustdoc!"); + }); + let tests = match tests { + Ok(tests) => tests, + Err(ErrorReported) => return 1, + }; test_args.insert(0, "rustdoctest".to_string()); diff --git a/src/test/rustdoc-ui/test-compile-fail1.rs b/src/test/rustdoc-ui/test-compile-fail1.rs new file mode 100644 index 0000000000000..a05390238784d --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail1.rs @@ -0,0 +1,8 @@ +// compile-flags:--test + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} + +pub fn f() {} diff --git a/src/test/rustdoc-ui/test-compile-fail1.stderr b/src/test/rustdoc-ui/test-compile-fail1.stderr new file mode 100644 index 0000000000000..2b38ba9e973d1 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail1.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `f` is defined multiple times + --> $DIR/test-compile-fail1.rs:8:1 + | +6 | pub fn f() {} + | ---------- previous definition of the value `f` here +7 | +8 | pub fn f() {} + | ^^^^^^^^^^ `f` redefined here + | + = note: `f` must be defined only once in the value namespace of this module + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/rustdoc-ui/test-compile-fail2.rs b/src/test/rustdoc-ui/test-compile-fail2.rs new file mode 100644 index 0000000000000..651ded0a04793 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail2.rs @@ -0,0 +1,3 @@ +// compile-flags:--test + +fail diff --git a/src/test/rustdoc-ui/test-compile-fail2.stderr b/src/test/rustdoc-ui/test-compile-fail2.stderr new file mode 100644 index 0000000000000..cee5b63cf5097 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail2.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `::`, found `` + --> $DIR/test-compile-fail2.rs:3:1 + | +3 | fail + | ^^^^ expected one of `!` or `::` + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/test-compile-fail3.rs b/src/test/rustdoc-ui/test-compile-fail3.rs new file mode 100644 index 0000000000000..faa30ad836712 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail3.rs @@ -0,0 +1,3 @@ +// compile-flags:--test + +"fail diff --git a/src/test/rustdoc-ui/test-compile-fail3.stderr b/src/test/rustdoc-ui/test-compile-fail3.stderr new file mode 100644 index 0000000000000..7a2f1815ed8e5 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail3.stderr @@ -0,0 +1,8 @@ +error: unterminated double quote string + --> $DIR/test-compile-fail3.rs:3:1 + | +3 | "fail + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/test-no_std.rs b/src/test/rustdoc-ui/test-no_std.rs new file mode 100644 index 0000000000000..166a87382cb65 --- /dev/null +++ b/src/test/rustdoc-ui/test-no_std.rs @@ -0,0 +1,12 @@ +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// build-pass + +#![no_std] + +extern crate alloc; + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} diff --git a/src/test/rustdoc-ui/test-no_std.stdout b/src/test/rustdoc-ui/test-no_std.stdout new file mode 100644 index 0000000000000..9cdcac2a483ab --- /dev/null +++ b/src/test/rustdoc-ui/test-no_std.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/test-no_std.rs - f (line 9) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + From 42b6ed13be779499d118af721913a66bd3d946ea Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 19 Jan 2020 12:59:15 +0800 Subject: [PATCH 0478/1253] account temporary borrow by raw-ptr --- .../traits/error_reporting/suggestions.rs | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index bf6891214ace1..189412f60b904 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -13,6 +13,7 @@ use rustc_errors::{ }; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::def::DefKind; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; @@ -1366,14 +1367,40 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let Some(expr_id) = expr { let expr = hir.expect_expr(expr_id); - let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + debug!("target_ty evaluated from {:?}", expr); + let parent = hir.get_parent_node(expr_id); if let Some(hir::Node::Expr(e)) = hir.find(parent) { - let method_span = hir.span(parent); - if tables.is_method_call(e) && is_ref { + let parent_span = hir.span(parent); + let parent_did = parent.owner_def_id(); + // ```rust + // impl T { + // fn foo(&self) -> i32 {} + // } + // T.foo(); + // ^^^^^^^ a temporary `&T` created inside this method call due to `&self` + // ``` + // + let is_region_borrow = + tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + + // ```rust + // struct Foo(*const u8); + // bar(Foo(std::ptr::null())).await; + // ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor. + // ``` + debug!("parent_def_kind: {:?}", self.tcx.def_kind(parent_did)); + let is_raw_borrow_inside_fn_like_call = match self.tcx.def_kind(parent_did) { + Some(DefKind::Fn) | Some(DefKind::Ctor(..)) => target_ty.is_unsafe_ptr(), + _ => false, + }; + + if (tables.is_method_call(e) && is_region_borrow) + || is_raw_borrow_inside_fn_like_call + { err.span_help( - method_span, - "consider moving this method call into a `let` \ + parent_span, + "consider moving this into a `let` \ binding to create a shorter lived borrow", ); } From cd7b5edc2cac3fa0db6b464a6e94edd8f334274d Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 19 Jan 2020 12:59:59 +0800 Subject: [PATCH 0479/1253] update test ui for raw-ptr borrow inside generator --- .../traits/error_reporting/suggestions.rs | 2 +- .../issue-64130-4-async-move.stderr | 2 +- .../issues/issue-65436-raw-ptr-not-send.rs | 16 ++++++++++++ .../issue-65436-raw-ptr-not-send.stderr | 26 +++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs create mode 100644 src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 189412f60b904..ce961112670ab 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -12,8 +12,8 @@ use rustc_errors::{ error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, }; use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_hir::def::DefKind; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index f59dbc2638400..1e52d74f1559c 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -25,7 +25,7 @@ LL | let _x = get().await; ... LL | } | - `client` is later dropped here -help: consider moving this method call into a `let` binding to create a shorter lived borrow +help: consider moving this into a `let` binding to create a shorter lived borrow --> $DIR/issue-64130-4-async-move.rs:19:15 | LL | match client.status() { diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs new file mode 100644 index 0000000000000..3a814b47517ba --- /dev/null +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs @@ -0,0 +1,16 @@ +// edition:2018 + +struct Foo(*const u8); + +unsafe impl Send for Foo {} + +async fn bar(_: Foo) {} + +fn assert_send(_: T) {} + +fn main() { + assert_send(async { + //~^ ERROR future cannot be sent between threads safely + bar(Foo(std::ptr::null())).await; + }) +} diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr new file mode 100644 index 0000000000000..7638ba1fe7de8 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -0,0 +1,26 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-65436-raw-ptr-not-send.rs:12:5 + | +LL | fn assert_send(_: T) {} + | ----------- ---- required by this bound in `assert_send` +... +LL | assert_send(async { + | ^^^^^^^^^^^ future returned by `main` is not `Send` + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*const u8` +note: future is not `Send` as this value is used across an await + --> $DIR/issue-65436-raw-ptr-not-send.rs:14:9 + | +LL | bar(Foo(std::ptr::null())).await; + | ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here + | | | + | | has type `*const u8` + | await occurs here, with `std::ptr::null()` maybe used later +help: consider moving this into a `let` binding to create a shorter lived borrow + --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13 + | +LL | bar(Foo(std::ptr::null())).await; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From de388032555b697d1b0ef197241886ab90ac39b2 Mon Sep 17 00:00:00 2001 From: Tobias Kortkamp Date: Sun, 19 Jan 2020 07:04:24 +0100 Subject: [PATCH 0480/1253] Add -Wl,-znotext to default linker flags to link with lld 9 on FreeBSD 13.0-CURRENT i386 rust-nightly has been failing to link since 2019-12-10 with variations of ``` = note: ld: error: relocation R_386_PC32 cannot be used against symbol __rust_probestack; recompile with -fPIC >>> defined in /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libcompiler_builtins-6570a75fe85f0e1a.rlib(compiler_builtins-6570a75fe85f0e1a.compiler_builtins.2i519eqi-cgu.15.rcgu.o) >>> referenced by std.4xivr03c-cgu.14 >>> std-9bd70afd58e204b7.std.4xivr03c-cgu.14.rcgu.o:(_$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h1c78ed6e734a2bfc (.llvm.10122419023709863394)) in archive /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libstd-9bd70afd58e204b7.rlib ld: error: relocation R_386_PC32 cannot be used against symbol __rust_probestack; recompile with -fPIC >>> defined in /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libcompiler_builtins-6570a75fe85f0e1a.rlib(compiler_builtins-6570a75fe85f0e1a.compiler_builtins.2i519eqi-cgu.15.rcgu.o) >>> referenced by std.4xivr03c-cgu.14 >>> std-9bd70afd58e204b7.std.4xivr03c-cgu.14.rcgu.o:(std::io::util::copy::h9115f048f2203467) in archive /wrkdirs/usr/ports/lang/rust-nightly/work/rustc-nightly-src/build/i686-unknown-freebsd/stage1/lib/rustlib/i686-unknown-freebsd/lib/libstd-9bd70afd58e204b7.rlib clang-cpp: error: linker command failed with exit code 1 (use -v to see invocation) error: aborting due to previous error error: could not compile `rustc_macros`. ``` Full log: http://beefy17.nyi.freebsd.org/data/head-i386-default/p523508_s356869/logs/rust-nightly-1.42.0.20200118.log AFAICT it stopped building after bumping compiler_builtins to 0.1.22 in https://github.com/rust-lang/rust/pull/67110. --- src/librustc_target/spec/i686_unknown_freebsd.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/src/librustc_target/spec/i686_unknown_freebsd.rs index 88c944a6cb7eb..60f2188514e1b 100644 --- a/src/librustc_target/spec/i686_unknown_freebsd.rs +++ b/src/librustc_target/spec/i686_unknown_freebsd.rs @@ -4,7 +4,9 @@ pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + pre_link_args.push("-m32".to_string()); + pre_link_args.push("-Wl,-znotext".to_string()); base.stack_probes = true; Ok(Target { From 188f0bbe7fa2f64b6436e3e552320a1de1a00f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 19 Jan 2020 14:01:52 +0100 Subject: [PATCH 0481/1253] submodules: update clippy from a8d90f6a to fd0428f6 Changes: ```` Treat more strange pattern Split up `if_same_then_else` ui test Apply review comments Run `update_lints` Reduce span range Rename `ok_if_let` to `if_let_some_result` Apply review comments Add suggestion in `if_let_some_result` rustup https://github.com/rust-lang/rust/pull/67712 Allow `unused_self` lint at the function level Downgrade range_plus_one to pedantic Rustup to rust-lang/rust#68204 Add lifetimes to `LateLintPass` Fix rustc lint import paths generated by `new_lint` Add lint for default lint description Update documentation for adding new lints Generate new lints easily Split up `booleans` ui test Fix the ordering on `nonminimal_bool` ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index a8d90f6a57925..fd0428f622fee 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit a8d90f6a57925d204efb21b3f6d9726d6674f9bd +Subproject commit fd0428f622feee209e6014b802f5717d48d9e978 From 0c7f40f3b2fb75649ec6ed3970486c34dbf4db3b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 19 Jan 2020 15:35:44 +0100 Subject: [PATCH 0482/1253] clean up E0201 explanation --- src/librustc_error_codes/error_codes/E0201.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0201.md b/src/librustc_error_codes/error_codes/E0201.md index bdbf02f0033ab..0e1a7b7b7deb1 100644 --- a/src/librustc_error_codes/error_codes/E0201.md +++ b/src/librustc_error_codes/error_codes/E0201.md @@ -1,7 +1,7 @@ -It is an error to define two associated items (like methods, associated types, -associated functions, etc.) with the same identifier. +Two associated items (like methods, associated types, associated functions, +etc.) were defined with the same identifier. -For example: +Erroneous code example: ```compile_fail,E0201 struct Foo(u8); From a9aa2dfe844840a7e414873ce55ef9d02f1038a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 19 Jan 2020 15:35:55 +0100 Subject: [PATCH 0483/1253] clean up E0204 explanation --- src/librustc_error_codes/error_codes/E0204.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0204.md b/src/librustc_error_codes/error_codes/E0204.md index 315690111359f..96e44758be4fd 100644 --- a/src/librustc_error_codes/error_codes/E0204.md +++ b/src/librustc_error_codes/error_codes/E0204.md @@ -1,21 +1,24 @@ -An attempt to implement the `Copy` trait for a struct failed because one of the -fields does not implement `Copy`. To fix this, you must implement `Copy` for the -mentioned field. Note that this may not be possible, as in the example of +The `Copy` trait was implemented on a type which contains a field that doesn't +implement the `Copy` trait. + +Erroneous code example: ```compile_fail,E0204 struct Foo { - foo : Vec, + foo: Vec, } -impl Copy for Foo { } +impl Copy for Foo { } // error! ``` -This fails because `Vec` does not implement `Copy` for any `T`. +The `Copy` trait is implemented by default only on primitive types. If your +type only contains primitive types, you'll be able to implement `Copy` on it. +Otherwise, it won't be possible. Here's another example that will fail: ```compile_fail,E0204 -#[derive(Copy)] +#[derive(Copy)] // error! struct Foo<'a> { ty: &'a mut bool, } From b77a7997a866573bdf835f9dc00012877d87a22f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 Jan 2020 10:09:52 -0600 Subject: [PATCH 0484/1253] adjust codegen-units tests --- .../item-collection/drop_in_place_intrinsic.rs | 5 ++--- .../item-collection/generic-drop-glue.rs | 12 ++++++------ .../instantiation-through-vtable.rs | 4 ++-- .../item-collection/non-generic-drop-glue.rs | 4 ++-- .../item-collection/transitive-drop-glue.rs | 18 +++++++++--------- .../item-collection/tuple-drop-glue.rs | 8 ++++---- .../codegen-units/item-collection/unsizing.rs | 8 ++++---- .../partitioning/extern-drop-glue.rs | 6 +++--- .../partitioning/local-drop-glue.rs | 8 ++++---- .../partitioning/vtable-through-const.rs | 2 +- 10 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs index d5ddfb5e1c24c..27fb3cb1380d3 100644 --- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -4,7 +4,7 @@ #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ drop_in_place_intrinsic-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ drop_in_place_intrinsic-cgu.0[Internal] struct StructWithDtor(u32); impl Drop for StructWithDtor { @@ -16,7 +16,7 @@ impl Drop for StructWithDtor { #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal] let x = [StructWithDtor(0), StructWithDtor(1)]; drop_slice_in_place(&x); @@ -31,7 +31,6 @@ fn drop_slice_in_place(x: &[StructWithDtor]) { // not have drop-glue for the unsized [StructWithDtor]. This has to be // generated though when the drop_in_place() intrinsic is used. //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal] ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]); } } diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs index 94e79f0b32044..675bdfdb4d250 100644 --- a/src/test/codegen-units/item-collection/generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs @@ -37,7 +37,7 @@ enum EnumNoDrop { struct NonGenericNoDrop(i32); struct NonGenericWithDrop(i32); -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ generic_drop_glue-cgu.0[Internal] impl Drop for NonGenericWithDrop { //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0] @@ -47,11 +47,11 @@ impl Drop for NonGenericWithDrop { //~ MONO_ITEM fn generic_drop_glue::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0] let _ = StructWithDrop { x: 0i8, y: 'a' }.x; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]> let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y; @@ -60,17 +60,17 @@ fn start(_: isize, _: *const *const u8) -> isize { // This is supposed to generate drop-glue because it contains a field that // needs to be dropped. - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0] let _ = match EnumWithDrop::A::(0) { EnumWithDrop::A(x) => x, EnumWithDrop::B(x) => x as i32 }; - //~MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0] let _ = match EnumWithDrop::B::(1.0) { EnumWithDrop::A(x) => x, diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs index e79b069b25c13..db0390b58c84a 100644 --- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs +++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs @@ -24,13 +24,13 @@ impl Trait for Struct { fn start(_: isize, _: *const *const u8) -> isize { let s1 = Struct { _a: 0u32 }; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0] let _ = &s1 as &Trait; let s1 = Struct { _a: 0u64 }; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0] let _ = &s1 as &Trait; diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs index f13952bb7810e..a899b8b2c8b9c 100644 --- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs @@ -5,7 +5,7 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] struct StructWithDrop { x: i32 } @@ -19,7 +19,7 @@ struct StructNoDrop { x: i32 } -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] enum EnumWithDrop { A(i32) } diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs index 14545a33b5945..7e29af43538fd 100644 --- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs +++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs @@ -5,11 +5,11 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Root(Intermediate); -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Intermediate(Leaf); -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Leaf; impl Drop for Leaf { @@ -30,15 +30,15 @@ impl Drop for LeafGen { fn start(_: isize, _: *const *const u8) -> isize { let _ = Root(Intermediate(Leaf)); - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0] let _ = RootGen(IntermediateGen(LeafGen(0u32))); - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0] let _ = RootGen(IntermediateGen(LeafGen(0i16))); diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs index 54aff575f9117..d77de53ce010d 100644 --- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs +++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs @@ -5,7 +5,7 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ tuple_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ tuple_drop_glue-cgu.0[Internal] struct Dropped; impl Drop for Dropped { @@ -16,11 +16,11 @@ impl Drop for Dropped { //~ MONO_ITEM fn tuple_drop_glue::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal] let x = (0u32, Dropped); - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal] let x = (0i16, (Dropped, true)); 0 diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs index fd794df37608b..1ed60dcf265ff 100644 --- a/src/test/codegen-units/item-collection/unsizing.rs +++ b/src/test/codegen-units/item-collection/unsizing.rs @@ -48,13 +48,13 @@ impl, U: ?Sized> CoerceUnsized> for Wrapper fn start(_: isize, _: *const *const u8) -> isize { // simple case let bool_sized = &true; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0] let _bool_unsized = bool_sized as &Trait; let char_sized = &'a'; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0] let _char_unsized = char_sized as &Trait; @@ -64,13 +64,13 @@ fn start(_: isize, _: *const *const u8) -> isize { _b: 2, _c: 3.0f64 }; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0] let _struct_unsized = struct_sized as &Struct; // custom coercion let wrapper_sized = Wrapper(&0u32); - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0] let _wrapper_sized = wrapper_sized as Wrapper; diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index 0f3d72d16a96e..f85ae0c077486 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -11,14 +11,14 @@ // aux-build:cgu_extern_drop_glue.rs extern crate cgu_extern_drop_glue; -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal] struct LocalStruct(cgu_extern_drop_glue::Struct); //~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } @@ -30,7 +30,7 @@ pub mod mod1 { //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-mod1[Internal] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } } diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 938d4ffb693c9..366af4d4c386b 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -7,7 +7,7 @@ #![allow(dead_code)] #![crate_type="rlib"] -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] struct Struct { _a: u32 } @@ -17,7 +17,7 @@ impl Drop for Struct { fn drop(&mut self) {} } -//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] struct Outer { _a: Struct } @@ -36,10 +36,10 @@ pub mod mod1 { use super::Struct; - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-mod1[Internal] struct Struct2 { _a: Struct, - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] _b: (u32, Struct), } diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs index 5d23a4e13cbad..06e2ef6bb2257 100644 --- a/src/test/codegen-units/partitioning/vtable-through-const.rs +++ b/src/test/codegen-units/partitioning/vtable-through-const.rs @@ -66,7 +66,7 @@ mod mod1 { //~ MONO_ITEM fn vtable_through_const::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ vtable_through_const[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ vtable_through_const[Internal] // Since Trait1::do_something() is instantiated via its default implementation, // it is considered a generic and is instantiated here only because it is From 95934937bb32190c70ce48915cac14bb4609336d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 Jan 2020 10:11:16 -0600 Subject: [PATCH 0485/1253] fix real_drop_in_place in comments --- src/test/codegen/drop.rs | 2 +- .../ui/recursion/issue-38591-non-regular-dropck-recursion.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs index 959929fbafbf1..0c7f3bb2020a9 100644 --- a/src/test/codegen/drop.rs +++ b/src/test/codegen/drop.rs @@ -21,7 +21,7 @@ pub fn droppy() { // regular function exit. We used to have problems with quadratic growths of drop calls in such // functions. // FIXME(eddyb) the `void @` forces a match on the instruction, instead of the -// comment, that's `; call core::ptr::real_drop_in_place::` +// comment, that's `; call core::intrinsics::drop_in_place::` // for the `v0` mangling, should switch to matching on that once `legacy` is gone. // CHECK-NOT: invoke void @{{.*}}drop_in_place{{.*}}SomeUniqueName // CHECK: call void @{{.*}}drop_in_place{{.*}}SomeUniqueName diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs index 0fcf77d8722d6..d9996b80ac09d 100644 --- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs @@ -1,6 +1,6 @@ // Dropck shouldn't hit a recursion limit from checking `S` since it has // no free regions or type parameters. -// Codegen however, has to error for the infinitely many `real_drop_in_place` +// Codegen however, has to error for the infinitely many `drop_in_place` // functions it has been asked to create. // build-fail From d336e593cc07139468c8f6f12b929e80ae365159 Mon Sep 17 00:00:00 2001 From: Tianjiao Huang <18585305+gitletH@users.noreply.github.com> Date: Sun, 19 Jan 2020 12:16:29 -0800 Subject: [PATCH 0486/1253] Fix invalid link to C++ Exception Handling ABI documentation --- src/libpanic_unwind/gcc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 6e04317d491fc..591ff9d7fdcaa 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -4,7 +4,7 @@ //! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and //! documents linked from it. //! These are also good reads: -//! http://mentorembedded.github.io/cxx-abi/abi-eh.html +//! https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html //! http://monoinfinito.wordpress.com/series/exception-handling-in-c/ //! http://www.airs.com/blog/index.php?s=exception+frames //! From 2ecc48ffa17d55ec02f3beb5bb17c718cb439202 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 10 Jan 2020 05:08:02 +0900 Subject: [PATCH 0487/1253] Fix ICE #68025 --- src/librustc_typeck/expr_use_visitor.rs | 4 ++-- src/test/ui/closures/issue-68025.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/closures/issue-68025.rs diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index be00c57763a4e..47635209b0865 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -327,10 +327,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn walk_callee(&mut self, call: &hir::Expr<'_>, callee: &hir::Expr<'_>) { - let callee_ty = return_if_err!(self.mc.expr_ty_adjusted(callee)); + let callee_ty = self.mc.tables.expr_ty_adjusted(callee); debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty); match callee_ty.kind { - ty::FnDef(..) | ty::FnPtr(_) => { + ty::FnDef(..) | ty::FnPtr(_) | ty::Closure(..) => { self.consume_expr(callee); } ty::Error => {} diff --git a/src/test/ui/closures/issue-68025.rs b/src/test/ui/closures/issue-68025.rs new file mode 100644 index 0000000000000..261bfd60aaea9 --- /dev/null +++ b/src/test/ui/closures/issue-68025.rs @@ -0,0 +1,12 @@ +// check-pass + +fn foo(_: G, _: Box) +where + F: Fn(), + G: Fn(Box), +{ +} + +fn main() { + foo(|f| (*f)(), Box::new(|| {})); +} From fd90e56120c9fec88808f9464e27283b0c6954ad Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Thu, 16 Jan 2020 18:58:32 -0800 Subject: [PATCH 0488/1253] Add failing #[track_caller] test with fn pointers. --- .../tracked-fn-ptr-with-arg.rs | 16 ++++++++++++++++ .../ui/rfc-2091-track-caller/tracked-fn-ptr.rs | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs create mode 100644 src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs new file mode 100644 index 0000000000000..210a4f22f09cd --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(track_caller)] + +fn pass_to_ptr_call(f: fn(T), x: T) { + f(x); +} + +#[track_caller] +fn tracked_unit(_: ()) { + assert_eq!(std::panic::Location::caller().file(), file!()); +} + +fn main() { + pass_to_ptr_call(tracked_unit, ()); +} diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs new file mode 100644 index 0000000000000..1ce8f678b60f7 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(track_caller)] + +fn ptr_call(f: fn()) { + f(); +} + +#[track_caller] +fn tracked() { + assert_eq!(std::panic::Location::caller().file(), file!()); +} + +fn main() { + ptr_call(tracked); +} From 0ee922123facae1a170257bf1d6c493f8fa9f29e Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Thu, 16 Jan 2020 19:23:45 -0800 Subject: [PATCH 0489/1253] InstanceDef::requires_caller_location limited to items. --- src/librustc/ty/instance.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 9be50d19a5030..1ea695e40b255 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -141,7 +141,12 @@ impl<'tcx> InstanceDef<'tcx> { } pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { - tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) + match *self { + InstanceDef::Item(def_id) => { + tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) + } + _ => false, + } } } From 19d8527890b59ed25432fbf5a9f1bd75ac814ae2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 19 Jan 2020 21:21:48 +0200 Subject: [PATCH 0490/1253] rustc_mir: don't require a self argument for ReifyShim. --- src/librustc_mir/shim.rs | 80 ++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 01cecdd067945..b84616142cb07 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -31,9 +31,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx let mut result = match instance { ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance), - ty::InstanceDef::VtableShim(def_id) => { - build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None) - } + ty::InstanceDef::VtableShim(def_id) => build_call_shim( + tcx, + instance, + Some(Adjustment::DerefMove), + CallKind::Direct(def_id), + None, + ), ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); let adjustment = match tcx.lang_items().fn_trait_kind(trait_) { @@ -50,7 +54,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys)) + build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect, Some(arg_tys)) } // We are generating a call back to our def-id, which the // codegen backend knows to turn to an actual call, be it @@ -58,7 +62,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). ty::InstanceDef::ReifyShim(def_id) => { - build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None) + build_call_shim(tcx, instance, None, CallKind::Direct(def_id), None) } ty::InstanceDef::ClosureOnceShim { call_once: _ } => { let fn_mut = tcx.lang_items().fn_mut_trait().unwrap(); @@ -68,7 +72,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx .unwrap() .def_id; - build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None) + build_call_shim( + tcx, + instance, + Some(Adjustment::RefMut), + CallKind::Direct(call_mut), + None, + ) } ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty), ty::InstanceDef::CloneShim(def_id, ty) => { @@ -648,7 +658,7 @@ impl CloneShimBuilder<'tcx> { fn build_call_shim<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>, - rcvr_adjustment: Adjustment, + rcvr_adjustment: Option, call_kind: CallKind, untuple_args: Option<&[Ty<'tcx>]>, ) -> BodyAndCache<'tcx> { @@ -680,14 +690,16 @@ fn build_call_shim<'tcx>( let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }; - let rcvr_arg = Local::new(1 + 0); - let rcvr_l = Place::from(rcvr_arg); + let rcvr_place = || { + assert!(rcvr_adjustment.is_some()); + Place::from(Local::new(1 + 0)) + }; let mut statements = vec![]; - let rcvr = match rcvr_adjustment { - Adjustment::Identity => Operand::Move(rcvr_l), - Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)), - Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)), + let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment { + Adjustment::Identity => Operand::Move(rcvr_place()), + Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())), + Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())), Adjustment::RefMut => { // let rcvr = &mut rcvr; let ref_rcvr = local_decls.push(temp_decl( @@ -703,15 +715,15 @@ fn build_call_shim<'tcx>( source_info, kind: StatementKind::Assign(box ( Place::from(ref_rcvr), - Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l), + Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()), )), }); Operand::Move(Place::from(ref_rcvr)) } - }; + }); let (callee, mut args) = match call_kind { - CallKind::Indirect => (rcvr, vec![]), + CallKind::Indirect => (rcvr.unwrap(), vec![]), CallKind::Direct(def_id) => { let ty = tcx.type_of(def_id); ( @@ -720,21 +732,35 @@ fn build_call_shim<'tcx>( user_ty: None, literal: ty::Const::zero_sized(tcx, ty), }), - vec![rcvr], + rcvr.into_iter().collect::>(), ) } }; + let mut arg_range = 0..sig.inputs().len(); + + // Take the `self` ("receiver") argument out of the range (it's adjusted above). + if rcvr_adjustment.is_some() { + arg_range.start += 1; + } + + // Take the last argument, if we need to untuple it (handled below). + if untuple_args.is_some() { + arg_range.end -= 1; + } + + // Pass all of the non-special arguments directly. + args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i))))); + + // Untuple the last argument, if we have to. if let Some(untuple_args) = untuple_args { + let tuple_arg = Local::new(1 + (sig.inputs().len() - 1)); args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { - let arg_place = Place::from(Local::new(1 + 1)); - Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity)) + Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity)) })); - } else { - args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i))))); } - let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 }; + let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 }; let mut blocks = IndexVec::with_capacity(n_blocks); let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| { blocks.push(BasicBlockData { @@ -752,7 +778,7 @@ fn build_call_shim<'tcx>( func: callee, args, destination: Some((Place::return_place(), BasicBlock::new(1))), - cleanup: if let Adjustment::RefMut = rcvr_adjustment { + cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment { Some(BasicBlock::new(3)) } else { None @@ -762,13 +788,13 @@ fn build_call_shim<'tcx>( false, ); - if let Adjustment::RefMut = rcvr_adjustment { + if let Some(Adjustment::RefMut) = rcvr_adjustment { // BB #1 - drop for Self block( &mut blocks, vec![], TerminatorKind::Drop { - location: Place::from(rcvr_arg), + location: rcvr_place(), target: BasicBlock::new(2), unwind: None, }, @@ -777,13 +803,13 @@ fn build_call_shim<'tcx>( } // BB #1/#2 - return block(&mut blocks, vec![], TerminatorKind::Return, false); - if let Adjustment::RefMut = rcvr_adjustment { + if let Some(Adjustment::RefMut) = rcvr_adjustment { // BB #3 - drop if closure panics block( &mut blocks, vec![], TerminatorKind::Drop { - location: Place::from(rcvr_arg), + location: rcvr_place(), target: BasicBlock::new(4), unwind: None, }, From 72dffac6cf170c6c16c043299e35848014aae8d4 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sun, 19 Jan 2020 14:25:43 -0800 Subject: [PATCH 0491/1253] Test that ReifyShim + caller_location return the def site. --- src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs | 5 ++++- src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs index 210a4f22f09cd..0407eafbfd41c 100644 --- a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs +++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs @@ -8,7 +8,10 @@ fn pass_to_ptr_call(f: fn(T), x: T) { #[track_caller] fn tracked_unit(_: ()) { - assert_eq!(std::panic::Location::caller().file(), file!()); + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); } fn main() { diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs index 1ce8f678b60f7..a4baaa26ced1e 100644 --- a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs +++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs @@ -8,7 +8,10 @@ fn ptr_call(f: fn()) { #[track_caller] fn tracked() { - assert_eq!(std::panic::Location::caller().file(), file!()); + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); } fn main() { From 0017f495783324b036ffcaafedf7881725ba1e02 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 20 Jan 2020 07:38:05 +0900 Subject: [PATCH 0492/1253] Replace `walk_callee` with `consume_expr` --- src/librustc_typeck/expr_use_visitor.rs | 60 +------------------------ 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index 47635209b0865..1d3ace933cc43 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -3,7 +3,6 @@ //! `ExprUseVisitor` determines how expressions are being used. pub use self::ConsumeMode::*; -use self::OverloadedCallType::*; // Export these here so that Clippy can use them. pub use mc::{Place, PlaceBase, Projection}; @@ -48,35 +47,6 @@ pub enum MutateMode { WriteAndRead, // x += y } -#[derive(Copy, Clone)] -enum OverloadedCallType { - FnOverloadedCall, - FnMutOverloadedCall, - FnOnceOverloadedCall, -} - -impl OverloadedCallType { - fn from_trait_id(tcx: TyCtxt<'_>, trait_id: DefId) -> OverloadedCallType { - for &(maybe_function_trait, overloaded_call_type) in &[ - (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall), - (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall), - (tcx.lang_items().fn_trait(), FnOverloadedCall), - ] { - match maybe_function_trait { - Some(function_trait) if function_trait == trait_id => return overloaded_call_type, - _ => continue, - } - } - - bug!("overloaded call didn't map to known function trait") - } - - fn from_method_id(tcx: TyCtxt<'_>, method_id: DefId) -> OverloadedCallType { - let method = tcx.associated_item(method_id); - OverloadedCallType::from_trait_id(tcx, method.container.id()) - } -} - /////////////////////////////////////////////////////////////////////////// // The ExprUseVisitor type // @@ -211,7 +181,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::Call(ref callee, ref args) => { // callee(args) - self.walk_callee(expr, callee); + self.consume_expr(callee); self.consume_exprs(args); } @@ -326,34 +296,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - fn walk_callee(&mut self, call: &hir::Expr<'_>, callee: &hir::Expr<'_>) { - let callee_ty = self.mc.tables.expr_ty_adjusted(callee); - debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty); - match callee_ty.kind { - ty::FnDef(..) | ty::FnPtr(_) | ty::Closure(..) => { - self.consume_expr(callee); - } - ty::Error => {} - _ => { - if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) { - match OverloadedCallType::from_method_id(self.tcx(), def_id) { - FnMutOverloadedCall => { - self.borrow_expr(callee, ty::MutBorrow); - } - FnOverloadedCall => { - self.borrow_expr(callee, ty::ImmBorrow); - } - FnOnceOverloadedCall => self.consume_expr(callee), - } - } else { - self.tcx() - .sess - .delay_span_bug(call.span, "no type-dependent def for overloaded call"); - } - } - } - } - fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) { match stmt.kind { hir::StmtKind::Local(ref local) => { From 6ba08755dfd9ddbb55248a0263a4e81d3602b410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 18:34:30 -0800 Subject: [PATCH 0493/1253] When encountering an undefined named lifetime, point to where it can be This doesn't mention that using an existing lifetime is possible, but that would hopefully be clear as always being an option. The intention of this is to teach newcomers what the lifetime syntax is. --- src/librustc_resolve/lib.rs | 1 + src/librustc_resolve/lifetimes.rs | 41 +++++- src/test/ui/error-codes/E0261.stderr | 6 +- .../feature-gate-in_band_lifetimes.stderr | 118 ++++++++++++++++-- ...ssociated_type_undeclared_lifetimes.stderr | 18 +++ .../no_in_band_in_struct.stderr | 4 + .../no_introducing_in_band_in_locals.stderr | 2 + ...ethod-call-lifetime-args-unresolved.stderr | 2 + .../parser/trait-object-trait-parens.stderr | 3 + src/test/ui/regions/regions-in-enums.stderr | 4 + src/test/ui/regions/regions-in-structs.stderr | 5 + .../ui/regions/regions-name-undeclared.stderr | 46 ++++++- src/test/ui/regions/regions-undeclared.stderr | 11 +- .../where-lifetime-resolution.stderr | 6 + 14 files changed, 249 insertions(+), 18 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 60a0049f5da37..29872be47c2f3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -11,6 +11,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] #![feature(nll)] +#![feature(slice_patterns)] #![recursion_limit = "256"] pub use rustc_hir::def::{Namespace, PerNS}; diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 5fae8f3318743..f8e2f0cafff02 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -183,6 +183,10 @@ struct LifetimeContext<'a, 'tcx> { xcrate_object_lifetime_defaults: DefIdMap>, lifetime_uses: &'a mut DefIdMap>, + + /// When encountering an undefined named lifetime, we will suggest introducing it in these + /// places. + missing_named_lifetime_spots: Vec<&'tcx hir::Generics<'tcx>>, } #[derive(Debug)] @@ -342,6 +346,7 @@ fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), lifetime_uses: &mut Default::default(), + missing_named_lifetime_spots: vec![], }; for (_, item) in &krate.items { visitor.visit_item(item); @@ -384,9 +389,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { match item.kind { hir::ItemKind::Fn(ref sig, ref generics, _) => { + self.missing_named_lifetime_spots.push(generics); self.visit_early_late(None, &sig.decl, generics, |this| { intravisit::walk_item(this, item); }); + self.missing_named_lifetime_spots.pop(); } hir::ItemKind::ExternCrate(_) @@ -417,6 +424,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) | hir::ItemKind::Impl { ref generics, .. } => { + self.missing_named_lifetime_spots.push(generics); + // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x let track_lifetime_uses = match item.kind { @@ -454,6 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.check_lifetime_params(old_scope, &generics.params); intravisit::walk_item(this, item); }); + self.missing_named_lifetime_spots.pop(); } } } @@ -686,6 +696,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; + self.missing_named_lifetime_spots.push(&trait_item.generics); match trait_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -737,10 +748,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_trait_item(self, trait_item); } } + self.missing_named_lifetime_spots.pop(); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { use self::hir::ImplItemKind::*; + self.missing_named_lifetime_spots.push(&impl_item.generics); match impl_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -824,6 +837,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_impl_item(self, impl_item); } } + self.missing_named_lifetime_spots.pop(); } fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { @@ -1306,7 +1320,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { where F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>), { - let LifetimeContext { tcx, map, lifetime_uses, .. } = self; + let LifetimeContext { tcx, map, lifetime_uses, missing_named_lifetime_spots, .. } = self; let labels_in_fn = take(&mut self.labels_in_fn); let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { @@ -1317,7 +1331,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { is_in_fn_syntax: self.is_in_fn_syntax, labels_in_fn, xcrate_object_lifetime_defaults, - lifetime_uses: lifetime_uses, + lifetime_uses, + missing_named_lifetime_spots: missing_named_lifetime_spots.to_vec(), }; debug!("entering scope {:?}", this.scope); f(self.scope, &mut this); @@ -1807,15 +1822,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, def); } else { - struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, lifetime_ref.span, E0261, "use of undeclared lifetime name `{}`", lifetime_ref - ) - .span_label(lifetime_ref.span, "undeclared lifetime") - .emit(); + ); + err.span_label(lifetime_ref.span, "undeclared lifetime"); + if !self.is_in_fn_syntax { + for generics in &self.missing_named_lifetime_spots { + let (span, sugg) = match &generics.params { + [] => (generics.span, format!("<{}>", lifetime_ref)), + [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), + }; + err.span_suggestion( + span, + &format!("consider introducing lifetime `{}` here", lifetime_ref), + sugg, + Applicability::MaybeIncorrect, + ); + } + } + err.emit(); } } diff --git a/src/test/ui/error-codes/E0261.stderr b/src/test/ui/error-codes/E0261.stderr index 3bf5e9d815485..0eab2dc0ee05f 100644 --- a/src/test/ui/error-codes/E0261.stderr +++ b/src/test/ui/error-codes/E0261.stderr @@ -2,11 +2,15 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/E0261.rs:1:12 | LL | fn foo(x: &'a str) { } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/E0261.rs:5:9 | +LL | struct Foo { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | x: &'a str, | ^^ undeclared lifetime diff --git a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr index 5c64bf6539c91..bbf3ea8a89f23 100644 --- a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr +++ b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr @@ -2,103 +2,207 @@ error[E0261]: use of undeclared lifetime name `'x` --> $DIR/feature-gate-in_band_lifetimes.rs:3:12 | LL | fn foo(x: &'x u8) -> &'x u8 { x } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` error[E0261]: use of undeclared lifetime name `'x` --> $DIR/feature-gate-in_band_lifetimes.rs:3:23 | LL | fn foo(x: &'x u8) -> &'x u8 { x } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:15:12 | LL | impl<'a> X<'b> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'b` here: `'b,` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:17:27 | LL | fn inner_2(&self) -> &'b u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> X<'b> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn inner_2<'b>(&self) -> &'b u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:23:8 | LL | impl X<'b> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'b` here: `<'b>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:25:27 | LL | fn inner_3(&self) -> &'b u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> X<'b> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn inner_3<'b>(&self) -> &'b u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:33:9 | LL | impl Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:35:25 | LL | fn inner(&self) -> &'a u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | impl<'a> Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'a` here + | +LL | fn inner<'a>(&self) -> &'a u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:43:27 | LL | fn any_lifetime() -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn any_lifetime<'b>() -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:45:27 | LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:45:40 | LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:50:14 | LL | impl MyTrait<'a> for Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:50:25 | LL | impl MyTrait<'a> for Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:53:31 | LL | fn my_lifetime(&self) -> &'a u8 { self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | impl<'a> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'a` here + | +LL | fn my_lifetime<'a>(&self) -> &'a u8 { self.0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:55:27 | LL | fn any_lifetime() -> &'b u8 { &0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn any_lifetime<'b>() -> &'b u8 { &0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:57:27 | LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:57:40 | LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 } + | ^^^^ error: aborting due to 17 previous errors diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index 81137e81dc489..fc2ce1cb866bb 100644 --- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -3,12 +3,30 @@ error[E0261]: use of undeclared lifetime name `'b` | LL | + Deref>; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait Iterable<'b> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | type Iter<'b, 'a>: Iterator> + | ^^^ error[E0261]: use of undeclared lifetime name `'undeclared` --> $DIR/generic_associated_type_undeclared_lifetimes.rs:12:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; | ^^^^^^^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'undeclared` here + | +LL | trait Iterable<'undeclared> { + | ^^^^^^^^^^^^^ +help: consider introducing lifetime `'undeclared` here + | +LL | fn iter<'undeclared, 'a>(&'a self) -> Self::Iter<'undeclared>; + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr index a270dd03926dc..fe656f7af7e01 100644 --- a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr +++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr @@ -1,12 +1,16 @@ error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_in_band_in_struct.rs:5:9 | +LL | struct Foo { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | x: &'test u32, | ^^^^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_in_band_in_struct.rs:9:10 | +LL | enum Bar { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | Baz(&'test u32), | ^^^^^ undeclared lifetime diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index c307066be6b46..bfb20ade035cf 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -1,6 +1,8 @@ error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_introducing_in_band_in_locals.rs:5:13 | +LL | fn foo(x: &u32) { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | let y: &'test u32 = x; | ^^^^^ undeclared lifetime diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr index 67fd8d7a13eb1..c9f235c4f7df7 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr @@ -1,6 +1,8 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/method-call-lifetime-args-unresolved.rs:2:15 | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | 0.clone::<'a>(); | ^^ undeclared lifetime diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index 03fb764ee0384..4b9f49423cbf4 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -33,6 +33,9 @@ LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>; error[E0261]: use of undeclared lifetime name `'a` --> $DIR/trait-object-trait-parens.rs:11:31 | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>; | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-in-enums.stderr b/src/test/ui/regions/regions-in-enums.stderr index cfed9feba4b82..66537653291c7 100644 --- a/src/test/ui/regions/regions-in-enums.stderr +++ b/src/test/ui/regions/regions-in-enums.stderr @@ -1,12 +1,16 @@ error[E0261]: use of undeclared lifetime name `'foo` --> $DIR/regions-in-enums.rs:13:9 | +LL | enum No0 { + | - help: consider introducing lifetime `'foo` here: `<'foo>` LL | X5(&'foo usize) | ^^^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-enums.rs:17:9 | +LL | enum No1 { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | X6(&'a usize) | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-in-structs.stderr b/src/test/ui/regions/regions-in-structs.stderr index 8314942759d1a..5dfdc2ee93b43 100644 --- a/src/test/ui/regions/regions-in-structs.stderr +++ b/src/test/ui/regions/regions-in-structs.stderr @@ -1,12 +1,17 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-structs.rs:10:9 | +LL | struct StructDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | a: &'a isize, | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-structs.rs:11:9 | +LL | struct StructDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | a: &'a isize, LL | b: &'a isize, | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index 5f6a48a35f368..79ebef41dccd6 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -3,34 +3,67 @@ error[E0261]: use of undeclared lifetime name `'b` | LL | fn m4(&self, arg: &'b isize) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m4<'b>(&self, arg: &'b isize) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:16:12 | LL | fn m5(&'b self) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m5<'b>(&'b self) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:17:27 | LL | fn m6(&self, arg: Foo<'b>) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m6<'b>(&self, arg: Foo<'b>) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:25:22 | LL | type X = Option<&'a isize>; - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:27:13 | +LL | enum E { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | E1(&'a isize) | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:30:13 | +LL | struct S { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | f: &'a isize | ^^ undeclared lifetime @@ -38,13 +71,17 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:32:14 | LL | fn f(a: &'a isize) { } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:40:17 | LL | fn fn_types(a: &'a isize, - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:42:36 @@ -61,6 +98,9 @@ LL | ... &'b isize)>, error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:46:17 | +LL | fn fn_types(a: &'a isize, + | - help: consider introducing lifetime `'a` here: `<'a>` +... LL | c: &'a isize) | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-undeclared.stderr b/src/test/ui/regions/regions-undeclared.stderr index 495aec3fde5f1..6bfde5524ac49 100644 --- a/src/test/ui/regions/regions-undeclared.stderr +++ b/src/test/ui/regions/regions-undeclared.stderr @@ -7,12 +7,17 @@ LL | static c_x: &'blk isize = &22; error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:4:10 | +LL | enum EnumDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | Foo(&'a isize), | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:5:10 | +LL | enum EnumDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | Foo(&'a isize), LL | Bar(&'a isize), | ^^ undeclared lifetime @@ -20,11 +25,15 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:8:15 | LL | fn fnDecl(x: &'a isize, - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:9:15 | +LL | fn fnDecl(x: &'a isize, + | - help: consider introducing lifetime `'a` here: `<'a>` LL | y: &'a isize) | ^^ undeclared lifetime diff --git a/src/test/ui/where-clauses/where-lifetime-resolution.stderr b/src/test/ui/where-clauses/where-lifetime-resolution.stderr index 0081ae07163b3..49799a93017eb 100644 --- a/src/test/ui/where-clauses/where-lifetime-resolution.stderr +++ b/src/test/ui/where-clauses/where-lifetime-resolution.stderr @@ -1,6 +1,9 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/where-lifetime-resolution.rs:6:38 | +LL | fn f() where + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | for<'a> dyn Trait1<'a>: Trait1<'a>, // OK LL | (dyn for<'a> Trait1<'a>): Trait1<'a>, | ^^ undeclared lifetime @@ -13,6 +16,9 @@ LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, error[E0261]: use of undeclared lifetime name `'b` --> $DIR/where-lifetime-resolution.rs:8:52 | +LL | fn f() where + | - help: consider introducing lifetime `'b` here: `<'b>` +... LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, | ^^ undeclared lifetime From 78d3ea5484c3ebcc49bddba39f5b5be5f99b8c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 18:35:48 -0800 Subject: [PATCH 0494/1253] When encountering an expected named lifetime and none are present, suggest adding one --- src/librustc_resolve/lifetimes.rs | 82 ++++++++++++++++--- src/test/ui/error-codes/E0106.rs | 2 +- src/test/ui/error-codes/E0106.stderr | 32 +++++++- .../assoc-type.stderr | 14 +++- ...anon-lifetime-in-struct-declaration.stderr | 7 +- src/test/ui/issues/issue-19707.stderr | 12 ++- src/test/ui/issues/issue-26638.stderr | 6 +- src/test/ui/issues/issue-30255.stderr | 18 +++- ...urn-type-requires-explicit-lifetime.stderr | 12 ++- .../ex1b-return-no-names-if-else.stderr | 6 +- src/test/ui/proc-macro/item-error.stderr | 8 +- .../ui/regions/regions-in-enums-anon.stderr | 8 +- .../ui/regions/regions-in-structs-anon.stderr | 8 +- src/test/ui/rfc1623.stderr | 4 +- ...oxed-closure-sugar-lifetime-elision.stderr | 11 ++- .../dyn-trait-underscore-in-struct.stderr | 8 +- .../in-fn-return-illegal.stderr | 6 +- .../ui/underscore-lifetime/in-struct.stderr | 16 +++- .../underscore-lifetime-binders.stderr | 8 +- 19 files changed, 229 insertions(+), 39 deletions(-) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index f8e2f0cafff02..345e5184e84b6 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -2398,6 +2398,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_refs.len(), &lifetime_names, self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + &self.missing_named_lifetime_spots, ); } @@ -2908,19 +2909,80 @@ fn add_missing_lifetime_specifiers_label( count: usize, lifetime_names: &FxHashSet, snippet: Option<&str>, + missing_named_lifetime_spots: &[&hir::Generics<'_>], ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); - } else if let (1, Some(name), Some("&")) = - (lifetime_names.len(), lifetime_names.iter().next(), snippet) - { - err.span_suggestion( - span, - "consider using the named lifetime", - format!("&{} ", name), - Applicability::MaybeIncorrect, - ); } else { - err.span_label(span, "expected lifetime parameter"); + let mut introduce_suggestion = vec![]; + if let Some(generics) = missing_named_lifetime_spots.iter().last() { + introduce_suggestion.push(match &generics.params { + [] => (generics.span, "<'lifetime>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + }); + } + + match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { + (1, Some(name), Some("&")) => { + err.span_suggestion( + span, + "consider using the named lifetime", + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); + } + (1, Some(name), Some("'_")) => { + err.span_suggestion( + span, + "consider using the named lifetime", + name.to_string(), + Applicability::MaybeIncorrect, + ); + } + (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { + err.span_suggestion( + span, + "consider using the named lifetime", + format!("{}<{}>", snippet, name), + Applicability::MaybeIncorrect, + ); + } + (0, _, Some("&")) => { + err.span_label(span, "expected named lifetime parameter"); + if !introduce_suggestion.is_empty() { + introduce_suggestion.push((span, "&'lifetime ".to_string())); + err.multipart_suggestion( + "consider introducing a named lifetime", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + } + (0, _, Some("'_")) => { + err.span_label(span, "expected named lifetime parameter"); + if !introduce_suggestion.is_empty() { + introduce_suggestion.push((span, "'lifetime".to_string())); + err.multipart_suggestion( + "consider introducing a named lifetime", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + } + (0, _, Some(snippet)) if !snippet.ends_with(">") => { + err.span_label(span, "expected named lifetime parameter"); + if !introduce_suggestion.is_empty() { + introduce_suggestion.push((span, format!("{}<'lifetime>", snippet))); + err.multipart_suggestion( + "consider introducing a named lifetime", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + } + _ => { + err.span_label(span, "expected lifetime parameter"); + } + } } } diff --git a/src/test/ui/error-codes/E0106.rs b/src/test/ui/error-codes/E0106.rs index d6537d123637c..cc3438727a817 100644 --- a/src/test/ui/error-codes/E0106.rs +++ b/src/test/ui/error-codes/E0106.rs @@ -16,7 +16,7 @@ struct Buzz<'a, 'b>(&'a str, &'b str); struct Quux { baz: Baz, //~^ ERROR E0106 - //~| expected lifetime parameter + //~| expected named lifetime parameter buzz: Buzz, //~^ ERROR E0106 //~| expected 2 lifetime parameters diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index cea9581e70138..bb7efa90c8002 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -2,25 +2,49 @@ error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:2:8 | LL | x: &bool, - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime bool, + | error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:7:7 | LL | B(&bool), - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | enum Bar<'lifetime> { +LL | A(u8), +LL | B(&'lifetime bool), + | error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:10:14 | LL | type MyStr = &str; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | type MyStr<'lifetime> = &'lifetime str; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:17:10 | LL | baz: Baz, - | ^^^ expected lifetime parameter + | ^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Quux<'lifetime> { +LL | baz: Baz<'lifetime>, + | error[E0106]: missing lifetime specifiers --> $DIR/E0106.rs:20:11 diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr index 492ca872187e0..0835970df40f5 100644 --- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -2,13 +2,23 @@ error[E0106]: missing lifetime specifier --> $DIR/assoc-type.rs:11:19 | LL | type Output = &i32; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | type Output<'lifetime> = &'lifetime i32; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/assoc-type.rs:16:20 | LL | type Output = &'_ i32; - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | type Output<'lifetime> = &'lifetime i32; + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr index 9579abb76b32f..32507e21d27b5 100644 --- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr +++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr @@ -2,7 +2,12 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-61124-anon-lifetime-in-struct-declaration.rs:8:19 | LL | struct Heartbreak(Betrayal); - | ^^^^^^^^ expected lifetime parameter + | ^^^^^^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>); + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index c85ce0eb3a75e..51a8aabb48307 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -2,17 +2,25 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:3:28 | LL | type Foo = fn(&u8, &u8) -> &u8; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime + | +LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 | LL | fn bar &u8>(f: &F) {} - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime + | +LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 6d7c1b0c43fce..8396c932c5b43 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:1:62 | LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime + | +LL | fn parse_type<'lifetime>(iter: Box+'static>) -> &'lifetime str { iter.next() } + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:4:40 diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index c53129b7f2967..64f89496caaa3 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -2,25 +2,37 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:9:24 | LL | fn f(a: &S, b: i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime + | +LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 | LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` +help: consider introducing a named lifetime + | +LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 | LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` +help: consider introducing a named lifetime + | +LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 3f7c3934a0ba2..075ea3c691fca 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -10,17 +10,25 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33 | LL | fn g(_x: &isize, _y: &isize) -> &isize { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` +help: consider introducing a named lifetime + | +LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 | LL | fn h(_x: &Foo) -> &isize { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime + | +LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index a4e0d71a3fa6b..f95b4cb16be2f 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/ex1b-return-no-names-if-else.rs:1:29 | LL | fn foo(x: &i32, y: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: consider introducing a named lifetime + | +LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr index e801c26c43b9c..19bbadbcd4177 100644 --- a/src/test/ui/proc-macro/item-error.stderr +++ b/src/test/ui/proc-macro/item-error.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/item-error.rs:10:8 | LL | a: &u64 - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct A<'lifetime> { +LL | a: &'lifetime u64 + | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr index ae06e7653dbeb..6e653452f552b 100644 --- a/src/test/ui/regions/regions-in-enums-anon.stderr +++ b/src/test/ui/regions/regions-in-enums-anon.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/regions-in-enums-anon.rs:4:9 | LL | Bar(&isize) - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | enum Foo<'lifetime> { +LL | Bar(&'lifetime isize) + | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr index a1d4ebb597b4c..b40990e3edbed 100644 --- a/src/test/ui/regions/regions-in-structs-anon.stderr +++ b/src/test/ui/regions/regions-in-structs-anon.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/regions-in-structs-anon.rs:4:8 | LL | x: &isize - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime isize + | error: aborting due to previous error diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 171c00ba7b813..5b665e181412a 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:8:42 | LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:10:39 | LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 9fb9a07166f84..3b101bf304a7d 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -2,9 +2,18 @@ error[E0106]: missing lifetime specifier --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:39 | LL | let _: dyn Foo(&isize, &usize) -> &usize; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime + | +LL | fn main<'lifetime>() { +LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, +LL | dyn Foo(&isize) -> &isize >(); +LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, +LL | dyn Foo(&isize) -> (&isize, &isize) >(); +LL | + ... error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index b20c23ade2b78..c06891d2308ca 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/dyn-trait-underscore-in-struct.rs:9:24 | LL | x: Box, - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Foo<'lifetime> { +LL | x: Box, + | error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound --> $DIR/dyn-trait-underscore-in-struct.rs:9:12 diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index ed61bdfdddab3..bdfb8ce4d83d4 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/in-fn-return-illegal.rs:5:30 | LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: consider introducing a named lifetime + | +LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr index 6bbdc71195a50..46dc3f899a140 100644 --- a/src/test/ui/underscore-lifetime/in-struct.stderr +++ b/src/test/ui/underscore-lifetime/in-struct.stderr @@ -2,13 +2,25 @@ error[E0106]: missing lifetime specifier --> $DIR/in-struct.rs:6:9 | LL | x: &'_ u32, - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime u32, + | error[E0106]: missing lifetime specifier --> $DIR/in-struct.rs:10:14 | LL | Variant(&'_ u32), - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime + | +LL | enum Bar<'lifetime> { +LL | Variant(&'lifetime u32), + | error: aborting due to 2 previous errors diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index ef9e7e39df0bc..6c2159bc66169 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -14,7 +14,7 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:2:17 | LL | struct Baz<'a>(&'_ &'a u8); - | ^^ expected lifetime parameter + | ^^ help: consider using the named lifetime: `'a` error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:10:33 @@ -28,9 +28,13 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:16:35 | LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` +help: consider introducing a named lifetime + | +LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to 5 previous errors From 2102723887cbd3253dace65f4574422be516259c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 22:05:31 -0800 Subject: [PATCH 0495/1253] review comments --- src/librustc_resolve/lifetimes.rs | 6 +++--- src/test/ui/error-codes/E0106.stderr | 8 ++++---- .../ui/impl-header-lifetime-elision/assoc-type.stderr | 4 ++-- ...issue-61124-anon-lifetime-in-struct-declaration.stderr | 2 +- src/test/ui/issues/issue-19707.stderr | 4 ++-- src/test/ui/issues/issue-26638.stderr | 2 +- src/test/ui/issues/issue-30255.stderr | 6 +++--- ...-elision-return-type-requires-explicit-lifetime.stderr | 4 ++-- .../lifetime-errors/ex1b-return-no-names-if-else.stderr | 2 +- src/test/ui/proc-macro/item-error.stderr | 2 +- src/test/ui/regions/regions-in-enums-anon.stderr | 2 +- src/test/ui/regions/regions-in-structs-anon.stderr | 2 +- .../unboxed-closure-sugar-lifetime-elision.stderr | 2 +- .../dyn-trait-underscore-in-struct.stderr | 2 +- .../ui/underscore-lifetime/in-fn-return-illegal.stderr | 2 +- src/test/ui/underscore-lifetime/in-struct.stderr | 4 ++-- .../underscore-lifetime-binders.stderr | 2 +- 17 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 345e5184e84b6..1fb35ca26d6f8 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -2952,7 +2952,7 @@ fn add_missing_lifetime_specifiers_label( if !introduce_suggestion.is_empty() { introduce_suggestion.push((span, "&'lifetime ".to_string())); err.multipart_suggestion( - "consider introducing a named lifetime", + "consider introducing a named lifetime parameter", introduce_suggestion, Applicability::MaybeIncorrect, ); @@ -2963,7 +2963,7 @@ fn add_missing_lifetime_specifiers_label( if !introduce_suggestion.is_empty() { introduce_suggestion.push((span, "'lifetime".to_string())); err.multipart_suggestion( - "consider introducing a named lifetime", + "consider introducing a named lifetime parameter", introduce_suggestion, Applicability::MaybeIncorrect, ); @@ -2974,7 +2974,7 @@ fn add_missing_lifetime_specifiers_label( if !introduce_suggestion.is_empty() { introduce_suggestion.push((span, format!("{}<'lifetime>", snippet))); err.multipart_suggestion( - "consider introducing a named lifetime", + "consider introducing a named lifetime parameter", introduce_suggestion, Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index bb7efa90c8002..e01e0a6f54b07 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | x: &bool, | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Foo<'lifetime> { LL | x: &'lifetime bool, @@ -16,7 +16,7 @@ error[E0106]: missing lifetime specifier LL | B(&bool), | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | enum Bar<'lifetime> { LL | A(u8), @@ -29,7 +29,7 @@ error[E0106]: missing lifetime specifier LL | type MyStr = &str; | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | type MyStr<'lifetime> = &'lifetime str; | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -40,7 +40,7 @@ error[E0106]: missing lifetime specifier LL | baz: Baz, | ^^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Quux<'lifetime> { LL | baz: Baz<'lifetime>, diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr index 0835970df40f5..14c53f906654b 100644 --- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | type Output = &i32; | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | type Output<'lifetime> = &'lifetime i32; | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -15,7 +15,7 @@ error[E0106]: missing lifetime specifier LL | type Output = &'_ i32; | ^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | type Output<'lifetime> = &'lifetime i32; | ^^^^^^^^^^^ ^^^^^^^^^ diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr index 32507e21d27b5..5f101a24c1d43 100644 --- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr +++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | struct Heartbreak(Betrayal); | ^^^^^^^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>); | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 51a8aabb48307..8a627bc0bd4de 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -5,7 +5,7 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn bar &u8>(f: &F) {} | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} | ^^^^^^^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 8396c932c5b43..85d5d9cc42e9a 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -5,7 +5,7 @@ LL | fn parse_type(iter: Box+'static>) -> &str { iter.ne | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn parse_type<'lifetime>(iter: Box+'static>) -> &'lifetime str { iter.next() } | ^^^^^^^^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index 64f89496caaa3..c940227764099 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -5,7 +5,7 @@ LL | fn f(a: &S, b: i32) -> &i32 { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { | ^^^^^^^^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 075ea3c691fca..1d5eeac23f96a 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -13,7 +13,7 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { | ^^^^^^^^^^^ ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn h(_x: &Foo) -> &isize { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { | ^^^^^^^^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index f95b4cb16be2f..2990ab8682434 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -5,7 +5,7 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { | ^^^^^^^^^^^ ^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr index 19bbadbcd4177..01eadbe252e9f 100644 --- a/src/test/ui/proc-macro/item-error.stderr +++ b/src/test/ui/proc-macro/item-error.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | a: &u64 | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct A<'lifetime> { LL | a: &'lifetime u64 diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr index 6e653452f552b..41655a210b3c0 100644 --- a/src/test/ui/regions/regions-in-enums-anon.stderr +++ b/src/test/ui/regions/regions-in-enums-anon.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | Bar(&isize) | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | enum Foo<'lifetime> { LL | Bar(&'lifetime isize) diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr index b40990e3edbed..fbe8036880f48 100644 --- a/src/test/ui/regions/regions-in-structs-anon.stderr +++ b/src/test/ui/regions/regions-in-structs-anon.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | x: &isize | ^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Foo<'lifetime> { LL | x: &'lifetime isize diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 3b101bf304a7d..0a028e44919a6 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -5,7 +5,7 @@ LL | let _: dyn Foo(&isize, &usize) -> &usize; | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn main<'lifetime>() { LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index c06891d2308ca..04df2e4570396 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | x: Box, | ^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Foo<'lifetime> { LL | x: Box, diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index bdfb8ce4d83d4..cf820249c80af 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -5,7 +5,7 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } | ^^^^^^^^^^^ ^^^^^^^^^ diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr index 46dc3f899a140..e01b39a4b64f4 100644 --- a/src/test/ui/underscore-lifetime/in-struct.stderr +++ b/src/test/ui/underscore-lifetime/in-struct.stderr @@ -4,7 +4,7 @@ error[E0106]: missing lifetime specifier LL | x: &'_ u32, | ^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | struct Foo<'lifetime> { LL | x: &'lifetime u32, @@ -16,7 +16,7 @@ error[E0106]: missing lifetime specifier LL | Variant(&'_ u32), | ^^ expected named lifetime parameter | -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | enum Bar<'lifetime> { LL | Variant(&'lifetime u32), diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 6c2159bc66169..517904ee62869 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -31,7 +31,7 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` -help: consider introducing a named lifetime +help: consider introducing a named lifetime parameter | LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } | ^^^^^^^^^^^ ^^^^^^^^^ From 12ff4d0bd633b44939b6bca4ec67b0eac2d8be42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 17 Jan 2020 15:59:07 -0800 Subject: [PATCH 0496/1253] review comments: use closures --- src/librustc_resolve/lifetimes.rs | 83 ++++++++++++------------------- 1 file changed, 31 insertions(+), 52 deletions(-) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 1fb35ca26d6f8..528f5aaf034c7 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -2914,71 +2914,50 @@ fn add_missing_lifetime_specifiers_label( if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); } else { - let mut introduce_suggestion = vec![]; - if let Some(generics) = missing_named_lifetime_spots.iter().last() { - introduce_suggestion.push(match &generics.params { - [] => (generics.span, "<'lifetime>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), - }); - } + let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_suggestion( + span, + "consider using the named lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + }; + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_label(span, "expected named lifetime parameter"); + + if let Some(generics) = missing_named_lifetime_spots.iter().last() { + let mut introduce_suggestion = vec![]; + introduce_suggestion.push(match &generics.params { + [] => (generics.span, "<'lifetime>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + }); + introduce_suggestion.push((span, sugg)); + err.multipart_suggestion( + "consider introducing a named lifetime parameter", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + }; match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { (1, Some(name), Some("&")) => { - err.span_suggestion( - span, - "consider using the named lifetime", - format!("&{} ", name), - Applicability::MaybeIncorrect, - ); + suggest_existing(err, format!("&{} ", name)); } (1, Some(name), Some("'_")) => { - err.span_suggestion( - span, - "consider using the named lifetime", - name.to_string(), - Applicability::MaybeIncorrect, - ); + suggest_existing(err, name.to_string()); } (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { - err.span_suggestion( - span, - "consider using the named lifetime", - format!("{}<{}>", snippet, name), - Applicability::MaybeIncorrect, - ); + suggest_existing(err, format!("{}<{}>", snippet, name)); } (0, _, Some("&")) => { - err.span_label(span, "expected named lifetime parameter"); - if !introduce_suggestion.is_empty() { - introduce_suggestion.push((span, "&'lifetime ".to_string())); - err.multipart_suggestion( - "consider introducing a named lifetime parameter", - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - } + suggest_new(err, "&'lifetime ".to_string()); } (0, _, Some("'_")) => { - err.span_label(span, "expected named lifetime parameter"); - if !introduce_suggestion.is_empty() { - introduce_suggestion.push((span, "'lifetime".to_string())); - err.multipart_suggestion( - "consider introducing a named lifetime parameter", - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - } + suggest_new(err, "'lifetime".to_string()); } (0, _, Some(snippet)) if !snippet.ends_with(">") => { - err.span_label(span, "expected named lifetime parameter"); - if !introduce_suggestion.is_empty() { - introduce_suggestion.push((span, format!("{}<'lifetime>", snippet))); - err.multipart_suggestion( - "consider introducing a named lifetime parameter", - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - } + suggest_new(err, format!("{}<'lifetime>", snippet)); } _ => { err.span_label(span, "expected lifetime parameter"); From 0a6b5538ad2bbe0eba55f35e120e896ef6c5c83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 17 Jan 2020 16:03:11 -0800 Subject: [PATCH 0497/1253] Deal with stabilization of `feature(slice_patterns)` --- src/librustc_resolve/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 29872be47c2f3..96406bc9a8c81 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -11,7 +11,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] pub use rustc_hir::def::{Namespace, PerNS}; From 03d7fed165a350c0b9acfbbaf76feae7014c97d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 17:48:47 -0800 Subject: [PATCH 0498/1253] review comments --- src/librustc_resolve/diagnostics.rs | 74 ++++++++++++++++++++++++- src/librustc_resolve/lifetimes.rs | 83 +++-------------------------- 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a433ae8ed676a..a85f787b67789 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -5,8 +5,9 @@ use rustc::bug; use rustc::session::Session; use rustc::ty::{self, DefIdTree}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; +use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -1447,3 +1448,74 @@ crate fn show_candidates( } } } + +crate fn report_missing_lifetime_specifiers( + sess: &Session, + span: Span, + count: usize, +) -> DiagnosticBuilder<'_> { + struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count)) +} + +crate fn add_missing_lifetime_specifiers_label( + err: &mut DiagnosticBuilder<'_>, + span: Span, + count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, + missing_named_lifetime_spots: &[&hir::Generics<'_>], +) { + if count > 1 { + err.span_label(span, format!("expected {} lifetime parameters", count)); + } else { + let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_suggestion( + span, + "consider using the named lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + }; + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_label(span, "expected named lifetime parameter"); + + if let Some(generics) = missing_named_lifetime_spots.iter().last() { + let mut introduce_suggestion = vec![]; + introduce_suggestion.push(match &generics.params { + [] => (generics.span, "<'lifetime>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + }); + introduce_suggestion.push((span, sugg)); + err.multipart_suggestion( + "consider introducing a named lifetime parameter", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + }; + + match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { + (1, Some(name), Some("&")) => { + suggest_existing(err, format!("&{} ", name)); + } + (1, Some(name), Some("'_")) => { + suggest_existing(err, name.to_string()); + } + (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { + suggest_existing(err, format!("{}<{}>", snippet, name)); + } + (0, _, Some("&")) => { + suggest_new(err, "&'lifetime ".to_string()); + } + (0, _, Some("'_")) => { + suggest_new(err, "'lifetime".to_string()); + } + (0, _, Some(snippet)) if !snippet.ends_with(">") => { + suggest_new(err, format!("{}<'lifetime>", snippet)); + } + _ => { + err.span_label(span, "expected lifetime parameter"); + } + } + } +} diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 528f5aaf034c7..1c667d1467de0 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -5,14 +5,16 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. +use crate::diagnostics::{ + add_missing_lifetime_specifiers_label, report_missing_lifetime_specifiers, +}; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::resolve_lifetime::*; -use rustc::session::Session; use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use rustc::{bug, span_bug}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; @@ -1320,9 +1322,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { where F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>), { - let LifetimeContext { tcx, map, lifetime_uses, missing_named_lifetime_spots, .. } = self; + let LifetimeContext { tcx, map, lifetime_uses, .. } = self; let labels_in_fn = take(&mut self.labels_in_fn); let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); + let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots); let mut this = LifetimeContext { tcx: *tcx, map: map, @@ -1332,7 +1335,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { labels_in_fn, xcrate_object_lifetime_defaults, lifetime_uses, - missing_named_lifetime_spots: missing_named_lifetime_spots.to_vec(), + missing_named_lifetime_spots, }; debug!("entering scope {:?}", this.scope); f(self.scope, &mut this); @@ -1340,6 +1343,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { debug!("exiting scope {:?}", this.scope); self.labels_in_fn = this.labels_in_fn; self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; + self.missing_named_lifetime_spots = this.missing_named_lifetime_spots; } /// helper method to determine the span to remove when suggesting the @@ -2894,74 +2898,3 @@ fn insert_late_bound_lifetimes( } } } - -fn report_missing_lifetime_specifiers( - sess: &Session, - span: Span, - count: usize, -) -> DiagnosticBuilder<'_> { - struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count)) -} - -fn add_missing_lifetime_specifiers_label( - err: &mut DiagnosticBuilder<'_>, - span: Span, - count: usize, - lifetime_names: &FxHashSet, - snippet: Option<&str>, - missing_named_lifetime_spots: &[&hir::Generics<'_>], -) { - if count > 1 { - err.span_label(span, format!("expected {} lifetime parameters", count)); - } else { - let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { - err.span_suggestion( - span, - "consider using the named lifetime", - sugg, - Applicability::MaybeIncorrect, - ); - }; - let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| { - err.span_label(span, "expected named lifetime parameter"); - - if let Some(generics) = missing_named_lifetime_spots.iter().last() { - let mut introduce_suggestion = vec![]; - introduce_suggestion.push(match &generics.params { - [] => (generics.span, "<'lifetime>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), - }); - introduce_suggestion.push((span, sugg)); - err.multipart_suggestion( - "consider introducing a named lifetime parameter", - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - } - }; - - match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { - (1, Some(name), Some("&")) => { - suggest_existing(err, format!("&{} ", name)); - } - (1, Some(name), Some("'_")) => { - suggest_existing(err, name.to_string()); - } - (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { - suggest_existing(err, format!("{}<{}>", snippet, name)); - } - (0, _, Some("&")) => { - suggest_new(err, "&'lifetime ".to_string()); - } - (0, _, Some("'_")) => { - suggest_new(err, "'lifetime".to_string()); - } - (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, format!("{}<'lifetime>", snippet)); - } - _ => { - err.span_label(span, "expected lifetime parameter"); - } - } - } -} From 2ce7b619952dade385f9f67fcc6f3003a90eefd7 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Jan 2020 18:31:56 -0800 Subject: [PATCH 0499/1253] Explain motivation for `GenKill` trait --- src/librustc_mir/dataflow/generic/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index 09ca72e75b651..897b95ea99602 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -3,10 +3,10 @@ //! There is another interface for dataflow in the compiler in `librustc_mir/dataflow/mod.rs`. The //! interface in this module will eventually [replace that one][design-meeting]. //! -//! To actually use this framework, you must implement either the `Analysis` or the -//! `GenKillAnalysis` trait. If your transfer function can be expressed with only gen/kill -//! operations, prefer `GenKillAnalysis` as it will perform better. Create an `Engine` using the -//! appropriate constructor and call `iterate_to_fixpoint`. You can use a `ResultsCursor` to +//! To actually use this framework, you must implement either the `Analysis` or the `GenKillAnalysis` +//! trait. If your transfer function can be expressed with only gen/kill operations, prefer +//! `GenKillAnalysis` since it will run faster while iterating to fixpoint. Create an `Engine` using +//! the appropriate constructor and call `iterate_to_fixpoint`. You can use a `ResultsCursor` to //! inspect the fixpoint solution to your dataflow problem. //! //! ```ignore(cross-crate-imports) @@ -273,6 +273,14 @@ where } /// The legal operations for a transfer function in a gen/kill problem. +/// +/// This abstraction exists because there are two different contexts in which we call the methods in +/// `GenKillAnalysis`. Sometimes we need to store a single transfer function that can be efficiently +/// applied multiple times, such as when computing the cumulative transfer function for each block. +/// These cases require a `GenKillSet`, which in turn requires two `BitSet`s of storage. Oftentimes, +/// however, we only need to apply an effect once. In *these* cases, it is more efficient to pass the +/// `BitSet` representing the state vector directly into the `*_effect` methods as opposed to +/// building up a `GenKillSet` and then throwing it away. pub trait GenKill { /// Inserts `elem` into the state vector. fn gen(&mut self, elem: T); From 7b4dca282a0bfad265238d04b22f7bdb0d498d74 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Jan 2020 18:47:29 -0800 Subject: [PATCH 0500/1253] Document all methods --- src/librustc_mir/dataflow/generic/engine.rs | 6 ++++++ src/librustc_mir/dataflow/generic/mod.rs | 10 +++++++--- src/librustc_mir/dataflow/generic/tests.rs | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/engine.rs b/src/librustc_mir/dataflow/generic/engine.rs index 3322177006666..c0152b0c7d504 100644 --- a/src/librustc_mir/dataflow/generic/engine.rs +++ b/src/librustc_mir/dataflow/generic/engine.rs @@ -121,11 +121,17 @@ where } } + /// Signals that we do not want dataflow state to propagate across unwind edges for these + /// `BasicBlock`s. + /// + /// You must take care that `dead_unwinds` does not contain a `BasicBlock` that *can* actually + /// unwind during execution. Otherwise, your dataflow results will not be correct. pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet) -> Self { self.dead_unwinds = Some(dead_unwinds); self } + /// Computes the fixpoint for this dataflow problem and returns it. pub fn iterate_to_fixpoint(mut self) -> Results<'tcx, A> { let mut temp_state = BitSet::new_empty(self.bits_per_block); diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index 897b95ea99602..c9b4f875ebdf8 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -60,11 +60,13 @@ impl Results<'tcx, A> where A: Analysis<'tcx>, { - pub fn into_cursor(self, body: &'mir mir::Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> { + /// Creates a `ResultsCursor` that can inspect these `Results`. + pub fn into_results_cursor(self, body: &'mir mir::Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> { ResultsCursor::new(body, self) } - pub fn on_block_entry(&self, block: BasicBlock) -> &BitSet { + /// Gets the entry set for the given block. + pub fn entry_set_for_block(&self, block: BasicBlock) -> &BitSet { &self.entry_sets[block] } } @@ -288,12 +290,14 @@ pub trait GenKill { /// Removes `elem` from the state vector. fn kill(&mut self, elem: T); + /// Calls `gen` for each element in `elems`. fn gen_all(&mut self, elems: impl IntoIterator) { for elem in elems { self.gen(elem); } } + /// Calls `kill` for each element in `elems`. fn kill_all(&mut self, elems: impl IntoIterator) { for elem in elems { self.kill(elem); @@ -304,7 +308,7 @@ pub trait GenKill { /// Stores a transfer function for a gen/kill problem. /// /// Calling `gen`/`kill` on a `GenKillSet` will "build up" a transfer function so that it can be -/// applied to a state vector efficiently. When there are multiple calls to `gen` and/or `kill` for +/// applied multiple times efficiently. When there are multiple calls to `gen` and/or `kill` for /// the same element, the most recent one takes precedence. #[derive(Clone)] pub struct GenKillSet { diff --git a/src/librustc_mir/dataflow/generic/tests.rs b/src/librustc_mir/dataflow/generic/tests.rs index cc339cf8ce955..50d4bdb67f755 100644 --- a/src/librustc_mir/dataflow/generic/tests.rs +++ b/src/librustc_mir/dataflow/generic/tests.rs @@ -276,7 +276,8 @@ fn cursor_seek() { let body = &body; let analysis = MockAnalysis { body }; - let mut cursor = Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_cursor(body); + let mut cursor = + Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_results_cursor(body); // Sanity check: the mock call return effect is unique and actually being applied. let call_terminator_loc = Location { block: BasicBlock::from_usize(2), statement_index: 2 }; From 01cbe506f99aa484f583a7affb65d15a839d2412 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:23 -0800 Subject: [PATCH 0501/1253] Add `constness` field to `ast::ItemKind::Impl` --- src/librustc_ast_lowering/item.rs | 6 +++--- src/librustc_ast_passes/ast_validation.rs | 2 ++ src/librustc_builtin_macros/deriving/generic/mod.rs | 1 + src/librustc_builtin_macros/deriving/mod.rs | 1 + src/librustc_parse/parser/item.rs | 2 ++ src/librustc_save_analysis/sig.rs | 4 ++++ src/libsyntax/ast.rs | 1 + src/libsyntax/mut_visit.rs | 1 + src/libsyntax/print/pprust.rs | 9 +++++++++ src/libsyntax/visit.rs | 1 + 10 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 6da2d457f3c3b..170968e71fb35 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -67,9 +67,8 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { if let Some(hir_id) = item_hir_id { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl { ref of_trait, .. } = item.kind { - if of_trait.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { - this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); + if let ItemKind::Impl { constness, ref of_trait, .. } = item.kind { + if constness == Constness::Const { this.lctx .diagnostic() .span_err(item.span, "const trait impls are not yet implemented"); @@ -366,6 +365,7 @@ impl<'hir> LoweringContext<'_, 'hir> { unsafety, polarity, defaultness, + constness: _, // TODO generics: ref ast_generics, of_trait: ref trait_ref, self_ty: ref ty, diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 23701459025ae..23d2858a49966 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -616,6 +616,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { unsafety, polarity, defaultness: _, + constness: _, // TODO generics: _, of_trait: Some(_), ref self_ty, @@ -649,6 +650,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { unsafety, polarity, defaultness, + constness: _, // TODO generics: _, of_trait: None, self_ty: _, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index d346dbc8b4ee7..f8918016c1b98 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -709,6 +709,7 @@ impl<'a> TraitDef<'a> { unsafety, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, + constness: ast::Constness::NotConst, generics: trait_generics, of_trait: opt_trait_ref, self_ty: self_type, diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 9aa7623dc9f77..914dcdf196921 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -160,6 +160,7 @@ fn inject_impl_of_structural_trait( unsafety: ast::Unsafety::Normal, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, + constness: ast::Constness::NotConst, generics, of_trait: Some(trait_ref), self_ty: self_type, diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 1921a6c850689..e4982896376d6 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -638,6 +638,7 @@ impl<'a> Parser<'a> { unsafety, polarity, defaultness, + constness, generics, of_trait: Some(trait_ref), self_ty: ty_second, @@ -657,6 +658,7 @@ impl<'a> Parser<'a> { unsafety, polarity, defaultness, + constness, generics, of_trait: None, self_ty: ty_first, diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 779d3f55018d5..a9d2bfabb1ba6 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -486,6 +486,7 @@ impl Sig for ast::Item { unsafety, polarity, defaultness, + constness, ref generics, ref of_trait, ref self_ty, @@ -499,6 +500,9 @@ impl Sig for ast::Item { text.push_str("unsafe "); } text.push_str("impl"); + if constness == ast::Constness::Const { + text.push_str(" const"); + } let generics_sig = generics.make(offset + text.len(), id, scx)?; text.push_str(&generics_sig.text); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a5a4eb1583bed..6b54893075e7b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2618,6 +2618,7 @@ pub enum ItemKind { unsafety: Unsafety, polarity: ImplPolarity, defaultness: Defaultness, + constness: Constness, generics: Generics, /// The trait being implemented, if any. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 750d054e8a0f2..8f82ff6b040a6 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -922,6 +922,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { unsafety: _, polarity: _, defaultness: _, + constness: _, generics, of_trait, self_ty, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bc67980c454c0..3927e4f903011 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1230,6 +1230,7 @@ impl<'a> State<'a> { unsafety, polarity, defaultness, + constness, ref generics, ref of_trait, ref self_ty, @@ -1240,6 +1241,7 @@ impl<'a> State<'a> { self.print_defaultness(defaultness); self.print_unsafety(unsafety); self.word_nbsp("impl"); + self.print_constness(constness); if !generics.params.is_empty() { self.print_generic_params(&generics.params); @@ -2773,6 +2775,13 @@ impl<'a> State<'a> { } } + crate fn print_constness(&mut self, s: ast::Constness) { + match s { + ast::Constness::Const => self.word_nbsp("const"), + ast::Constness::NotConst => {} + } + } + crate fn print_is_auto(&mut self, s: ast::IsAuto) { match s { ast::IsAuto::Yes => self.word_nbsp("auto"), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d03a9dfc16758..946a0d29cd399 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -312,6 +312,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { unsafety: _, polarity: _, defaultness: _, + constness: _, ref generics, ref of_trait, ref self_ty, From a790f9bb2d277b5c7c267b15b812db12cc20b7a1 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:24 -0800 Subject: [PATCH 0502/1253] Add `constness` field to `hir::ItemKind::Impl` --- src/librustc_ast_lowering/item.rs | 3 ++- src/librustc_hir/hir.rs | 1 + src/librustc_hir/intravisit.rs | 1 + src/librustc_hir/print.rs | 5 +++++ src/librustdoc/doctree.rs | 1 + src/librustdoc/visit_ast.rs | 2 ++ 6 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 170968e71fb35..c47a0f4eaca6c 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -365,7 +365,7 @@ impl<'hir> LoweringContext<'_, 'hir> { unsafety, polarity, defaultness, - constness: _, // TODO + constness, generics: ref ast_generics, of_trait: ref trait_ref, self_ty: ref ty, @@ -422,6 +422,7 @@ impl<'hir> LoweringContext<'_, 'hir> { unsafety, polarity, defaultness: self.lower_defaultness(defaultness, true /* [1] */), + constness, generics, of_trait: trait_ref, self_ty: lowered_ty, diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 1fef871b5140e..d850cfe69cebe 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2440,6 +2440,7 @@ pub enum ItemKind<'hir> { unsafety: Unsafety, polarity: ImplPolarity, defaultness: Defaultness, + constness: Constness, generics: Generics<'hir>, /// The trait being implemented, if any. diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 1a73e41db9da5..539a0eee0e312 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -570,6 +570,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { unsafety: _, defaultness: _, polarity: _, + constness: _, ref generics, ref of_trait, ref self_ty, diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 6c7d419395317..b9598c9376146 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -631,6 +631,7 @@ impl<'a> State<'a> { unsafety, polarity, defaultness, + constness, ref generics, ref of_trait, ref self_ty, @@ -647,6 +648,10 @@ impl<'a> State<'a> { self.s.space(); } + if constness == ast::Constness::Const { + self.word_nbsp("const"); + } + if let hir::ImplPolarity::Negative = polarity { self.s.word("!"); } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 178ba69277233..218674b757f39 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -203,6 +203,7 @@ pub struct Impl<'hir> { pub unsafety: hir::Unsafety, pub polarity: hir::ImplPolarity, pub defaultness: hir::Defaultness, + pub constness: ast::Constness, pub generics: &'hir hir::Generics<'hir>, pub trait_: &'hir Option>, pub for_: &'hir hir::Ty<'hir>, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index fdff18779e795..d3d45ccccad36 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -562,6 +562,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { unsafety, polarity, defaultness, + constness, ref generics, ref of_trait, self_ty, @@ -576,6 +577,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { unsafety, polarity, defaultness, + constness, generics, trait_: of_trait, for_: self_ty, From 958b0bc8d22633927796502b13a7ce944100dec5 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:25 -0800 Subject: [PATCH 0503/1253] Store `impl const` in `ItemKind::Impl` --- src/librustc_ast_passes/ast_validation.rs | 10 ++++++++-- src/librustc_parse/parser/item.rs | 16 ++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 23d2858a49966..7dbd2362f04c9 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -616,7 +616,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { unsafety, polarity, defaultness: _, - constness: _, // TODO + constness: _, generics: _, of_trait: Some(_), ref self_ty, @@ -650,7 +650,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { unsafety, polarity, defaultness, - constness: _, // TODO + constness, generics: _, of_trait: None, self_ty: _, @@ -678,6 +678,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .note("only trait implementations may be annotated with default") .emit(); } + if constness == Constness::Const { + self.err_handler() + .struct_span_err(item.span, "inherent impls cannot be `const`") + .note("only trait implementations may be annotated with `const`") + .emit(); + } } ItemKind::Fn(ref sig, ref generics, _) => { self.visit_fn_header(&sig.header); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index e4982896376d6..43495da192839 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -5,7 +5,7 @@ use crate::maybe_whole; use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey}; -use rustc_span::source_map::{self, respan, Span, Spanned}; +use rustc_span::source_map::{self, respan, Span}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::BytePos; use syntax::ast::{self, AttrKind, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; @@ -566,9 +566,9 @@ impl<'a> Parser<'a> { let constness = if self.eat_keyword(kw::Const) { let span = self.prev_span; self.sess.gated_spans.gate(sym::const_trait_impl, span); - Some(respan(span, Constness::Const)) + Constness::Const } else { - None + Constness::NotConst }; // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. @@ -631,8 +631,7 @@ impl<'a> Parser<'a> { err_path(ty_first.span) } }; - let constness = constness.map(|c| c.node); - let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; + let trait_ref = TraitRef { path, ref_id: ty_first.id }; ItemKind::Impl { unsafety, @@ -646,13 +645,6 @@ impl<'a> Parser<'a> { } } None => { - // Reject `impl const Type {}` here - if let Some(Spanned { node: Constness::Const, span }) = constness { - self.struct_span_err(span, "`const` cannot modify an inherent impl") - .help("only a trait impl can be `const`") - .emit(); - } - // impl Type ItemKind::Impl { unsafety, From eb60346cc99bde574708fe2e419898044868c1f8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:27 -0800 Subject: [PATCH 0504/1253] Add `MaybeConst` variant to `{ast,hir}::TraitBoundModifier` --- src/librustc_ast_lowering/lib.rs | 8 +++--- src/librustc_ast_passes/ast_validation.rs | 20 +++----------- src/librustc_hir/hir.rs | 1 + src/librustc_parse/parser/ty.rs | 33 ++++++++++++++++------- src/librustdoc/html/format.rs | 1 + src/libsyntax/ast.rs | 11 ++++++-- 6 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 76a0889c376a2..90560c371e292 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1250,7 +1250,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bounds = this.arena.alloc_from_iter(bounds.iter().filter_map( |bound| match *bound { - GenericBound::Trait(ref ty, TraitBoundModifier::None) => { + GenericBound::Trait(ref ty, TraitBoundModifier::None) + | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => { Some(this.lower_poly_trait_ref(ty, itctx.reborrow())) } GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, @@ -2158,10 +2159,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &PolyTraitRef, mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::PolyTraitRef<'hir> { - if p.trait_ref.constness.is_some() { - self.diagnostic().span_err(p.span, "`?const` on trait bounds is not yet implemented"); - } - let bound_generic_params = self.lower_generic_params( &p.bound_generic_params, &NodeMap::default(), @@ -2301,6 +2298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match f { TraitBoundModifier::None => hir::TraitBoundModifier::None, TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst, } } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 7dbd2362f04c9..23cb97348339d 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -917,22 +917,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_param_bound(&mut self, bound: &'a GenericBound) { - if let GenericBound::Trait(poly, maybe_bound) = bound { - match poly.trait_ref.constness { - Some(Constness::NotConst) => { - if *maybe_bound == TraitBoundModifier::Maybe { - self.err_handler() - .span_err(bound.span(), "`?const` and `?` are mutually exclusive"); - } - - if let Some(ctx) = self.bound_context { - let msg = format!("`?const` is not permitted in {}", ctx.description()); - self.err_handler().span_err(bound.span(), &msg); - } - } - - Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"), - None => {} + if let GenericBound::Trait(_, TraitBoundModifier::MaybeConst) = bound { + if let Some(ctx) = self.bound_context { + let msg = format!("`?const` is not permitted in {}", ctx.description()); + self.err_handler().span_err(bound.span(), &msg); } } diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index d850cfe69cebe..b62a7e413e303 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -364,6 +364,7 @@ impl GenericArgs<'_> { pub enum TraitBoundModifier { None, Maybe, + MaybeConst, } /// The AST represents all type param bounds as types. diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 065a3b14428c7..9c9180778e522 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -27,11 +27,17 @@ struct BoundModifiers { } impl BoundModifiers { - fn trait_bound_modifier(&self) -> TraitBoundModifier { - match self.maybe { - Some(_) => TraitBoundModifier::Maybe, - None => TraitBoundModifier::None, - } + fn to_trait_bound_modifier(&self) -> Result { + let modifier = match (self.maybe, self.maybe_const) { + (None, None) => TraitBoundModifier::None, + (Some(_), None) => TraitBoundModifier::Maybe, + (None, Some(_)) => TraitBoundModifier::MaybeConst, + (Some(_), Some(_)) => { + return Err("`?const` and `?` are mutually exclusive"); + } + }; + + Ok(modifier) } } @@ -215,7 +221,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, TyKind> { assert_ne!(self.token, token::Question); - let poly_trait_ref = PolyTraitRef::new(generic_params, path, None, lo.to(self.prev_span)); + let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span)); let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; if parse_plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded @@ -557,9 +563,18 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; } - let constness = modifiers.maybe_const.map(|_| ast::Constness::NotConst); - let poly_trait = PolyTraitRef::new(lifetime_defs, path, constness, lo.to(self.prev_span)); - Ok(GenericBound::Trait(poly_trait, modifiers.trait_bound_modifier())) + let modifier = match modifiers.to_trait_bound_modifier() { + Ok(m) => m, + Err(msg) => { + self.struct_span_err(lo.to(self.prev_span), msg).emit(); + + // Continue compilation as if the user had written `?Trait`. + TraitBoundModifier::Maybe + } + }; + + let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span)); + Ok(GenericBound::Trait(poly_trait, modifier)) } /// Optionally parses `for<$generic_params>`. diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6434dccdfc75b..79923fc3d3689 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -361,6 +361,7 @@ impl clean::GenericBound { let modifier_str = match modifier { hir::TraitBoundModifier::None => "", hir::TraitBoundModifier::Maybe => "?", + hir::TraitBoundModifier::MaybeConst => "?const", }; if f.alternate() { write!(f, "{}{:#}", modifier_str, ty.print()) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 6b54893075e7b..ce4d9cca81eb3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -266,12 +266,19 @@ pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0); /// small, positive ids. pub const DUMMY_NODE_ID: NodeId = NodeId::MAX; -/// A modifier on a bound, currently this is only used for `?Sized`, where the -/// modifier is `Maybe`. Negative bounds should also be handled here. +/// A modifier on a bound, e.g., `?Sized` or `?const Trait`. +/// +/// Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] pub enum TraitBoundModifier { + /// No modifiers None, + + /// `?Trait` Maybe, + + /// `?const Trait` + MaybeConst, } /// The AST represents all type param bounds as types. From 1a3bd5775f8b8a1354ec703acf3a3a07e5f8b7c2 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:29 -0800 Subject: [PATCH 0505/1253] Revert "Add a `constness` field to `ast::TraitRef`" This reverts commit fd4a6a12136c5b5d6bce4081e95890df1fd1febd. --- src/librustc_expand/build.rs | 2 +- src/libsyntax/ast.rs | 20 +++----------------- src/libsyntax/mut_visit.rs | 3 +-- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index bd3d6b589d00a..11f94ab2e6279 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -110,7 +110,7 @@ impl<'a> ExtCtxt<'a> { } pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { - ast::TraitRef { path, constness: None, ref_id: ast::DUMMY_NODE_ID } + ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } } pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ce4d9cca81eb3..7c2608a0c2a31 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1040,7 +1040,7 @@ impl Expr { pub fn to_bound(&self) -> Option { match &self.kind { ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(Vec::new(), path.clone(), None, self.span), + PolyTraitRef::new(Vec::new(), path.clone(), self.span), TraitBoundModifier::None, )), _ => None, @@ -2383,15 +2383,6 @@ pub enum AttrKind { pub struct TraitRef { pub path: Path, pub ref_id: NodeId, - - /// The `const` modifier, if any, that appears before this trait. - /// - /// | | `constness` | - /// |----------------|-----------------------------| - /// | `Trait` | `None` | - /// | `const Trait` | `Some(Constness::Const)` | - /// | `?const Trait` | `Some(Constness::NotConst)` | - pub constness: Option, } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2406,15 +2397,10 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new( - generic_params: Vec, - path: Path, - constness: Option, - span: Span, - ) -> Self { + pub fn new(generic_params: Vec, path: Path, span: Span) -> Self { PolyTraitRef { bound_generic_params: generic_params, - trait_ref: TraitRef { path, constness, ref_id: DUMMY_NODE_ID }, + trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, span, } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 8f82ff6b040a6..4a460c5d7b24c 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -838,8 +838,7 @@ pub fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut } } -pub fn noop_visit_trait_ref(tr: &mut TraitRef, vis: &mut T) { - let TraitRef { path, ref_id, constness: _ } = tr; +pub fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { vis.visit_path(path); vis.visit_id(ref_id); } From ab3081a70e5d402188c26c6f3e671a3c44812d1b Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:31 -0800 Subject: [PATCH 0506/1253] Add `constness` field to `ty::Predicate::Trait` --- src/librustc/traits/auto_trait.rs | 9 +++++--- src/librustc/traits/fulfill.rs | 2 +- src/librustc/traits/object_safety.rs | 4 ++-- .../traits/query/type_op/prove_predicate.rs | 2 +- src/librustc/traits/select.rs | 10 +++++---- src/librustc/traits/util.rs | 8 +++---- src/librustc/traits/wf.rs | 4 ++-- src/librustc/ty/fold.rs | 9 ++++++++ src/librustc/ty/mod.rs | 21 ++++++++++++------- src/librustc/ty/print/pretty.rs | 7 ++++++- src/librustc/ty/structural_impls.rs | 12 +++++++++-- src/librustc_lint/unused.rs | 2 +- .../borrow_check/type_check/mod.rs | 21 ++++++++++++------- .../transform/qualify_min_const_fn.rs | 11 ++++++++-- src/librustc_privacy/lib.rs | 2 +- src/librustc_traits/lowering/mod.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 8 +++---- src/librustc_typeck/collect.rs | 4 ++-- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/simplify.rs | 2 +- src/libsyntax/ast.rs | 3 ++- 27 files changed, 104 insertions(+), 55 deletions(-) diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 89b28aeda1c5e..c97c5c2077f85 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -337,7 +337,10 @@ impl AutoTraitFinder<'tcx> { &Err(SelectionError::Unimplemented) => { if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) { already_visited.remove(&pred); - self.add_user_pred(&mut user_computed_preds, ty::Predicate::Trait(pred)); + self.add_user_pred( + &mut user_computed_preds, + ty::Predicate::Trait(pred, ast::Constness::NotConst), + ); predicates.push_back(pred); } else { debug!( @@ -405,7 +408,7 @@ impl AutoTraitFinder<'tcx> { let mut should_add_new = true; user_computed_preds.retain(|&old_pred| { match (&new_pred, old_pred) { - (&ty::Predicate::Trait(new_trait), ty::Predicate::Trait(old_trait)) => { + (&ty::Predicate::Trait(new_trait, _), ty::Predicate::Trait(old_trait, _)) => { if new_trait.def_id() == old_trait.def_id() { let new_substs = new_trait.skip_binder().trait_ref.substs; let old_substs = old_trait.skip_binder().trait_ref.substs; @@ -627,7 +630,7 @@ impl AutoTraitFinder<'tcx> { // We check this by calling is_of_param on the relevant types // from the various possible predicates match &predicate { - &ty::Predicate::Trait(p) => { + &ty::Predicate::Trait(p, _) => { if self.is_param_no_infer(p.skip_binder().trait_ref.substs) && !only_projections && is_new_pred diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 9e5abc80822c7..1dbf53003585f 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -331,7 +331,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } match obligation.predicate { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { let trait_obligation = obligation.with(data.clone()); if data.is_global() { diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ce57fb8110496..ad6b821b1d771 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -234,7 +234,7 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o .map(|(predicate, _)| predicate.subst_supertrait(tcx, &trait_ref)) .any(|predicate| { match predicate { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { // In the case of a trait predicate, we can skip the "self" type. data.skip_binder().input_types().skip(1).any(has_self_ty) } @@ -285,7 +285,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let predicates = tcx.predicates_of(def_id); let predicates = predicates.instantiate_identity(tcx).predicates; elaborate_predicates(tcx, predicates).any(|predicate| match predicate { - ty::Predicate::Trait(ref trait_pred) => { + ty::Predicate::Trait(ref trait_pred, _) => { trait_pred.def_id() == sized_def_id && trait_pred.skip_binder().self_ty().is_param(0) } ty::Predicate::Projection(..) diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index c0a0cbe9a3876..15870ec95d8d2 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -24,7 +24,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { // `&T`, accounts for about 60% percentage of the predicates // we have to prove. No need to canonicalize and all that for // such cases. - if let Predicate::Trait(trait_ref) = key.value.predicate { + if let Predicate::Trait(trait_ref, _) = key.value.predicate { if let Some(sized_def_id) = tcx.lang_items().sized_trait() { if trait_ref.def_id() == sized_def_id { if trait_ref.skip_binder().self_ty().is_trivially_sized(tcx) { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 3bfe542baabbf..9db907e88fab8 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -51,7 +51,7 @@ use std::cmp; use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; -use syntax::attr; +use syntax::{ast, attr}; pub struct SelectionContext<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, @@ -718,7 +718,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match obligation.predicate { - ty::Predicate::Trait(ref t) => { + ty::Predicate::Trait(ref t, _) => { debug_assert!(!t.has_escaping_bound_vars()); let obligation = obligation.with(t.clone()); self.evaluate_trait_predicate_recursively(previous_stack, obligation) @@ -945,7 +945,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // trait refs. This is important because it's only a cycle // if the regions match exactly. let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth); - let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate)); + let cycle = cycle.map(|stack| { + ty::Predicate::Trait(stack.obligation.predicate, ast::Constness::NotConst) + }); if self.coinductive_match(cycle) { debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref); Some(EvaluatedToOk) @@ -1060,7 +1062,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool { let result = match predicate { - ty::Predicate::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()), + ty::Predicate::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()), _ => false, }; debug!("coinductive_predicate({:?}) = {:?}", predicate, result); diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index f058a4d2df24a..a5a16a1471225 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -13,8 +13,8 @@ use super::{Normalized, Obligation, ObligationCause, PredicateObligation, Select fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { match *pred { - ty::Predicate::Trait(ref data) => { - ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)) + ty::Predicate::Trait(ref data, constness) => { + ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness) } ty::Predicate::RegionOutlives(ref data) => { @@ -127,7 +127,7 @@ impl Elaborator<'tcx> { fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) { let tcx = self.visited.tcx; match *predicate { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); @@ -471,7 +471,7 @@ impl<'tcx, I: Iterator>> Iterator for FilterToTraits< fn next(&mut self) -> Option> { while let Some(pred) = self.base_iterator.next() { - if let ty::Predicate::Trait(data) = pred { + if let ty::Predicate::Trait(data, _) = pred { return Some(data.to_poly_trait_ref()); } } diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 869ba5315c1ae..aba09c3c81850 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -62,7 +62,7 @@ pub fn predicate_obligations<'a, 'tcx>( // (*) ok to skip binders, because wf code is prepared for it match *predicate { - ty::Predicate::Trait(ref t) => { + ty::Predicate::Trait(ref t, _) => { wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*) } ty::Predicate::RegionOutlives(..) => {} @@ -245,7 +245,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } } - ty::Predicate::Trait(proj) => { + ty::Predicate::Trait(proj, _) => { // An associated item obligation born out of the `trait` failed to be met. // Point at the `impl` that failed the obligation, the associated item that // needed to meet the obligation, and the definition of that associated item, diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index b16db6ae5b18d..0dddca98c6257 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -150,6 +150,15 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } } +impl TypeFoldable<'tcx> for syntax::ast::Constness { + fn super_fold_with>(&self, _: &mut F) -> Self { + *self + } + fn super_visit_with>(&self, _: &mut V) -> bool { + false + } +} + /// The `TypeFolder` trait defines the actual *folding*. There is a /// method defined for every foldable type. Each of these has a /// default implementation that does an "identity" fold. Within each diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3040ecf90ed53..c5fbf2896a4a1 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1068,7 +1068,11 @@ pub enum Predicate<'tcx> { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// the `Self` type of the trait reference and `A`, `B`, and `C` /// would be the type parameters. - Trait(PolyTraitPredicate<'tcx>), + /// + /// A trait predicate will have `Constness::Const` if it originates + /// from a bound on a `const fn` without the `?const` opt-out (e.g., + /// `const fn foobar() {}`). + Trait(PolyTraitPredicate<'tcx>, ast::Constness), /// `where 'a: 'b` RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), @@ -1191,8 +1195,8 @@ impl<'tcx> Predicate<'tcx> { let substs = &trait_ref.skip_binder().substs; match *self { - Predicate::Trait(ref binder) => { - Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs))) + Predicate::Trait(ref binder, constness) => { + Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)), constness) } Predicate::Subtype(ref binder) => { Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs))) @@ -1338,13 +1342,16 @@ pub trait ToPredicate<'tcx> { impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { fn to_predicate(&self) -> Predicate<'tcx> { - ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() })) + ty::Predicate::Trait( + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }), + ast::Constness::NotConst, + ) } } impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { fn to_predicate(&self) -> Predicate<'tcx> { - ty::Predicate::Trait(self.to_poly_trait_predicate()) + ty::Predicate::Trait(self.to_poly_trait_predicate(), ast::Constness::NotConst) } } @@ -1413,7 +1420,7 @@ impl<'tcx> Predicate<'tcx> { /// with depth 0 are bound by the predicate. pub fn walk_tys(&'a self) -> impl Iterator> + 'a { match *self { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { WalkTysIter::InputTypes(data.skip_binder().input_types()) } ty::Predicate::Subtype(binder) => { @@ -1439,7 +1446,7 @@ impl<'tcx> Predicate<'tcx> { pub fn to_opt_poly_trait_ref(&self) -> Option> { match *self { - Predicate::Trait(ref t) => Some(t.to_poly_trait_ref()), + Predicate::Trait(ref t, _) => Some(t.to_poly_trait_ref()), Predicate::Projection(..) | Predicate::Subtype(..) | Predicate::RegionOutlives(..) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 8b1b2bb586597..9091de55b7d8e 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1791,7 +1791,12 @@ define_print_and_forward_display! { ty::Predicate<'tcx> { match *self { - ty::Predicate::Trait(ref data) => p!(print(data)), + ty::Predicate::Trait(ref data, constness) => { + if let ast::Constness::Const = constness { + p!(write("const ")); + } + p!(print(data)) + } ty::Predicate::Subtype(ref predicate) => p!(print(predicate)), ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)), ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)), diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 62e895af7f355..25f9dc5b0c7bf 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -15,6 +15,7 @@ use smallvec::SmallVec; use std::fmt; use std::rc::Rc; use std::sync::Arc; +use syntax::ast; impl fmt::Debug for ty::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -234,7 +235,12 @@ impl fmt::Debug for ty::ProjectionPredicate<'tcx> { impl fmt::Debug for ty::Predicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - ty::Predicate::Trait(ref a) => a.fmt(f), + ty::Predicate::Trait(ref a, constness) => { + if let ast::Constness::Const = constness { + write!(f, "const ")?; + } + a.fmt(f) + } ty::Predicate::Subtype(ref pair) => pair.fmt(f), ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f), ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f), @@ -474,7 +480,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> { type Lifted = ty::Predicate<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::Predicate::Trait(ref binder) => tcx.lift(binder).map(ty::Predicate::Trait), + ty::Predicate::Trait(ref binder, constness) => { + tcx.lift(binder).map(|binder| ty::Predicate::Trait(binder, constness)) + } ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype), ty::Predicate::RegionOutlives(ref binder) => { tcx.lift(binder).map(ty::Predicate::RegionOutlives) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 26cbda3d97895..15158c09af074 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in cx.tcx.predicates_of(def).predicates { - if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { + if let ty::Predicate::Trait(ref poly_trait_predicate, _) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; let descr_pre = diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 947bbef4379f5..8f00801eb25a3 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -33,6 +33,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::{Span, DUMMY_SP}; +use syntax::ast; use crate::dataflow::move_paths::MoveData; use crate::dataflow::FlowAtLocation; @@ -1931,12 +1932,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { traits::ObligationCauseCode::RepeatVec(should_suggest), ), self.param_env, - ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new( - self.tcx().lang_items().copy_trait().unwrap(), - tcx.mk_substs_trait(ty, &[]), - ), - })), + ty::Predicate::Trait( + ty::Binder::bind(ty::TraitPredicate { + trait_ref: ty::TraitRef::new( + self.tcx().lang_items().copy_trait().unwrap(), + tcx.mk_substs_trait(ty, &[]), + ), + }), + ast::Constness::NotConst, + ), ), &traits::SelectionError::Unimplemented, false, @@ -2574,7 +2578,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { category: ConstraintCategory, ) { self.prove_predicates( - Some(ty::Predicate::Trait(trait_ref.to_poly_trait_ref().to_poly_trait_predicate())), + Some(ty::Predicate::Trait( + trait_ref.to_poly_trait_ref().to_poly_trait_predicate(), + ast::Constness::NotConst, + )), locations, category, ); diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index d927553c72e8b..b047e534e4f1c 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use std::borrow::Cow; -use syntax::attr; +use syntax::{ast, attr}; type McfResult = Result<(), (Span, Cow<'static, str>)>; @@ -27,12 +27,19 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) - bug!("closure kind predicate on function: {:#?}", predicate) } Predicate::Subtype(_) => bug!("subtype predicate on function: {:#?}", predicate), - Predicate::Trait(pred) => { + Predicate::Trait(pred, constness) => { if Some(pred.def_id()) == tcx.lang_items().sized_trait() { continue; } match pred.skip_binder().self_ty().kind { ty::Param(ref p) => { + // Allow `T: ?const Trait` + if *constness == ast::Constness::NotConst + && feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out) + { + continue; + } + let generics = tcx.generics_of(current); let def = generics.type_param(p, tcx); let span = tcx.def_span(def.def_id); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 90a422a4dcf6c..4b2e90ed83de2 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -93,7 +93,7 @@ where let ty::GenericPredicates { parent: _, predicates } = predicates; for (predicate, _span) in predicates { match predicate { - ty::Predicate::Trait(poly_predicate) => { + ty::Predicate::Trait(poly_predicate, _) => { let ty::TraitPredicate { trait_ref } = *poly_predicate.skip_binder(); if self.visit_trait(trait_ref) { return true; diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 4b4fa4b7147fc..b77c603da9a74 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -94,7 +94,7 @@ impl<'tcx> Lower> for ty::Predicate<'tcx> { use rustc::ty::Predicate; match self { - Predicate::Trait(predicate) => predicate.lower(), + Predicate::Trait(predicate, _) => predicate.lower(), Predicate::RegionOutlives(predicate) => predicate.lower(), Predicate::TypeOutlives(predicate) => predicate.lower(), Predicate::Projection(predicate) => predicate.lower(), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 173bb29e964d1..7f196b2c4d352 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1490,7 +1490,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref ); match trait_ref { - ty::Predicate::Trait(pred) => { + ty::Predicate::Trait(pred, constness) => { associated_types.entry(span).or_default().extend( tcx.associated_items(pred.def_id()) .filter(|item| item.kind == ty::AssocKind::Type) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a32fbff7bfe2d..087b720a2f4c4 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -565,7 +565,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let obligation = queue.remove(0); debug!("coerce_unsized resolve step: {:?}", obligation); let trait_ref = match obligation.predicate { - ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => { + ty::Predicate::Trait(ref tr, _) if traits.contains(&tr.def_id()) => { if unsize_did == tr.def_id() { let sty = &tr.skip_binder().input_types().nth(1).unwrap().kind; if let ty::Tuple(..) = sty { diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 88e7a265ebbcf..a88dca008d751 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -234,7 +234,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let predicate_matches_closure = |p: &'_ Predicate<'tcx>| { let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env); match (predicate, p) { - (Predicate::Trait(a), Predicate::Trait(b)) => relator.relate(a, b).is_ok(), + (Predicate::Trait(a, _), Predicate::Trait(b, _)) => relator.relate(a, b).is_ok(), (Predicate::Projection(a), Predicate::Projection(b)) => { relator.relate(a, b).is_ok() } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 636ea5b87d659..2012a2a1526b1 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -569,7 +569,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { traits::elaborate_predicates(self.tcx, predicates.predicates.clone()) .filter_map(|predicate| match predicate { - ty::Predicate::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => { + ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { Some(trait_pred) } _ => None, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index b2542cc27a551..67526bb70d125 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -826,7 +826,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // FIXME: do we want to commit to this behavior for param bounds? let bounds = self.param_env.caller_bounds.iter().filter_map(|predicate| match *predicate { - ty::Predicate::Trait(ref trait_predicate) => { + ty::Predicate::Trait(ref trait_predicate, _) => { match trait_predicate.skip_binder().trait_ref.self_ty().kind { ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()), _ => None, @@ -1430,7 +1430,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let o = self.resolve_vars_if_possible(&o); if !self.predicate_may_hold(&o) { result = ProbeResult::NoMatch; - if let &ty::Predicate::Trait(ref pred) = &o.predicate { + if let &ty::Predicate::Trait(ref pred, _) = &o.predicate { possibly_unsatisfied_predicates.push(pred.skip_binder().trait_ref); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4affdc4a9d64e..7c1876f5d449c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2623,7 +2623,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { parent: None, predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map( |&predicate| match predicate { - ty::Predicate::Trait(ref data) + ty::Predicate::Trait(ref data, _) if data.skip_binder().self_ty().is_param(index) => { // HACK(eddyb) should get the original `Span`. @@ -3695,7 +3695,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Predicate::Projection(ref data) => { Some((data.to_poly_trait_ref(self.tcx), obligation)) } - ty::Predicate::Trait(ref data) => Some((data.to_poly_trait_ref(), obligation)), + ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)), ty::Predicate::Subtype(..) => None, ty::Predicate::RegionOutlives(..) => None, ty::Predicate::TypeOutlives(..) => None, @@ -3998,7 +3998,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - if let ty::Predicate::Trait(predicate) = error.obligation.predicate { + if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate { // Collect the argument position for all arguments that could have caused this // `FulfillmentError`. let mut referenced_in = final_arg_types @@ -4042,7 +4042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::Path(qpath) = &path.kind { if let hir::QPath::Resolved(_, path) = &qpath { for error in errors { - if let ty::Predicate::Trait(predicate) = error.obligation.predicate { + if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate { // If any of the type arguments in this path segment caused the // `FullfillmentError`, point at its span (#61860). for arg in path diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a03b9f747372e..35f9a4fa68e11 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -432,7 +432,7 @@ fn type_param_predicates( icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true)) .into_iter() .filter(|(predicate, _)| match predicate { - ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index), + ty::Predicate::Trait(ref data, _) => data.skip_binder().self_ty().is_param(index), _ => false, }), ); @@ -857,7 +857,7 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi // which will, in turn, reach indirect supertraits. for &(pred, span) in superbounds { debug!("superbound: {:?}", pred); - if let ty::Predicate::Trait(bound) = pred { + if let ty::Predicate::Trait(bound, _) = pred { tcx.at(span).super_predicates_of(bound.def_id()); } } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f37f6921cebaf..27f8059691a14 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -462,7 +462,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .filter(|p| { !orig_bounds.contains(p) || match p { - &&ty::Predicate::Trait(pred) => pred.def_id() == sized_trait, + ty::Predicate::Trait(pred, _) => pred.def_id() == sized_trait, _ => false, } }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 20a5a6c54984d..7a7d69c68a585 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -482,7 +482,7 @@ impl<'a> Clean> for ty::Predicate<'a> { use rustc::ty::Predicate; match *self { - Predicate::Trait(ref pred) => Some(pred.clean(cx)), + Predicate::Trait(ref pred, _) => Some(pred.clean(cx)), Predicate::Subtype(ref pred) => Some(pred.clean(cx)), Predicate::RegionOutlives(ref pred) => pred.clean(cx), Predicate::TypeOutlives(ref pred) => pred.clean(cx), diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index c7b12d38c430a..2b59c60f0b77f 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -141,7 +141,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) .predicates .iter() .filter_map(|(pred, _)| { - if let ty::Predicate::Trait(ref pred) = *pred { + if let ty::Predicate::Trait(ref pred, _) = *pred { if pred.skip_binder().trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7c2608a0c2a31..88bfb8ccb9525 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2165,7 +2165,8 @@ impl IsAsync { } } -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(HashStable_Generic)] pub enum Constness { Const, NotConst, From d2aefbb286c94240e25cbe0b8cc92a1336db5408 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:32 -0800 Subject: [PATCH 0507/1253] Add `ConstnessAnd` that implements `ToPredicate` --- src/librustc/traits/engine.rs | 4 +- src/librustc/traits/error_reporting/mod.rs | 28 ++++++---- .../traits/error_reporting/suggestions.rs | 17 +++--- src/librustc/traits/mod.rs | 4 +- src/librustc/traits/object_safety.rs | 6 +- src/librustc/traits/project.rs | 11 +++- src/librustc/traits/select.rs | 4 +- src/librustc/traits/util.rs | 25 +++++---- src/librustc/traits/wf.rs | 10 +++- src/librustc/ty/mod.rs | 56 ++++++++++++++++--- src/librustc/ty/sty.rs | 10 +++- src/librustc_ty/ty.rs | 3 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/autoderef.rs | 9 ++- src/librustc_typeck/check/method/mod.rs | 4 +- src/librustc_typeck/check/method/probe.rs | 3 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 7 ++- src/librustc_typeck/collect.rs | 12 ++-- src/librustdoc/clean/blanket_impl.rs | 4 +- 21 files changed, 155 insertions(+), 74 deletions(-) diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index 5b804480119fe..84bfc86e6a94e 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -1,6 +1,6 @@ use crate::infer::InferCtxt; use crate::traits::Obligation; -use crate::ty::{self, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_hir::def_id::DefId; use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError}; @@ -33,7 +33,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }, ); } diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index db3173989ac60..2d02dbf823006 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -19,7 +19,9 @@ use crate::ty::error::ExpectedFound; use crate::ty::fast_reject; use crate::ty::fold::TypeFolder; use crate::ty::SubtypePredicate; -use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{ + self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, +}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; @@ -130,7 +132,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let (cond, error) = match (cond, error) { - (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), + (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error, _)) => (cond, error), _ => { // FIXME: make this work in other cases too. return false; @@ -138,7 +140,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { - if let ty::Predicate::Trait(implication) = implication { + if let ty::Predicate::Trait(implication, _) = implication { let error = error.to_poly_trait_ref(); let implication = implication.to_poly_trait_ref(); // FIXME: I'm just not taking associated types at all here. @@ -530,7 +532,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } match obligation.predicate { - ty::Predicate::Trait(ref trait_predicate) => { + ty::Predicate::Trait(ref trait_predicate, _) => { let trait_predicate = self.resolve_vars_if_possible(trait_predicate); if self.tcx.sess.has_errors() && trait_predicate.references_error() { @@ -583,7 +585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "{}", message.unwrap_or_else(|| format!( "the trait bound `{}` is not satisfied{}", - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), post_message, )) ); @@ -695,7 +697,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { trait_pred }); let unit_obligation = Obligation { - predicate: ty::Predicate::Trait(predicate), + predicate: ty::Predicate::Trait( + predicate, + ast::Constness::NotConst, + ), ..obligation.clone() }; if self.predicate_may_hold(&unit_obligation) { @@ -988,7 +993,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> PredicateObligation<'tcx> { let new_trait_ref = ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; - Obligation::new(cause, param_env, new_trait_ref.to_predicate()) + Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate()) } } @@ -1076,7 +1081,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let mut err = match predicate { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { let trait_ref = data.to_poly_trait_ref(); let self_ty = trait_ref.self_ty(); debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); @@ -1269,8 +1274,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) .value; - let obligation = - Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); + let obligation = Obligation::new( + ObligationCause::dummy(), + param_env, + cleaned_pred.without_const().to_predicate(), + ); self.predicate_may_hold(&obligation) }) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c09fd3079731c..9d8fa362ebbd9 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -6,7 +6,7 @@ use super::{ use crate::infer::InferCtxt; use crate::traits::object_safety::object_safety_violations; use crate::ty::TypeckTables; -use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_errors::{ error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, @@ -50,7 +50,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { " where" }, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), ), Applicability::MachineApplicable, ); @@ -340,8 +340,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let new_self_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, self_ty); let substs = self.tcx.mk_substs_trait(new_self_ty, &[]); let new_trait_ref = ty::TraitRef::new(obligation.parent_trait_ref.def_id(), substs); - let new_obligation = - Obligation::new(ObligationCause::dummy(), param_env, new_trait_ref.to_predicate()); + let new_obligation = Obligation::new( + ObligationCause::dummy(), + param_env, + new_trait_ref.without_const().to_predicate(), + ); if self.predicate_must_hold_modulo_regions(&new_obligation) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { // We have a very specific type of error, where just borrowing this argument @@ -1122,7 +1125,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // the type. The last generator has information about where the bound was introduced. At // least one generator should be present for this diagnostic to be modified. let (mut trait_ref, mut target_ty) = match obligation.predicate { - ty::Predicate::Trait(p) => { + ty::Predicate::Trait(p, _) => { (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty())) } _ => (None, None), @@ -1545,7 +1548,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.note(&format!("required because it appears within the type `{}`", ty)); obligated_types.push(ty); - let parent_predicate = parent_trait_ref.to_predicate(); + let parent_predicate = parent_trait_ref.without_const().to_predicate(); if !self.is_recursive_obligation(obligated_types, &data.parent_code) { self.note_obligation_cause_code( err, @@ -1562,7 +1565,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { parent_trait_ref.print_only_trait_path(), parent_trait_ref.skip_binder().self_ty() )); - let parent_predicate = parent_trait_ref.to_predicate(); + let parent_predicate = parent_trait_ref.without_const().to_predicate(); self.note_obligation_cause_code( err, &parent_predicate, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 2e5da2b038254..7819366f8927d 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -29,7 +29,7 @@ use crate::mir::interpret::ErrorHandled; use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, SubstsRef}; -use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness}; use crate::util::common::ErrorReported; use chalk_engine; use rustc_hir as hir; @@ -732,7 +732,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( param_env, cause: ObligationCause::misc(span, hir::DUMMY_HIR_ID), recursion_depth: 0, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ad6b821b1d771..15f81bb3f47ed 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -12,7 +12,7 @@ use super::elaborate_predicates; use crate::traits::{self, Obligation, ObligationCause}; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -585,6 +585,7 @@ fn receiver_is_dispatchable<'tcx>( def_id: unsize_did, substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), } + .without_const() .to_predicate(); // U: Trait @@ -598,7 +599,7 @@ fn receiver_is_dispatchable<'tcx>( } }); - ty::TraitRef { def_id: unsize_did, substs }.to_predicate() + ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate() }; let caller_bounds: Vec> = param_env @@ -620,6 +621,7 @@ fn receiver_is_dispatchable<'tcx>( def_id: dispatch_from_dyn_did, substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), } + .without_const() .to_predicate(); Obligation::new(ObligationCause::dummy(), param_env, predicate) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 5bc211ade40ad..62672a7810480 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -16,7 +16,7 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; @@ -738,7 +738,12 @@ fn get_paranoid_cache_value_obligation<'a, 'tcx>( depth: usize, ) -> PredicateObligation<'tcx> { let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref(); - Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate() } + Obligation { + cause, + recursion_depth: depth, + param_env, + predicate: trait_ref.without_const().to_predicate(), + } } /// If we are projecting `::Item`, but `T: Trait` does not @@ -772,7 +777,7 @@ fn normalize_to_error<'a, 'tcx>( cause, recursion_depth: depth, param_env, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }; let tcx = selcx.infcx().tcx; let def_id = projection_ty.item_def_id; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9db907e88fab8..ac1ca4db9d6bb 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -37,7 +37,7 @@ use crate::middle::lang_items; use crate::ty::fast_reject; use crate::ty::relate::TypeRelation; use crate::ty::subst::{Subst, SubstsRef}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -3368,7 +3368,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { tcx.require_lang_item(lang_items::SizedTraitLangItem, None), tcx.mk_substs_trait(source, &[]), ); - nested.push(predicate_to_obligation(tr.to_predicate())); + nested.push(predicate_to_obligation(tr.without_const().to_predicate())); // If the type is `Foo + 'a`, ensure that the type // being cast to `Foo + 'a` outlives `'a`: diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index a5a16a1471225..f3bd98b855190 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -4,7 +4,7 @@ use smallvec::SmallVec; use crate::ty::outlives::Component; use crate::ty::subst::{GenericArg, Subst, SubstsRef}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -99,14 +99,14 @@ pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> Elaborator<'tcx> { - elaborate_predicates(tcx, vec![trait_ref.to_predicate()]) + elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()]) } pub fn elaborate_trait_refs<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, ) -> Elaborator<'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect(); + let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect(); elaborate_predicates(tcx, predicates) } @@ -358,7 +358,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { let tcx = self.tcx; let trait_ref = item.trait_ref(); - let pred = trait_ref.to_predicate(); + let pred = trait_ref.without_const().to_predicate(); debug!("expand_trait_aliases: trait_ref={:?}", trait_ref); @@ -370,13 +370,9 @@ impl<'tcx> TraitAliasExpander<'tcx> { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, &pred); - if item - .path - .iter() - .rev() - .skip(1) - .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) - { + if item.path.iter().rev().skip(1).any(|(tr, _)| { + anonymize_predicate(tcx, &tr.without_const().to_predicate()) == anon_pred + }) { return false; } @@ -545,7 +541,12 @@ pub fn predicate_for_trait_ref<'tcx>( trait_ref: ty::TraitRef<'tcx>, recursion_depth: usize, ) -> PredicateObligation<'tcx> { - Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() } + Obligation { + cause, + param_env, + recursion_depth, + predicate: trait_ref.without_const().to_predicate(), + } } pub fn predicate_for_trait_def( diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index aba09c3c81850..a0cb8446c9217 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -3,7 +3,7 @@ use crate::infer::InferCtxt; use crate::middle::lang_items; use crate::traits::{self, AssocTypeBoundData}; use crate::ty::subst::SubstsRef; -use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, Ident}; @@ -350,7 +350,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.compute_trait_ref(&trait_ref, Elaborate::None); if !data.has_escaping_bound_vars() { - let predicate = trait_ref.to_predicate(); + let predicate = trait_ref.without_const().to_predicate(); let cause = self.cause(traits::ProjectionWf(data)); self.out.push(traits::Obligation::new(cause, self.param_env, predicate)); } @@ -378,7 +378,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None), substs: self.infcx.tcx.mk_substs_trait(subty, &[]), }; - self.out.push(traits::Obligation::new(cause, self.param_env, trait_ref.to_predicate())); + self.out.push(traits::Obligation::new( + cause, + self.param_env, + trait_ref.without_const().to_predicate(), + )); } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c5fbf2896a4a1..0470ab20dc464 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -52,7 +52,7 @@ use std::ops::Deref; use std::ops::Range; use std::slice; use std::{mem, ptr}; -use syntax::ast::{self, Ident, Name, NodeId}; +use syntax::ast::{self, Constness, Ident, Name, NodeId}; use syntax::attr; pub use self::sty::BoundRegion::*; @@ -1072,7 +1072,7 @@ pub enum Predicate<'tcx> { /// A trait predicate will have `Constness::Const` if it originates /// from a bound on a `const fn` without the `?const` opt-out (e.g., /// `const fn foobar() {}`). - Trait(PolyTraitPredicate<'tcx>, ast::Constness), + Trait(PolyTraitPredicate<'tcx>, Constness), /// `where 'a: 'b` RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), @@ -1340,18 +1340,33 @@ pub trait ToPredicate<'tcx> { fn to_predicate(&self) -> Predicate<'tcx>; } -impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(&self) -> Predicate<'tcx> { ty::Predicate::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }), - ast::Constness::NotConst, + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + self.constness, ) } } -impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> { fn to_predicate(&self) -> Predicate<'tcx> { - ty::Predicate::Trait(self.to_poly_trait_predicate(), ast::Constness::NotConst) + ty::Predicate::Trait( + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + self.constness, + ) + } +} + +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { + fn to_predicate(&self) -> Predicate<'tcx> { + ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness) + } +} + +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&PolyTraitRef<'tcx>> { + fn to_predicate(&self) -> Predicate<'tcx> { + ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness) } } @@ -1707,6 +1722,33 @@ impl<'tcx> ParamEnv<'tcx> { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct ConstnessAnd { + pub constness: Constness, + pub value: T, +} + +// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate()` to ensure that +// the constness of trait bounds is being propagated correctly. +pub trait WithConstness: Sized { + #[inline] + fn with_constness(self, constness: Constness) -> ConstnessAnd { + ConstnessAnd { constness, value: self } + } + + #[inline] + fn with_const(self) -> ConstnessAnd { + self.with_constness(Constness::Const) + } + + #[inline] + fn without_const(self) -> ConstnessAnd { + self.with_constness(Constness::NotConst) + } +} + +impl WithConstness for T {} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] pub struct ParamEnvAnd<'tcx, T> { pub param_env: ParamEnv<'tcx>, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 842361284823d..13f623aadb1a3 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -12,7 +12,9 @@ use crate::mir::interpret::Scalar; use crate::mir::Promoted; use crate::ty::layout::VariantIdx; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; -use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable}; +use crate::ty::{ + self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness, +}; use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS}; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; @@ -665,14 +667,16 @@ impl<'tcx> Binder> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { use crate::ty::ToPredicate; match *self.skip_binder() { - ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(), + ExistentialPredicate::Trait(tr) => { + Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate() + } ExistentialPredicate::Projection(p) => { ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))) } ExistentialPredicate::AutoTrait(did) => { let trait_ref = Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) }); - trait_ref.to_predicate() + trait_ref.without_const().to_predicate() } } } diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index d47e54366b550..8b62403e6ce52 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -2,7 +2,7 @@ use rustc::hir::map as hir_map; use rustc::session::CrateDisambiguator; use rustc::traits::{self}; use rustc::ty::subst::Subst; -use rustc::ty::{self, ToPredicate, Ty, TyCtxt}; +use rustc::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::svh::Svh; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -58,6 +58,7 @@ fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>) def_id: sized_trait, substs: tcx.mk_substs_trait(ty, &[]), }) + .without_const() .to_predicate(); let predicates = tcx.predicates_of(adtdef.did).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7f196b2c4d352..9253c00e5ae27 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -17,7 +17,7 @@ use rustc::traits::astconv_object_safety_violations; use rustc::traits::error_reporting::report_object_safety_error; use rustc::traits::wf::object_region_bounds; use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; -use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; @@ -2980,7 +2980,7 @@ impl<'tcx> Bounds<'tcx> { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]), }); - (trait_ref.to_predicate(), span) + (trait_ref.without_const().to_predicate(), span) }) }); diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 8d6b74c3015c9..367fe0c3cc199 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -5,7 +5,7 @@ use rustc::infer::{InferCtxt, InferOk}; use rustc::session::DiagnosticMessageId; use rustc::traits::{self, TraitEngine}; use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; -use rustc::ty::{self, TraitRef, Ty, TyCtxt}; +use rustc::ty::{self, TraitRef, Ty, TyCtxt, WithConstness}; use rustc::ty::{ToPredicate, TypeFoldable}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -124,8 +124,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let cause = traits::ObligationCause::misc(self.span, self.body_id); - let obligation = - traits::Obligation::new(cause.clone(), self.param_env, trait_ref.to_predicate()); + let obligation = traits::Obligation::new( + cause.clone(), + self.param_env, + trait_ref.without_const().to_predicate(), + ); if !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); return None; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 711c285d17e88..c1cf3522b5d9c 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -17,7 +17,7 @@ use rustc::traits; use rustc::ty::subst::Subst; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::GenericParamDefKind; -use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable}; +use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable, WithConstness}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -322,7 +322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.to_predicate(), + poly_trait_ref.without_const().to_predicate(), ); // Now we want to know if this can be matched diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 67526bb70d125..ff2f150c63330 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -25,6 +25,7 @@ use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::GenericParamDefKind; use rustc::ty::{ self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, + WithConstness, }; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; @@ -1396,7 +1397,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } TraitCandidate(trait_ref) => { - let predicate = trait_ref.to_predicate(); + let predicate = trait_ref.without_const().to_predicate(); let obligation = traits::Obligation::new(cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { if self.probe(|_| self.select_trait_candidate(trait_ref).is_err()) { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index d6c0d9c77b495..35fffd3bcd45c 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -9,7 +9,7 @@ use rustc::hir::map::Map; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::Obligation; use rustc::ty::print::with_crate_prefix; -use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -59,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.to_predicate(), + poly_trait_ref.without_const().to_predicate(), ); self.predicate_may_hold(&obligation) }) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7c1876f5d449c..1e3927f33a77f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -112,7 +112,7 @@ use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSel use rustc::ty::util::{Discr, IntTypeExt, Representability}; use rustc::ty::{ self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef, - ToPredicate, Ty, TyCtxt, UserType, + ToPredicate, Ty, TyCtxt, UserType, WithConstness, }; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -1423,7 +1423,7 @@ fn check_fn<'a, 'tcx>( inherited.register_predicate(traits::Obligation::new( cause, param_env, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), )); } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 5e91e98a7dfa5..e4df69993c5d2 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -6,7 +6,9 @@ use rustc::middle::lang_items; use rustc::session::parse::feature_err; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::subst::{InternalSubsts, Subst}; -use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{ + self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, +}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir::def_id::DefId; @@ -955,7 +957,8 @@ fn receiver_is_implemented( substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]), }; - let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate()); + let obligation = + traits::Obligation::new(cause, fcx.param_env, trait_ref.without_const().to_predicate()); if fcx.predicate_must_hold_modulo_regions(&obligation) { true diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 35f9a4fa68e11..1211075d9429b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -30,7 +30,7 @@ use rustc::ty::subst::GenericArgKind; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; -use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; +use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; @@ -411,7 +411,8 @@ fn type_param_predicates( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - extend = Some((identity_trait_ref.to_predicate(), item.span)); + extend = + Some((identity_trait_ref.without_const().to_predicate(), item.span)); } generics } @@ -2056,7 +2057,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { let span = tcx.def_span(def_id); result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).to_predicate(), + ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(), span, )))); } @@ -2230,7 +2231,10 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id))); + predicates.push(( + trait_ref.to_poly_trait_ref().without_const().to_predicate(), + tcx.def_span(def_id), + )); } // Collect the region predicates that were declared inline as diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 525b1b2e6ecf7..18ebd254507ea 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -1,7 +1,7 @@ use rustc::infer::InferOk; use rustc::traits; use rustc::ty::subst::Subst; -use rustc::ty::ToPredicate; +use rustc::ty::{ToPredicate, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; use rustc_span::DUMMY_SP; @@ -64,7 +64,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { match infcx.evaluate_obligation(&traits::Obligation::new( cause, param_env, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), )) { Ok(eval_result) => eval_result.may_apply(), Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no From adbd01e84ad791ef370dc1d2baa726603f42094a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:33 -0800 Subject: [PATCH 0508/1253] Track constness while lowering bounds --- src/librustc_privacy/lib.rs | 2 +- src/librustc_typeck/astconv.rs | 54 +++++++++++++++++++++----------- src/librustc_typeck/check/mod.rs | 11 +++++++ src/librustc_typeck/collect.rs | 44 ++++++++++++++++++++++---- src/librustc_typeck/lib.rs | 1 + 5 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4b2e90ed83de2..a914537d13408 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1237,7 +1237,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // The traits' privacy in bodies is already checked as a part of trait object types. let bounds = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref); - for (trait_predicate, _) in bounds.trait_bounds { + for (trait_predicate, _, _) in bounds.trait_bounds { if self.visit_trait(*trait_predicate.skip_binder()) { return; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9253c00e5ae27..6726a1461052b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -31,7 +31,7 @@ use rustc_span::symbol::sym; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; use smallvec::SmallVec; -use syntax::ast; +use syntax::ast::{self, Constness}; use syntax::util::lev_distance::find_best_match_for_name; use std::collections::BTreeSet; @@ -49,6 +49,8 @@ pub trait AstConv<'tcx> { fn item_def_id(&self) -> Option; + fn default_constness_for_trait_bounds(&self) -> Constness; + /// Returns predicates in scope of the form `X: Foo`, where `X` is /// a type parameter `X` with the given id `def_id`. This is a /// subset of the full set of predicates. @@ -919,6 +921,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, trait_ref: &hir::TraitRef<'_>, span: Span, + constness: Constness, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, @@ -947,7 +950,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); - bounds.trait_bounds.push((poly_trait_ref, span)); + bounds.trait_bounds.push((poly_trait_ref, span, constness)); let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { @@ -993,12 +996,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { pub fn instantiate_poly_trait_ref( &self, poly_trait_ref: &hir::PolyTraitRef<'_>, + constness: Constness, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, ) -> Option> { self.instantiate_poly_trait_ref_inner( &poly_trait_ref.trait_ref, poly_trait_ref.span, + constness, self_ty, bounds, false, @@ -1181,18 +1186,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut trait_bounds = Vec::new(); let mut region_bounds = Vec::new(); + let constness = self.default_constness_for_trait_bounds(); for ast_bound in ast_bounds { match *ast_bound { hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => { - trait_bounds.push(b) + trait_bounds.push((b, constness)) + } + hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => { + trait_bounds.push((b, Constness::NotConst)) } hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} hir::GenericBound::Outlives(ref l) => region_bounds.push(l), } } - for bound in trait_bounds { - let _ = self.instantiate_poly_trait_ref(bound, param_ty, bounds); + for (bound, constness) in trait_bounds { + let _ = self.instantiate_poly_trait_ref(bound, constness, param_ty, bounds); } bounds.region_bounds.extend( @@ -1226,7 +1235,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut bounds = Bounds::default(); self.add_bounds(param_ty, ast_bounds, &mut bounds); - bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id()); + bounds.trait_bounds.sort_by_key(|(t, _, _)| t.def_id()); bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default { if !self.is_unsized(ast_bounds, span) { Some(span) } else { None } @@ -1417,15 +1426,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; for trait_bound in trait_bounds.iter().rev() { - let cur_potential_assoc_types = - self.instantiate_poly_trait_ref(trait_bound, dummy_self, &mut bounds); + let cur_potential_assoc_types = self.instantiate_poly_trait_ref( + trait_bound, + Constness::NotConst, + dummy_self, + &mut bounds, + ); potential_assoc_types.extend(cur_potential_assoc_types.into_iter().flatten()); } // Expand trait aliases recursively and check that only one regular (non-auto) trait // is used and no 'maybe' bounds are used. - let expanded_traits = - traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().cloned()); + let expanded_traits = traits::expand_trait_aliases( + tcx, + bounds.trait_bounds.iter().map(|&(a, b, _)| (a.clone(), b)), + ); let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); if regular_traits.len() > 1 { @@ -1481,16 +1496,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let regular_traits_refs_spans = bounds .trait_bounds .into_iter() - .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); + .filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id())); + + for (base_trait_ref, span, constness) in regular_traits_refs_spans { + assert_eq!(constness, ast::Constness::NotConst); - for (base_trait_ref, span) in regular_traits_refs_spans { for trait_ref in traits::elaborate_trait_ref(tcx, base_trait_ref) { debug!( "conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", trait_ref ); match trait_ref { - ty::Predicate::Trait(pred, constness) => { + ty::Predicate::Trait(pred, _) => { associated_types.entry(span).or_default().extend( tcx.associated_items(pred.def_id()) .filter(|item| item.kind == ty::AssocKind::Type) @@ -2949,7 +2966,7 @@ pub struct Bounds<'tcx> { /// A list of trait bounds. So if you had `T: Debug` this would be /// `T: Debug`. Note that the self-type is explicit here. - pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>, + pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, Constness)>, /// A list of projection equality bounds. So if you had `T: /// Iterator` this would include ` Bounds<'tcx> { let outlives = ty::OutlivesPredicate(param_ty, region_bound); (ty::Binder::bind(outlives).to_predicate(), span) }) - .chain( - self.trait_bounds - .iter() - .map(|&(bound_trait_ref, span)| (bound_trait_ref.to_predicate(), span)), - ) + .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| { + let predicate = bound_trait_ref.with_constness(constness).to_predicate(); + (predicate, span) + })) .chain( self.projection_bounds .iter() diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1e3927f33a77f..5e1b3a76fd28f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -90,6 +90,7 @@ pub mod writeback; use crate::astconv::{AstConv, PathSeg}; use crate::middle::lang_items; use crate::namespace::Namespace; +use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::Map; use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282; @@ -2612,6 +2613,16 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { None } + fn default_constness_for_trait_bounds(&self) -> ast::Constness { + // FIXME: refactor this into a method + let node = self.tcx.hir().get(self.body_id); + if let Some(fn_like) = FnLikeNode::from_node(node) { + fn_like.constness() + } else { + ast::Constness::NotConst + } + } + fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> { let tcx = self.tcx; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1211075d9429b..45d969a3d574f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -20,6 +20,7 @@ use crate::constrained_generic_params as cgp; use crate::lint; use crate::middle::resolve_lifetime as rl; use crate::middle::weak_lang_items; +use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::Map; use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::mir::mono::Linkage; @@ -288,6 +289,22 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { Some(self.item_def_id) } + fn default_constness_for_trait_bounds(&self) -> ast::Constness { + // FIXME: refactor this into a method + let hir_id = self + .tcx + .hir() + .as_local_hir_id(self.item_def_id) + .expect("Non-local call to local provider is_const_fn"); + + let node = self.tcx.hir().get(hir_id); + if let Some(fn_like) = FnLikeNode::from_node(node) { + fn_like.constness() + } else { + ast::Constness::NotConst + } + } + fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> { self.tcx.at(span).type_param_predicates((self.item_def_id, def_id)) } @@ -454,6 +471,7 @@ impl ItemCtxt<'tcx> { ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, ) -> Vec<(ty::Predicate<'tcx>, Span)> { + let constness = self.default_constness_for_trait_bounds(); let from_ty_params = ast_generics .params .iter() @@ -462,7 +480,7 @@ impl ItemCtxt<'tcx> { _ => None, }) .flat_map(|bounds| bounds.iter()) - .flat_map(|b| predicates_from_bound(self, ty, b)); + .flat_map(|b| predicates_from_bound(self, ty, b, constness)); let from_where_clauses = ast_generics .where_clause @@ -482,7 +500,7 @@ impl ItemCtxt<'tcx> { }; bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b))) }) - .flat_map(|(bt, b)| predicates_from_bound(self, bt, b)); + .flat_map(|(bt, b)| predicates_from_bound(self, bt, b, constness)); from_ty_params.chain(from_where_clauses).collect() } @@ -2107,6 +2125,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat let mut is_default_impl_trait = None; let icx = ItemCtxt::new(tcx, def_id); + let constness = icx.default_constness_for_trait_bounds(); const NO_GENERICS: &hir::Generics<'_> = &hir::Generics::empty(); @@ -2308,11 +2327,18 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat for bound in bound_pred.bounds.iter() { match bound { - &hir::GenericBound::Trait(ref poly_trait_ref, _) => { + &hir::GenericBound::Trait(ref poly_trait_ref, modifier) => { + let constness = match modifier { + hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst, + hir::TraitBoundModifier::None => constness, + hir::TraitBoundModifier::Maybe => bug!("this wasn't handled"), + }; + let mut bounds = Bounds::default(); let _ = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, + constness, ty, &mut bounds, ); @@ -2488,11 +2514,18 @@ fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx>, param_ty: Ty<'tcx>, bound: &'tcx hir::GenericBound<'tcx>, + constness: ast::Constness, ) -> Vec<(ty::Predicate<'tcx>, Span)> { match *bound { - hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { + hir::GenericBound::Trait(ref tr, modifier) => { + let constness = match modifier { + hir::TraitBoundModifier::Maybe => return vec![], + hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst, + hir::TraitBoundModifier::None => constness, + }; + let mut bounds = Bounds::default(); - let _ = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut bounds); + let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds); bounds.predicates(astconv.tcx(), param_ty) } hir::GenericBound::Outlives(ref lifetime) => { @@ -2500,7 +2533,6 @@ fn predicates_from_bound<'tcx>( let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region)); vec![(ty::Predicate::TypeOutlives(pred), lifetime.span)] } - hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![], } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 95cd3c631ed22..b3cf5f21fab9b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -382,6 +382,7 @@ pub fn hir_trait_to_predicates<'tcx>( &item_cx, hir_trait, DUMMY_SP, + syntax::ast::Constness::NotConst, tcx.types.err, &mut bounds, true, From 3b1a9d35c8ee396d2c546603347b5dc65d619cdf Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:35 -0800 Subject: [PATCH 0509/1253] Ignore filelength for `astconv` --- src/librustc_typeck/astconv.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 6726a1461052b..9397d183493b1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -3,6 +3,8 @@ //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an //! instance of `AstConv`. +// ignore-tidy-filelength + use crate::collect::PlaceholderHirTyCollector; use crate::lint; use crate::middle::lang_items::SizedTraitLangItem; From 0ac4ba0eed776599e2d9f2ef76f6ae94a4471a4e Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 20 Jan 2020 01:20:45 -0800 Subject: [PATCH 0510/1253] Parse `?const ?Trait` --- src/librustc_ast_lowering/lib.rs | 9 +++++++-- src/librustc_ast_passes/ast_validation.rs | 17 +++++++++++++---- src/librustc_parse/parser/ty.rs | 23 +++++------------------ src/libsyntax/ast.rs | 5 +++++ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 90560c371e292..bc922fa0f55a3 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1254,7 +1254,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => { Some(this.lower_poly_trait_ref(ty, itctx.reborrow())) } - GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, + GenericBound::Trait(_, TraitBoundModifier::Maybe) + | GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => { + None + } GenericBound::Outlives(ref lifetime) => { if lifetime_bound.is_none() { lifetime_bound = Some(this.lower_lifetime(lifetime)); @@ -2297,8 +2300,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier { match f { TraitBoundModifier::None => hir::TraitBoundModifier::None, - TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst, + TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => { + hir::TraitBoundModifier::Maybe + } } } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 23cb97348339d..9b71704f52d43 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -917,11 +917,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_param_bound(&mut self, bound: &'a GenericBound) { - if let GenericBound::Trait(_, TraitBoundModifier::MaybeConst) = bound { - if let Some(ctx) = self.bound_context { - let msg = format!("`?const` is not permitted in {}", ctx.description()); - self.err_handler().span_err(bound.span(), &msg); + match bound { + GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => { + if let Some(ctx) = self.bound_context { + let msg = format!("`?const` is not permitted in {}", ctx.description()); + self.err_handler().span_err(bound.span(), &msg); + } + } + + GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => { + self.err_handler() + .span_err(bound.span(), "`?const` and `?` are mutually exclusive"); } + + _ => {} } visit::walk_param_bound(self, bound) diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 9c9180778e522..efd8acc933aa8 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -27,17 +27,13 @@ struct BoundModifiers { } impl BoundModifiers { - fn to_trait_bound_modifier(&self) -> Result { - let modifier = match (self.maybe, self.maybe_const) { + fn to_trait_bound_modifier(&self) -> TraitBoundModifier { + match (self.maybe, self.maybe_const) { (None, None) => TraitBoundModifier::None, (Some(_), None) => TraitBoundModifier::Maybe, (None, Some(_)) => TraitBoundModifier::MaybeConst, - (Some(_), Some(_)) => { - return Err("`?const` and `?` are mutually exclusive"); - } - }; - - Ok(modifier) + (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe, + } } } @@ -563,16 +559,7 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; } - let modifier = match modifiers.to_trait_bound_modifier() { - Ok(m) => m, - Err(msg) => { - self.struct_span_err(lo.to(self.prev_span), msg).emit(); - - // Continue compilation as if the user had written `?Trait`. - TraitBoundModifier::Maybe - } - }; - + let modifier = modifiers.to_trait_bound_modifier(); let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span)); Ok(GenericBound::Trait(poly_trait, modifier)) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 88bfb8ccb9525..5f38ac4cc0f42 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -279,6 +279,11 @@ pub enum TraitBoundModifier { /// `?const Trait` MaybeConst, + + /// `?const ?Trait` + // + // This parses but will be rejected during AST validation. + MaybeConstMaybe, } /// The AST represents all type param bounds as types. From 23ea42cfd14e185f3af2232083318fdca90a4b6c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:34 -0800 Subject: [PATCH 0511/1253] Update tests --- .../feature-gate.gated.stderr | 8 ++--- .../const-trait-bound-opt-out/feature-gate.rs | 5 +-- .../feature-gate.stock.stderr | 10 ++---- .../in-impl-trait.rs | 4 --- .../in-impl-trait.stderr | 32 +++---------------- .../in-trait-bounds.rs | 1 - .../in-trait-bounds.stderr | 8 +---- .../in-trait-object.rs | 3 -- .../in-trait-object.stderr | 24 ++------------ .../with-maybe-sized.rs | 1 - .../with-maybe-sized.stderr | 8 +---- .../inherent-impl.rs | 9 ++++-- .../inherent-impl.stderr | 30 ++++++++++++++--- 13 files changed, 49 insertions(+), 94 deletions(-) diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr index 0bf337ad08dbf..e4f4d4262b64d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr @@ -1,8 +1,8 @@ -error: `?const` on trait bounds is not yet implemented - --> $DIR/feature-gate.rs:11:29 +error: fatal error triggered by #[rustc_error] + --> $DIR/feature-gate.rs:16:1 | -LL | const fn get_assoc_const() -> i32 { ::CONST } - | ^^^^^^^^ +LL | fn main() {} + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs index cf1ed30da0fcc..d600b53e44875 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs @@ -3,6 +3,7 @@ #![cfg_attr(gated, feature(const_trait_bound_opt_out))] #![allow(incomplete_features)] +#![feature(rustc_attrs)] trait T { const CONST: i32; @@ -10,6 +11,6 @@ trait T { const fn get_assoc_const() -> i32 { ::CONST } //[stock]~^ ERROR `?const` on trait bounds is experimental -//[stock,gated]~^^ ERROR `?const` on trait bounds is not yet implemented -fn main() {} +#[rustc_error] +fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error] diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr index 64388004b5b72..fbd3840cb1d2b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr @@ -1,5 +1,5 @@ error[E0658]: `?const` on trait bounds is experimental - --> $DIR/feature-gate.rs:11:29 + --> $DIR/feature-gate.rs:12:29 | LL | const fn get_assoc_const() -> i32 { ::CONST } | ^^^^^^ @@ -7,12 +7,6 @@ LL | const fn get_assoc_const() -> i32 { ::CONST } = note: for more information, see https://github.com/rust-lang/rust/issues/67794 = help: add `#![feature(const_trait_bound_opt_out)]` to the crate attributes to enable -error: `?const` on trait bounds is not yet implemented - --> $DIR/feature-gate.rs:11:29 - | -LL | const fn get_assoc_const() -> i32 { ::CONST } - | ^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs index e4e6bedd93746..f5561a922ddcd 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs @@ -8,18 +8,14 @@ impl T for S {} fn rpit() -> impl ?const T { S } //~^ ERROR `?const` is not permitted in `impl Trait` -//~| ERROR `?const` on trait bounds is not yet implemented fn apit(_: impl ?const T) {} //~^ ERROR `?const` is not permitted in `impl Trait` -//~| ERROR `?const` on trait bounds is not yet implemented fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } //~^ ERROR `?const` is not permitted in `impl Trait` -//~| ERROR `?const` on trait bounds is not yet implemented fn apit_assoc_bound(_: impl IntoIterator) {} //~^ ERROR `?const` is not permitted in `impl Trait` -//~| ERROR `?const` on trait bounds is not yet implemented fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr index f4abd4b714e8a..06cd00a956a2d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr @@ -5,46 +5,22 @@ LL | fn rpit() -> impl ?const T { S } | ^^^^^^^^ error: `?const` is not permitted in `impl Trait` - --> $DIR/in-impl-trait.rs:13:17 + --> $DIR/in-impl-trait.rs:12:17 | LL | fn apit(_: impl ?const T) {} | ^^^^^^^^ error: `?const` is not permitted in `impl Trait` - --> $DIR/in-impl-trait.rs:17:50 + --> $DIR/in-impl-trait.rs:15:50 | LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } | ^^^^^^^^ error: `?const` is not permitted in `impl Trait` - --> $DIR/in-impl-trait.rs:21:48 + --> $DIR/in-impl-trait.rs:18:48 | LL | fn apit_assoc_bound(_: impl IntoIterator) {} | ^^^^^^^^ -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-impl-trait.rs:9:19 - | -LL | fn rpit() -> impl ?const T { S } - | ^^^^^^^^ - -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-impl-trait.rs:13:17 - | -LL | fn apit(_: impl ?const T) {} - | ^^^^^^^^ - -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-impl-trait.rs:17:50 - | -LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } - | ^^^^^^^^ - -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-impl-trait.rs:21:48 - | -LL | fn apit_assoc_bound(_: impl IntoIterator) {} - | ^^^^^^^^ - -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs index 4523b46bc51f6..fc9ed5b1dc22e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs @@ -4,6 +4,5 @@ trait Super {} trait T: ?const Super {} //~^ ERROR `?const` is not permitted in supertraits -//~| ERROR `?const` on trait bounds is not yet implemented fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr index 8003361be7d2e..a0d8f95acd2a8 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr @@ -4,11 +4,5 @@ error: `?const` is not permitted in supertraits LL | trait T: ?const Super {} | ^^^^^^^^^^^^ -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-trait-bounds.rs:5:10 - | -LL | trait T: ?const Super {} - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs index 6cfca71548674..b3d1f48ace147 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs @@ -9,14 +9,11 @@ impl T for S {} // An inherent impl for the trait object `?const T`. impl ?const T {} //~^ ERROR `?const` is not permitted in trait objects -//~| ERROR `?const` on trait bounds is not yet implemented fn trait_object() -> &'static dyn ?const T { &S } //~^ ERROR `?const` is not permitted in trait objects -//~| ERROR `?const` on trait bounds is not yet implemented fn trait_object_in_apit(_: impl IntoIterator>) {} //~^ ERROR `?const` is not permitted in trait objects -//~| ERROR `?const` on trait bounds is not yet implemented fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr index c059f16902250..331fe0423fa94 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr @@ -5,34 +5,16 @@ LL | impl ?const T {} | ^^^^^^^^ error: `?const` is not permitted in trait objects - --> $DIR/in-trait-object.rs:14:35 + --> $DIR/in-trait-object.rs:13:35 | LL | fn trait_object() -> &'static dyn ?const T { &S } | ^^^^^^^^ error: `?const` is not permitted in trait objects - --> $DIR/in-trait-object.rs:18:61 + --> $DIR/in-trait-object.rs:16:61 | LL | fn trait_object_in_apit(_: impl IntoIterator>) {} | ^^^^^^^^ -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-trait-object.rs:10:6 - | -LL | impl ?const T {} - | ^^^^^^^^ - -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-trait-object.rs:14:35 - | -LL | fn trait_object() -> &'static dyn ?const T { &S } - | ^^^^^^^^ - -error: `?const` on trait bounds is not yet implemented - --> $DIR/in-trait-object.rs:18:61 - | -LL | fn trait_object_in_apit(_: impl IntoIterator>) {} - | ^^^^^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs index 425784f4e4326..c2c8689e2942b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs @@ -3,6 +3,5 @@ struct S(std::marker::PhantomData); //~^ ERROR `?const` and `?` are mutually exclusive -//~| ERROR `?const` on trait bounds is not yet implemented fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr index 44f6d464ae6a8..e8e9d6c1e7621 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr @@ -4,11 +4,5 @@ error: `?const` and `?` are mutually exclusive LL | struct S(std::marker::PhantomData); | ^^^^^^^^^^^^^ -error: `?const` on trait bounds is not yet implemented - --> $DIR/with-maybe-sized.rs:4:13 - | -LL | struct S(std::marker::PhantomData); - | ^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs index 9cffe75addd63..7f064c0c53ade 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs @@ -1,5 +1,3 @@ -// compile-flags: -Z parse-only - #![feature(const_trait_impl)] #![feature(const_trait_bound_opt_out)] #![allow(incomplete_features)] @@ -8,7 +6,12 @@ struct S; trait T {} +impl const S {} +//~^ ERROR inherent impls cannot be `const` +//~| ERROR const trait impls are not yet implemented + impl const T {} -//~^ ERROR `const` cannot modify an inherent impl +//~^ ERROR inherent impls cannot be `const` +//~| ERROR const trait impls are not yet implemented fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr index 1d24557655951..508c6f4c747e1 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr @@ -1,10 +1,30 @@ -error: `const` cannot modify an inherent impl - --> $DIR/inherent-impl.rs:11:6 +error: inherent impls cannot be `const` + --> $DIR/inherent-impl.rs:9:1 + | +LL | impl const S {} + | ^^^^^^^^^^^^^^^ + | + = note: only trait implementations may be annotated with `const` + +error: inherent impls cannot be `const` + --> $DIR/inherent-impl.rs:13:1 | LL | impl const T {} - | ^^^^^ + | ^^^^^^^^^^^^^^^ + | + = note: only trait implementations may be annotated with `const` + +error: const trait impls are not yet implemented + --> $DIR/inherent-impl.rs:9:1 + | +LL | impl const S {} + | ^^^^^^^^^^^^^^^ + +error: const trait impls are not yet implemented + --> $DIR/inherent-impl.rs:13:1 | - = help: only a trait impl can be `const` +LL | impl const T {} + | ^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 4 previous errors From 6be3446f92b444cd6584c7948be9f7cf20ce5518 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Mon, 20 Jan 2020 10:01:17 +0000 Subject: [PATCH 0512/1253] Added minor clarification to specification of realloc. The `layout` for the returned allocation of a `realloc` is only implicitly specified. This change makes it explicit. --- src/libcore/alloc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 4354e1c7b5f69..09f743fb81e4c 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -525,7 +525,8 @@ pub unsafe trait GlobalAlloc { /// The memory may or may not have been deallocated, /// and should be considered unusable (unless of course it was /// transferred back to the caller again via the return value of - /// this method). + /// this method). The new memory block is allocated with `layout`, but + /// with the `size` updated to `new_size`. /// /// If this method returns null, then ownership of the memory /// block has not been transferred to this allocator, and the From 93efe41b4ef9e0cccedbf962381002d48b3f780c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 00:53:54 +0100 Subject: [PATCH 0513/1253] stabilize transparent_enums --- .../language-features/transparent-enums.md | 93 ------------------- src/librustc_feature/accepted.rs | 2 + src/librustc_feature/active.rs | 3 - src/librustc_typeck/check/mod.rs | 10 -- .../codegen/repr-transparent-aggregates-1.rs | 2 +- .../codegen/repr-transparent-aggregates-2.rs | 2 +- .../codegen/repr-transparent-aggregates-3.rs | 2 +- src/test/codegen/repr-transparent.rs | 2 +- .../feature-gate-transparent_enums.rs | 6 -- .../feature-gate-transparent_enums.stderr | 12 --- src/test/ui/lint/lint-ctypes-enum.rs | 2 +- src/test/ui/repr/repr-transparent.rs | 2 +- 12 files changed, 8 insertions(+), 130 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/transparent-enums.md delete mode 100644 src/test/ui/feature-gates/feature-gate-transparent_enums.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-transparent_enums.stderr diff --git a/src/doc/unstable-book/src/language-features/transparent-enums.md b/src/doc/unstable-book/src/language-features/transparent-enums.md deleted file mode 100644 index 862411ab39203..0000000000000 --- a/src/doc/unstable-book/src/language-features/transparent-enums.md +++ /dev/null @@ -1,93 +0,0 @@ -# `transparent_enums` - -The tracking issue for this feature is [#60405] - -[60405]: https://github.com/rust-lang/rust/issues/60405 - ----- - -The `transparent_enums` feature allows you mark `enum`s as -`#[repr(transparent)]`. An `enum` may be `#[repr(transparent)]` if it has -exactly one variant, and that variant matches the same conditions which `struct` -requires for transparency. Some concrete illustrations follow. - -```rust -#![feature(transparent_enums)] - -// This enum has the same representation as `f32`. -#[repr(transparent)] -enum SingleFieldEnum { - Variant(f32) -} - -// This enum has the same representation as `usize`. -#[repr(transparent)] -enum MultiFieldEnum { - Variant { field: usize, nothing: () }, -} -``` - -For consistency with transparent `struct`s, `enum`s must have exactly one -non-zero-sized field. If all fields are zero-sized, the `enum` must not be -`#[repr(transparent)]`: - -```rust -#![feature(transparent_enums)] - -// This (non-transparent) enum is already valid in stable Rust: -pub enum GoodEnum { - Nothing, -} - -// Error: transparent enum needs exactly one non-zero-sized field, but has 0 -// #[repr(transparent)] -// pub enum BadEnum { -// Nothing(()), -// } - -// Error: transparent enum needs exactly one non-zero-sized field, but has 0 -// #[repr(transparent)] -// pub enum BadEmptyEnum { -// Nothing, -// } -``` - -The one exception is if the `enum` is generic over `T` and has a field of type -`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type: - -```rust -#![feature(transparent_enums)] - -// This enum has the same representation as `T`. -#[repr(transparent)] -pub enum GenericEnum { - Variant(T, ()), -} - -// This is okay even though `()` is a zero-sized type. -pub const THIS_IS_OKAY: GenericEnum<()> = GenericEnum::Variant((), ()); -``` - -Transparent `enum`s require exactly one variant: - -```rust -// Error: transparent enum needs exactly one variant, but has 0 -// #[repr(transparent)] -// pub enum TooFewVariants { -// } - -// Error: transparent enum needs exactly one variant, but has 2 -// #[repr(transparent)] -// pub enum TooManyVariants { -// First(usize), -// Second, -// } -``` - -Like transarent `struct`s, a transparent `enum` of type `E` has the same layout, -size, and ABI as its single non-ZST field. If it is generic over a type `T`, and -all its fields are ZSTs except for exactly one field of type `T`, then it has -the same layout and ABI as `T` (even if `T` is a ZST when monomorphized). - -Like transparent `struct`s, transparent `enum`s are FFI-safe if and only if -their underlying representation type is also FFI-safe. diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs index 007cee4c76424..18dc3e30db1d4 100644 --- a/src/librustc_feature/accepted.rs +++ b/src/librustc_feature/accepted.rs @@ -257,6 +257,8 @@ declare_features! ( /// Allows relaxing the coherence rules such that /// `impl ForeignTrait for ForeignType` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), + /// Allows #[repr(transparent)] on univariant enums (RFC 2645). + (accepted, transparent_enums, "1.42.0", Some(60405), None), /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. (accepted, slice_patterns, "1.42.0", Some(62254), None), diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 6af9b6c087278..f20a57ea61c42 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -468,9 +468,6 @@ declare_features! ( /// Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None), - /// Allows #[repr(transparent)] on enums (RFC 2645). - (active, transparent_enums, "1.37.0", Some(60405), None), - /// Allows #[repr(transparent)] on unions (RFC 2645). (active, transparent_unions, "1.37.0", Some(60405), None), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f7df630fb90b1..0c8830717aa3b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2433,16 +2433,6 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { } let sp = tcx.sess.source_map().def_span(sp); - if adt.is_enum() && !tcx.features().transparent_enums { - feature_err( - &tcx.sess.parse_sess, - sym::transparent_enums, - sp, - "transparent enums are unstable", - ) - .emit(); - } - if adt.is_union() && !tcx.features().transparent_unions { feature_err( &tcx.sess.parse_sess, diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 1c8959619d3b2..018a7ba4756a9 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -10,7 +10,7 @@ // ignore-windows // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs index afefb9c9f71a5..5669858672074 100644 --- a/src/test/codegen/repr-transparent-aggregates-2.rs +++ b/src/test/codegen/repr-transparent-aggregates-2.rs @@ -13,7 +13,7 @@ // ignore-x86_64 // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs index 1a59c9b48b976..e538be687801e 100644 --- a/src/test/codegen/repr-transparent-aggregates-3.rs +++ b/src/test/codegen/repr-transparent-aggregates-3.rs @@ -3,7 +3,7 @@ // only-mips64 // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index e705d5ce3cd72..49fd015624ace 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -1,7 +1,7 @@ // compile-flags: -C no-prepopulate-passes #![crate_type="lib"] -#![feature(repr_simd, transparent_enums, transparent_unions)] +#![feature(repr_simd, transparent_unions)] use std::marker::PhantomData; diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.rs b/src/test/ui/feature-gates/feature-gate-transparent_enums.rs deleted file mode 100644 index 0a7a73a168ed5..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-transparent_enums.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[repr(transparent)] -enum OkButUnstableEnum { //~ ERROR transparent enums are unstable - Foo((), String, ()), -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr deleted file mode 100644 index 8e727c33f20f8..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: transparent enums are unstable - --> $DIR/feature-gate-transparent_enums.rs:2:1 - | -LL | enum OkButUnstableEnum { - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/60405 - = help: add `#![feature(transparent_enums)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/lint/lint-ctypes-enum.rs b/src/test/ui/lint/lint-ctypes-enum.rs index 3898e67a07f7e..ccda005575c6e 100644 --- a/src/test/ui/lint/lint-ctypes-enum.rs +++ b/src/test/ui/lint/lint-ctypes-enum.rs @@ -1,4 +1,4 @@ -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![feature(ptr_internals)] #![deny(improper_ctypes)] #![allow(dead_code)] diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs index 730d428ff500b..969a323238ff5 100644 --- a/src/test/ui/repr/repr-transparent.rs +++ b/src/test/ui/repr/repr-transparent.rs @@ -3,7 +3,7 @@ // - repr-transparent-other-reprs.rs // - repr-transparent-other-items.rs -#![feature(repr_align, transparent_enums, transparent_unions)] +#![feature(transparent_unions)] use std::marker::PhantomData; From 25460ebef6ae94494fc89a736a2f51bef2ea55c3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 12 Jan 2020 16:05:18 +0100 Subject: [PATCH 0514/1253] transparent_enums: test alignment --- src/test/ui/repr/repr-transparent.rs | 10 ++++++++++ src/test/ui/repr/repr-transparent.stderr | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs index 969a323238ff5..8fbdb4cc80b5e 100644 --- a/src/test/ui/repr/repr-transparent.rs +++ b/src/test/ui/repr/repr-transparent.rs @@ -60,6 +60,16 @@ enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but Bar, } +#[repr(transparent)] +enum NontrivialAlignZstEnum { + Foo(u32, [u16; 0]), //~ ERROR alignment larger than 1 +} + +#[repr(transparent)] +enum GenericAlignEnum { + Foo { bar: ZstAlign32, baz: u32 } //~ ERROR alignment larger than 1 +} + #[repr(transparent)] union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0 u: (), diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr index f0c1fbe8ac9e1..cbc74fbb6a2cf 100644 --- a/src/test/ui/repr/repr-transparent.stderr +++ b/src/test/ui/repr/repr-transparent.stderr @@ -94,14 +94,26 @@ LL | Foo(String), LL | Bar, | --- too many variants in `TooManyVariants` +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:65:14 + | +LL | Foo(u32, [u16; 0]), + | ^^^^^^^^ has alignment larger than 1 + +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:70:11 + | +LL | Foo { bar: ZstAlign32, baz: u32 } + | ^^^^^^^^^^^^^^^^^^ has alignment larger than 1 + error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0 - --> $DIR/repr-transparent.rs:64:1 + --> $DIR/repr-transparent.rs:74:1 | LL | union UnitUnion { | ^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0 error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2 - --> $DIR/repr-transparent.rs:69:1 + --> $DIR/repr-transparent.rs:79:1 | LL | union TooManyFields { | ^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 2 @@ -110,7 +122,7 @@ LL | u: u32, LL | s: i32 | ------ this field is non-zero-sized -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0084, E0690, E0691, E0731. For more information about an error, try `rustc --explain E0084`. From 31095d7e3799e1e9d403ac88fa10b3906eb8ba37 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 16 Jan 2020 13:21:10 +0100 Subject: [PATCH 0515/1253] Make sure that all upstream generics get re-exported from Rust dylibs. --- src/librustc/middle/exported_symbols.rs | 21 +++- src/librustc/query/mod.rs | 8 ++ src/librustc_codegen_ssa/back/linker.rs | 13 +- .../back/symbol_export.rs | 30 +++++ src/librustc_codegen_ssa/back/write.rs | 4 +- src/librustc_codegen_utils/symbol_names.rs | 112 ++++++++++++------ 6 files changed, 140 insertions(+), 48 deletions(-) diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index e4af54f7771ea..a349b34eb1a0c 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -32,7 +32,9 @@ pub enum ExportedSymbol<'tcx> { } impl<'tcx> ExportedSymbol<'tcx> { - pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName { + /// This is the symbol name of an instance if it is instantiated in the + /// local crate. + pub fn symbol_name_for_local_instance(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName { match *self { ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, substs) => { @@ -50,9 +52,22 @@ impl<'tcx> ExportedSymbol<'tcx> { } ExportedSymbol::Generic(..) | ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, }, - ExportedSymbol::Generic(..) => match *other { + ExportedSymbol::Generic(self_def_id, self_substs) => match *other { ExportedSymbol::NonGeneric(_) => cmp::Ordering::Greater, - ExportedSymbol::Generic(..) => self.symbol_name(tcx).cmp(&other.symbol_name(tcx)), + ExportedSymbol::Generic(other_def_id, other_substs) => { + // We compare the symbol names because they are cached as query + // results which makes them relatively cheap to access repeatedly. + // + // It might be even faster to build a local cache of stable IDs + // for sorting. Exported symbols are really only sorted once + // in order to make the `exported_symbols` query result stable. + let self_symbol_name = + tcx.symbol_name(ty::Instance::new(self_def_id, self_substs)); + let other_symbol_name = + tcx.symbol_name(ty::Instance::new(other_def_id, other_substs)); + + self_symbol_name.cmp(&other_symbol_name) + } ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, }, ExportedSymbol::NoDefId(self_symbol_name) => match *other { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index a20e011b91a75..b7aef0c44d9ee 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -557,6 +557,9 @@ rustc_queries! { desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } } + /// The `symbol_name` query provides the symbol name for calling a + /// given instance from the local crate. In particular, it will also + /// look up the correct symbol name of instances from upstream crates. query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName { no_force desc { "computing the symbol for `{}`", key } @@ -971,6 +974,11 @@ rustc_queries! { } Linking { + /// The list of symbols exported from the given crate. + /// + /// - All names contained in `exported_symbols(cnum)` are guaranteed to + /// correspond to a publicly visible symbol in `cnum` machine code. + /// - The `exported_symbols` sets of different crates do not intersect. query exported_symbols(_: CrateNum) -> Arc, SymbolExportLevel)>> { desc { "exported_symbols" } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 11f5d3007e6b4..4679f6501336c 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1103,7 +1103,11 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for &(symbol, level) in tcx.exported_symbols(LOCAL_CRATE).iter() { if level.is_below_threshold(export_threshold) { - symbols.push(symbol.symbol_name(tcx).to_string()); + symbols.push(symbol_export::symbol_name_for_instance_in_crate( + tcx, + symbol, + LOCAL_CRATE, + )); } } @@ -1124,12 +1128,7 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { continue; } - // FIXME rust-lang/rust#64319, rust-lang/rust#64872: - // We want to block export of generics from dylibs, - // but we must fix rust-lang/rust#65890 before we can - // do that robustly. - - symbols.push(symbol.symbol_name(tcx).to_string()); + symbols.push(symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum)); } } } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index a406b5f103b9d..bd44b4a38fd58 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -8,6 +8,7 @@ use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::Instance; use rustc::ty::{SymbolName, TyCtxt}; +use rustc_codegen_utils::symbol_names; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; @@ -358,3 +359,32 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel SymbolExportLevel::Rust } } + +/// This is the symbol name of the given instance instantiated in a specific crate. +pub fn symbol_name_for_instance_in_crate<'tcx>( + tcx: TyCtxt<'tcx>, + symbol: ExportedSymbol<'tcx>, + instantiating_crate: CrateNum, +) -> String { + // If this is something instantiated in the local crate then we might + // already have cached the name as a query result. + if instantiating_crate == LOCAL_CRATE { + return symbol.symbol_name_for_local_instance(tcx).to_string(); + } + + // This is something instantiated in an upstream crate, so we have to use + // the slower (because uncached) version of computing the symbol name. + match symbol { + ExportedSymbol::NonGeneric(def_id) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::mono(tcx, def_id), + instantiating_crate, + ), + ExportedSymbol::Generic(def_id, substs) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::new(def_id, substs), + instantiating_crate, + ), + ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), + } +} diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 801bfdea70d6c..049faff7c49ee 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -2,7 +2,7 @@ use super::command::Command; use super::link::{self, get_linker, remove}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; -use super::symbol_export::ExportedSymbols; +use super::symbol_export::{symbol_name_for_instance_in_crate, ExportedSymbols}; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION, @@ -956,7 +956,7 @@ fn start_executing_work( let symbols = tcx .exported_symbols(cnum) .iter() - .map(|&(s, lvl)| (s.symbol_name(tcx).to_string(), lvl)) + .map(|&(s, lvl)| (symbol_name_for_instance_in_crate(tcx, s, cnum), lvl)) .collect(); Arc::new(symbols) }; diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 450dcd3b6041c..96a74f96fcf60 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -91,8 +91,9 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::session::config::SymbolManglingVersion; use rustc::ty::query::Providers; +use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Instance, TyCtxt}; -use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::Node; use rustc_span::symbol::Symbol; @@ -102,15 +103,70 @@ use log::debug; mod legacy; mod v0; +/// This function computes the symbol name for the given `instance` and the +/// given instantiating crate. That is, if you know that instance X is +/// instantiated in crate Y, this is the symbol name this instance would have. +pub fn symbol_name_for_instance_in_crate( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + instantiating_crate: CrateNum, +) -> String { + compute_symbol_name(tcx, instance, || instantiating_crate) +} + pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - symbol_name: |tcx, instance| ty::SymbolName { name: symbol_name(tcx, instance) }, + *providers = Providers { symbol_name: symbol_name_provider, ..*providers }; +} - ..*providers - }; +// The `symbol_name` query provides the symbol name for calling a given +// instance from the local crate. In particular, it will also look up the +// correct symbol name of instances from upstream crates. +fn symbol_name_provider(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { + let symbol_name = compute_symbol_name(tcx, instance, || { + // This closure determines the instantiating crate for instances that + // need an instantiating-crate-suffix for their symbol name, in order + // to differentiate between local copies. + // + // For generics we might find re-usable upstream instances. For anything + // else we rely on their being a local copy available. + + if is_generic(instance.substs) { + let def_id = instance.def_id(); + + if !def_id.is_local() && tcx.sess.opts.share_generics() { + // If we are re-using a monomorphization from another crate, + // we have to compute the symbol hash accordingly. + let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id); + + upstream_monomorphizations + .and_then(|monos| monos.get(&instance.substs).cloned()) + // If there is no instance available upstream, there'll be + // one in the current crate. + .unwrap_or(LOCAL_CRATE) + } else { + // For generic functions defined in the current crate, there + // can be no upstream instances. Also, if we don't share + // generics, we'll instantiate a local copy too. + LOCAL_CRATE + } + } else { + // For non-generic things that need to avoid naming conflicts, we + // always instantiate a copy in the local crate. + LOCAL_CRATE + } + }); + + ty::SymbolName { name: Symbol::intern(&symbol_name) } } -fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { +/// Computes the symbol name for the given instance. This function will call +/// `compute_instantiating_crate` if it needs to factor the instantiating crate +/// into the symbol name. +fn compute_symbol_name( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + compute_instantiating_crate: impl FnOnce() -> CrateNum, +) -> String { let def_id = instance.def_id(); let substs = instance.substs; @@ -121,11 +177,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { if def_id.is_local() { if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)); + return tcx.sess.generate_plugin_registrar_symbol(disambiguator); } if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)); + return tcx.sess.generate_proc_macro_decls_symbol(disambiguator); } } @@ -162,29 +218,28 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id) { if let Some(name) = attrs.link_name { - return name; + return name.to_string(); } - return tcx.item_name(def_id); + return tcx.item_name(def_id).to_string(); } } if let Some(name) = attrs.export_name { // Use provided name - return name; + return name.to_string(); } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id); + return tcx.item_name(def_id).to_string(); } - let is_generic = substs.non_erasable_generics().next().is_some(); let avoid_cross_crate_conflicts = // If this is an instance of a generic function, we also hash in // the ID of the instantiating crate. This avoids symbol conflicts // in case the same instances is emitted in two crates of the same // project. - is_generic || + is_generic(substs) || // If we're dealing with an instance of a function that's inlined from // another crate but we're marking it as globally shared to our @@ -197,25 +252,8 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { _ => false, }; - let instantiating_crate = if avoid_cross_crate_conflicts { - Some(if is_generic { - if !def_id.is_local() && tcx.sess.opts.share_generics() { - // If we are re-using a monomorphization from another crate, - // we have to compute the symbol hash accordingly. - let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id); - - upstream_monomorphizations - .and_then(|monos| monos.get(&substs).cloned()) - .unwrap_or(LOCAL_CRATE) - } else { - LOCAL_CRATE - } - } else { - LOCAL_CRATE - }) - } else { - None - }; + let instantiating_crate = + if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None }; // Pick the crate responsible for the symbol mangling version, which has to: // 1. be stable for each instance, whether it's being defined or imported @@ -232,10 +270,12 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { tcx.symbol_mangling_version(mangling_version_crate) }; - let mangled = match mangling_version { + match mangling_version { SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate), SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate), - }; + } +} - Symbol::intern(&mangled) +fn is_generic(substs: SubstsRef<'_>) -> bool { + substs.non_erasable_generics().next().is_some() } From ce6995f98eb371d9e24fd52362cbeeb6cbe5755b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 16 Jan 2020 15:09:49 +0100 Subject: [PATCH 0516/1253] Add regression test for shared-generics x dylibs (#67276). --- .../share-generics-dylib/Makefile | 22 +++++++++++++++++++ .../instance_provider_a.rs | 6 +++++ .../instance_provider_b.rs | 6 +++++ .../instance_user_a_rlib.rs | 9 ++++++++ .../instance_user_b_rlib.rs | 9 ++++++++ .../instance_user_dylib.rs | 7 ++++++ .../share-generics-dylib/linked_leaf.rs | 15 +++++++++++++ 7 files changed, 74 insertions(+) create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/Makefile create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs create mode 100644 src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs diff --git a/src/test/run-make-fulldeps/share-generics-dylib/Makefile b/src/test/run-make-fulldeps/share-generics-dylib/Makefile new file mode 100644 index 0000000000000..c6b5efcb4cdd8 --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/Makefile @@ -0,0 +1,22 @@ +# This test makes sure all generic instances get re-exported from Rust dylibs for use by +# `-Zshare-generics`. There are two rlibs (`instance_provider_a` and `instance_provider_b`) +# which both provide an instance of `Cell::set`. There is `instance_user_dylib` which is +# supposed to re-export both these instances, and then there are `instance_user_a_rlib` and +# `instance_user_b_rlib` which each rely on a specific instance to be available. +# +# In the end everything is linked together into `linked_leaf`. If `instance_user_dylib` does +# not export both then we'll get an `undefined reference` error for one of the instances. +# +# This is regression test for https://github.com/rust-lang/rust/issues/67276. + +-include ../../run-make-fulldeps/tools.mk + +COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Zsymbol-mangling-version=v0 + +all: + $(RUSTC) instance_provider_a.rs $(COMMON_ARGS) --crate-type=rlib + $(RUSTC) instance_provider_b.rs $(COMMON_ARGS) --crate-type=rlib + $(RUSTC) instance_user_dylib.rs $(COMMON_ARGS) --crate-type=dylib + $(RUSTC) instance_user_a_rlib.rs $(COMMON_ARGS) --crate-type=rlib + $(RUSTC) instance_user_b_rlib.rs $(COMMON_ARGS) --crate-type=rlib + $(RUSTC) linked_leaf.rs $(COMMON_ARGS) --crate-type=bin diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs new file mode 100644 index 0000000000000..b4e125ac0523a --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs @@ -0,0 +1,6 @@ +use std::cell::Cell; + +pub fn foo() { + let a: Cell = Cell::new(1); + a.set(123); +} diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs new file mode 100644 index 0000000000000..f613db873e6c6 --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs @@ -0,0 +1,6 @@ +use std::cell::Cell; + +pub fn foo() { + let b: Cell = Cell::new(1); + b.set(123); +} diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs new file mode 100644 index 0000000000000..c8e6ab95cf9ce --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs @@ -0,0 +1,9 @@ +extern crate instance_provider_a as upstream; +use std::cell::Cell; + +pub fn foo() { + upstream::foo(); + + let b: Cell = Cell::new(1); + b.set(123); +} diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs new file mode 100644 index 0000000000000..7c34af6d0dc87 --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs @@ -0,0 +1,9 @@ +extern crate instance_provider_b as upstream; +use std::cell::Cell; + +pub fn foo() { + upstream::foo(); + + let b: Cell = Cell::new(1); + b.set(123); +} diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs new file mode 100644 index 0000000000000..7c8368eec654b --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs @@ -0,0 +1,7 @@ +extern crate instance_provider_a; +extern crate instance_provider_b; + +pub fn foo() { + instance_provider_a::foo(); + instance_provider_b::foo(); +} diff --git a/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs b/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs new file mode 100644 index 0000000000000..e510dad691c57 --- /dev/null +++ b/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs @@ -0,0 +1,15 @@ +extern crate instance_user_dylib; +extern crate instance_user_a_rlib; +extern crate instance_user_b_rlib; + +use std::cell::Cell; + +fn main() { + + instance_user_a_rlib::foo(); + instance_user_b_rlib::foo(); + instance_user_dylib::foo(); + + let a: Cell = Cell::new(1); + a.set(123); +} From 0a9bcb0adf191897612e96a66b97ec8e1cff7412 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 16 Jan 2020 15:18:11 +0100 Subject: [PATCH 0517/1253] Add regression test for #64319 back in. The regression test is originally from #64324 but was removed again after the fix in there turned out to break other things. --- .../run-make-fulldeps/issue64319/Makefile | 39 +++++++++++++++++++ src/test/run-make-fulldeps/issue64319/bar.rs | 5 +++ src/test/run-make-fulldeps/issue64319/foo.rs | 9 +++++ 3 files changed, 53 insertions(+) create mode 100644 src/test/run-make-fulldeps/issue64319/Makefile create mode 100644 src/test/run-make-fulldeps/issue64319/bar.rs create mode 100644 src/test/run-make-fulldeps/issue64319/foo.rs diff --git a/src/test/run-make-fulldeps/issue64319/Makefile b/src/test/run-make-fulldeps/issue64319/Makefile new file mode 100644 index 0000000000000..5592f5a71fff1 --- /dev/null +++ b/src/test/run-make-fulldeps/issue64319/Makefile @@ -0,0 +1,39 @@ +-include ../../run-make-fulldeps/tools.mk + +# Different optimization levels imply different values for `-Zshare-generics`, +# so try out a whole bunch of combinations to make sure everything is compatible +all: + # First up, try some defaults + $(RUSTC) --crate-type rlib foo.rs + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 + + # Next try mixing up some things explicitly + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + + # Now combine a whole bunch of options together + $(RUSTC) --crate-type rlib foo.rs + $(RUSTC) --crate-type dylib bar.rs + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=yes diff --git a/src/test/run-make-fulldeps/issue64319/bar.rs b/src/test/run-make-fulldeps/issue64319/bar.rs new file mode 100644 index 0000000000000..3895c0b6cdbb3 --- /dev/null +++ b/src/test/run-make-fulldeps/issue64319/bar.rs @@ -0,0 +1,5 @@ +extern crate foo; + +pub fn bar() { + foo::foo(); +} diff --git a/src/test/run-make-fulldeps/issue64319/foo.rs b/src/test/run-make-fulldeps/issue64319/foo.rs new file mode 100644 index 0000000000000..c54a238e9add7 --- /dev/null +++ b/src/test/run-make-fulldeps/issue64319/foo.rs @@ -0,0 +1,9 @@ +pub fn foo() { + bar::(); +} + +pub fn bar() { + baz(); +} + +fn baz() {} From 12882a8392eb98e870628ffbab4e123b83466adf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 Jan 2020 23:28:34 +0100 Subject: [PATCH 0518/1253] Remove usage of global variable "inlined_types" --- src/librustdoc/html/render.rs | 55 +++++++++++++++++------------- src/librustdoc/html/static/main.js | 20 +++++++++-- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9406803825350..eb8a8956436d9 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -992,13 +992,11 @@ themePicker.onblur = handleThemeButtonsBlur; writeln!(v, "{}", *implementor).unwrap(); } v.push_str( - r" - if (window.register_implementors) { - window.register_implementors(implementors); - } else { - window.pending_implementors = implementors; - } - ", + "if (window.register_implementors) {\ + window.register_implementors(implementors);\ + } else {\ + window.pending_implementors = implementors;\ + }", ); v.push_str("})()"); cx.shared.fs.write(&mydst, &v)?; @@ -2353,6 +2351,7 @@ fn render_implementor( implementor: &Impl, w: &mut Buffer, implementor_dups: &FxHashMap<&str, (DefId, bool)>, + aliases: &[String], ) { // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` @@ -2375,6 +2374,7 @@ fn render_implementor( Some(use_absolute), false, false, + aliases, ); } @@ -2396,6 +2396,7 @@ fn render_impls(cx: &Context, w: &mut Buffer, traits: &[&&Impl], containing_item None, false, true, + &[], ); buffer.into_inner() }) @@ -2597,8 +2598,6 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) // If there are methods directly on this trait object, render them here. render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); - let mut synthetic_types = Vec::new(); - if let Some(implementors) = cx.cache.implementors.get(&it.def_id) { // The DefId is for the first Type found with that name. The bool is // if any Types with the same name but different DefId have been found. @@ -2649,6 +2648,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) None, true, false, + &[], ); } write_loading_content(w, ""); @@ -2661,7 +2661,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) "
", ); for implementor in concrete { - render_implementor(cx, implementor, w, &implementor_dups); + render_implementor(cx, implementor, w, &implementor_dups, &[]); } write_loading_content(w, "
"); @@ -2673,9 +2673,13 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) "
", ); for implementor in synthetic { - synthetic_types - .extend(collect_paths_for_type(implementor.inner_impl().for_.clone())); - render_implementor(cx, implementor, w, &implementor_dups); + render_implementor( + cx, + implementor, + w, + &implementor_dups, + &collect_paths_for_type(implementor.inner_impl().for_.clone()), + ); } write_loading_content(w, "
"); } @@ -2700,17 +2704,12 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) write_loading_content(w, ""); } } - write!( - w, - r#""#, - serde_json::to_string(&synthetic_types).unwrap(), - ); write!( w, - r#""#, + "", root_path = vec![".."; cx.current.len()].join("/"), path = if it.def_id.is_local() { cx.current.join("/") @@ -3392,6 +3391,7 @@ fn render_assoc_items( None, false, true, + &[], ); } } @@ -3602,6 +3602,9 @@ fn render_impl( use_absolute: Option, is_on_foreign_type: bool, show_default_items: bool, + // This argument is used to reference same type with different pathes to avoid duplication + // in documentation pages for trait with automatic implementations like "Send" and "Sync". + aliases: &[String], ) { if render_mode == RenderMode::Normal { let id = cx.derive_id(match i.inner_impl().trait_ { @@ -3614,8 +3617,13 @@ fn render_impl( } None => "impl".to_string(), }); + let aliases = if aliases.is_empty() { + String::new() + } else { + format!(" aliases=\"{}\"", aliases.join(",")) + }; if let Some(use_absolute) = use_absolute { - write!(w, "

", id); + write!(w, "

", id, aliases); fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute); if show_def_docs { for it in &i.inner_impl().items { @@ -3637,8 +3645,9 @@ fn render_impl( } else { write!( w, - "

{}", + "

{}", id, + aliases, i.inner_impl().print() ); } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 809d38a7ead8f..ec881d25dd2bf 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1895,6 +1895,22 @@ function getSearchElement() { var implementors = document.getElementById("implementors-list"); var synthetic_implementors = document.getElementById("synthetic-implementors-list"); + // This `inlined_types` variable is used to avoid having the same implementation showing + // up twice. For example "String" in the "Sync" doc page. + // + // By the way, this is only used by and useful for traits implemented automatically (like + // "Send" and "Sync"). + var inlined_types = new Set(); + onEachLazy(synthetic_implementors.getElementsByClassName("impl"), function(el) { + var aliases = el.getAttribute("aliases"); + if (!aliases) { + return; + } + aliases.split(",").forEach(function(alias) { + inlined_types.add(alias); + }); + }); + var libs = Object.getOwnPropertyNames(imp); var llength = libs.length; for (var i = 0; i < llength; ++i) { @@ -1911,10 +1927,10 @@ function getSearchElement() { if (struct.synthetic) { var stlength = struct.types.length; for (var k = 0; k < stlength; k++) { - if (window.inlined_types.has(struct.types[k])) { + if (inlined_types.has(struct.types[k])) { continue struct_loop; } - window.inlined_types.add(struct.types[k]); + inlined_types.add(struct.types[k]); } } From 6d218db26df424722d13db0ed3babae3cf450bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 20 Jan 2020 00:00:00 +0000 Subject: [PATCH 0519/1253] compiletest: Simplify multi-debugger support Previous implementation used a single mode type to store various pieces of otherwise loosely related information: * Whether debuginfo mode is in use or not. * Which debuggers should run in general. * Which debuggers are enabled for particular test case. The new implementation introduces a separation between those aspects. There is a single debuginfo mode parametrized by a debugger type. The debugger detection is performed first and a separate configuration is created for each detected debugger. The test cases are gathered independently for each debugger which makes it trivial to implement support for `ignore` / `only` conditions. Functional changes: * A single `debuginfo` entry point (rather than `debuginfo-cdb`, `debuginfo-gdb+lldb`, etc.). * Debugger name is included in the test name. * Test outputs are placed in per-debugger directory. * Fixed spurious hash mismatch. Previously, the config mode would change from `DebugInfoGdbLldb` (when collecting tests) to `DebugInfoGdb` or `DebugInfoLldb` (when running them) which would affect hash computation. * PYTHONPATH is additionally included in gdb hash. * lldb-python and lldb-python-dir are additionally included in lldb hash. --- src/bootstrap/test.rs | 8 -- src/tools/compiletest/src/common.rs | 49 ++++--- src/tools/compiletest/src/header.rs | 193 +++++++-------------------- src/tools/compiletest/src/main.rs | 189 ++++++++++++++------------ src/tools/compiletest/src/runtest.rs | 58 ++++---- 5 files changed, 211 insertions(+), 286 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 10e07489e1212..a186c16f1aa71 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -957,14 +957,6 @@ impl Step for Compiletest { } if suite == "debuginfo" { - let msvc = builder.config.build.contains("msvc"); - if mode == "debuginfo" { - return builder.ensure(Compiletest { - mode: if msvc { "debuginfo-cdb" } else { "debuginfo-gdb+lldb" }, - ..self - }); - } - builder .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target }); } diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 01001ff708c79..9cc19060cbddc 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -14,10 +14,7 @@ pub enum Mode { RunFail, RunPassValgrind, Pretty, - DebugInfoCdb, - DebugInfoGdbLldb, - DebugInfoGdb, - DebugInfoLldb, + DebugInfo, Codegen, Rustdoc, CodegenUnits, @@ -32,13 +29,9 @@ pub enum Mode { impl Mode { pub fn disambiguator(self) -> &'static str { // Pretty-printing tests could run concurrently, and if they do, - // they need to keep their output segregated. Same is true for debuginfo tests that - // can be run on cdb, gdb, and lldb. + // they need to keep their output segregated. match self { Pretty => ".pretty", - DebugInfoCdb => ".cdb", - DebugInfoGdb => ".gdb", - DebugInfoLldb => ".lldb", _ => "", } } @@ -52,10 +45,7 @@ impl FromStr for Mode { "run-fail" => Ok(RunFail), "run-pass-valgrind" => Ok(RunPassValgrind), "pretty" => Ok(Pretty), - "debuginfo-cdb" => Ok(DebugInfoCdb), - "debuginfo-gdb+lldb" => Ok(DebugInfoGdbLldb), - "debuginfo-lldb" => Ok(DebugInfoLldb), - "debuginfo-gdb" => Ok(DebugInfoGdb), + "debuginfo" => Ok(DebugInfo), "codegen" => Ok(Codegen), "rustdoc" => Ok(Rustdoc), "codegen-units" => Ok(CodegenUnits), @@ -77,10 +67,7 @@ impl fmt::Display for Mode { RunFail => "run-fail", RunPassValgrind => "run-pass-valgrind", Pretty => "pretty", - DebugInfoCdb => "debuginfo-cdb", - DebugInfoGdbLldb => "debuginfo-gdb+lldb", - DebugInfoGdb => "debuginfo-gdb", - DebugInfoLldb => "debuginfo-lldb", + DebugInfo => "debuginfo", Codegen => "codegen", Rustdoc => "rustdoc", CodegenUnits => "codegen-units", @@ -155,6 +142,29 @@ impl CompareMode { } } +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Debugger { + Cdb, + Gdb, + Lldb, +} + +impl Debugger { + fn to_str(&self) -> &'static str { + match self { + Debugger::Cdb => "cdb", + Debugger::Gdb => "gdb", + Debugger::Lldb => "lldb", + } + } +} + +impl fmt::Display for Debugger { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.to_str(), f) + } +} + /// Configuration for compiletest #[derive(Clone)] pub struct Config { @@ -208,6 +218,9 @@ pub struct Config { /// The test mode, compile-fail, run-fail, ui pub mode: Mode, + /// The debugger to use in debuginfo mode. Unset otherwise. + pub debugger: Option, + /// Run ignored tests pub run_ignored: bool, @@ -362,9 +375,11 @@ pub fn output_testname_unique( revision: Option<&str>, ) -> PathBuf { let mode = config.compare_mode.as_ref().map_or("", |m| m.to_str()); + let debugger = config.debugger.as_ref().map_or("", |m| m.to_str()); PathBuf::from(&testpaths.file.file_stem().unwrap()) .with_extra_extension(revision.unwrap_or("")) .with_extra_extension(mode) + .with_extra_extension(debugger) } /// Absolute path to the directory where all output for the given diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 691b8d3ccfd39..34f9ac037b4b8 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -6,52 +6,13 @@ use std::path::{Path, PathBuf}; use log::*; -use crate::common::{self, CompareMode, Config, FailMode, Mode, PassMode}; +use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode}; use crate::extract_gdb_version; use crate::util; #[cfg(test)] mod tests; -/// Whether to ignore the test. -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum Ignore { - /// Runs it. - Run, - /// Ignore it totally. - Ignore, - /// Ignore only the gdb test, but run the lldb test. - IgnoreGdb, - /// Ignore only the lldb test, but run the gdb test. - IgnoreLldb, -} - -impl Ignore { - pub fn can_run_gdb(&self) -> bool { - *self == Ignore::Run || *self == Ignore::IgnoreLldb - } - - pub fn can_run_lldb(&self) -> bool { - *self == Ignore::Run || *self == Ignore::IgnoreGdb - } - - pub fn no_gdb(&self) -> Ignore { - match *self { - Ignore::Run => Ignore::IgnoreGdb, - Ignore::IgnoreGdb => Ignore::IgnoreGdb, - _ => Ignore::Ignore, - } - } - - pub fn no_lldb(&self) -> Ignore { - match *self { - Ignore::Run => Ignore::IgnoreLldb, - Ignore::IgnoreLldb => Ignore::IgnoreLldb, - _ => Ignore::Ignore, - } - } -} - /// The result of parse_cfg_name_directive. #[derive(Clone, Copy, PartialEq, Debug)] enum ParsedNameDirective { @@ -59,16 +20,12 @@ enum ParsedNameDirective { NoMatch, /// Match. Match, - /// Mode was DebugInfoGdbLldb and this matched gdb. - MatchGdb, - /// Mode was DebugInfoGdbLldb and this matched lldb. - MatchLldb, } /// Properties which must be known very early, before actually running /// the test. pub struct EarlyProps { - pub ignore: Ignore, + pub ignore: bool, pub should_fail: bool, pub aux: Vec, pub aux_crate: Vec<(String, String)>, @@ -78,84 +35,61 @@ pub struct EarlyProps { impl EarlyProps { pub fn from_file(config: &Config, testfile: &Path) -> Self { let mut props = EarlyProps { - ignore: Ignore::Run, + ignore: false, should_fail: false, aux: Vec::new(), aux_crate: Vec::new(), revisions: vec![], }; - if config.mode == common::DebugInfoGdbLldb { - if config.lldb_python_dir.is_none() { - props.ignore = props.ignore.no_lldb(); - } - if config.gdb_version.is_none() { - props.ignore = props.ignore.no_gdb(); - } - } else if config.mode == common::DebugInfoCdb { - if config.cdb.is_none() { - props.ignore = Ignore::Ignore; - } - } - let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(); iter_header(testfile, None, &mut |ln| { // we should check if any only- exists and if it exists // and does not matches the current platform, skip the test - if props.ignore != Ignore::Ignore { + if !props.ignore { props.ignore = match config.parse_cfg_name_directive(ln, "ignore") { - ParsedNameDirective::Match => Ignore::Ignore, + ParsedNameDirective::Match => true, ParsedNameDirective::NoMatch => props.ignore, - ParsedNameDirective::MatchGdb => props.ignore.no_gdb(), - ParsedNameDirective::MatchLldb => props.ignore.no_lldb(), }; if config.has_cfg_prefix(ln, "only") { props.ignore = match config.parse_cfg_name_directive(ln, "only") { ParsedNameDirective::Match => props.ignore, - ParsedNameDirective::NoMatch => Ignore::Ignore, - ParsedNameDirective::MatchLldb => props.ignore.no_gdb(), - ParsedNameDirective::MatchGdb => props.ignore.no_lldb(), + ParsedNameDirective::NoMatch => true, }; } if ignore_llvm(config, ln) { - props.ignore = Ignore::Ignore; + props.ignore = true; } if config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln) { - props.ignore = Ignore::Ignore; + props.ignore = true; } if !rustc_has_profiler_support && config.parse_needs_profiler_support(ln) { - props.ignore = Ignore::Ignore; + props.ignore = true; } if !rustc_has_sanitizer_support && config.parse_needs_sanitizer_support(ln) { - props.ignore = Ignore::Ignore; + props.ignore = true; } if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) { - props.ignore = Ignore::Ignore; + props.ignore = true; } - } - if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb) - && props.ignore.can_run_gdb() - && ignore_gdb(config, ln) - { - props.ignore = props.ignore.no_gdb(); - } + if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) { + props.ignore = true; + } - if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoGdbLldb) - && props.ignore.can_run_lldb() - && ignore_lldb(config, ln) - { - props.ignore = props.ignore.no_lldb(); + if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) { + props.ignore = true; + } } if let Some(s) = config.parse_aux_build(ln) { @@ -881,70 +815,37 @@ impl Config { /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` /// or `normalize-stderr-32bit`. fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective { - if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') { - let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap(); - - if name == "test" || - &self.target == name || // triple - util::matches_os(&self.target, name) || // target - util::matches_env(&self.target, name) || // env - name == util::get_arch(&self.target) || // architecture - name == util::get_pointer_width(&self.target) || // pointer width - name == self.stage_id.split('-').next().unwrap() || // stage - (self.target != self.host && name == "cross-compile") || - match self.compare_mode { - Some(CompareMode::Nll) => name == "compare-mode-nll", - Some(CompareMode::Polonius) => name == "compare-mode-polonius", - None => false, - } || - (cfg!(debug_assertions) && name == "debug") - { - ParsedNameDirective::Match - } else { - match self.mode { - common::DebugInfoGdbLldb => { - if name == "gdb" { - ParsedNameDirective::MatchGdb - } else if name == "lldb" { - ParsedNameDirective::MatchLldb - } else { - ParsedNameDirective::NoMatch - } - } - common::DebugInfoCdb => { - if name == "cdb" { - ParsedNameDirective::Match - } else { - ParsedNameDirective::NoMatch - } - } - common::DebugInfoGdb => { - if name == "gdb" { - ParsedNameDirective::Match - } else { - ParsedNameDirective::NoMatch - } - } - common::DebugInfoLldb => { - if name == "lldb" { - ParsedNameDirective::Match - } else { - ParsedNameDirective::NoMatch - } - } - common::Pretty => { - if name == "pretty" { - ParsedNameDirective::Match - } else { - ParsedNameDirective::NoMatch - } - } - _ => ParsedNameDirective::NoMatch, - } - } - } else { - ParsedNameDirective::NoMatch + if !line.as_bytes().starts_with(prefix.as_bytes()) { + return ParsedNameDirective::NoMatch; + } + if line.as_bytes().get(prefix.len()) != Some(&b'-') { + return ParsedNameDirective::NoMatch; } + + let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap(); + + let is_match = name == "test" || + &self.target == name || // triple + util::matches_os(&self.target, name) || // target + util::matches_env(&self.target, name) || // env + name == util::get_arch(&self.target) || // architecture + name == util::get_pointer_width(&self.target) || // pointer width + name == self.stage_id.split('-').next().unwrap() || // stage + (self.target != self.host && name == "cross-compile") || + match self.compare_mode { + Some(CompareMode::Nll) => name == "compare-mode-nll", + Some(CompareMode::Polonius) => name == "compare-mode-polonius", + None => false, + } || + (cfg!(debug_assertions) && name == "debug") || + match self.debugger { + Some(Debugger::Cdb) => name == "cdb", + Some(Debugger::Gdb) => name == "gdb", + Some(Debugger::Lldb) => name == "lldb", + None => false, + }; + + if is_match { ParsedNameDirective::Match } else { ParsedNameDirective::NoMatch } } fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool { diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index efa9d05f16c38..0c8f4dd5eaaa1 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -8,9 +8,7 @@ extern crate test; use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; -use crate::common::{CompareMode, PassMode}; -use crate::common::{Config, TestPaths}; -use crate::common::{DebugInfoCdb, DebugInfoGdb, DebugInfoGdbLldb, DebugInfoLldb, Mode, Pretty}; +use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, Pretty, TestPaths}; use crate::util::logv; use env_logger; use getopts; @@ -26,7 +24,7 @@ use std::time::SystemTime; use test::ColorConfig; use walkdir::WalkDir; -use self::header::{EarlyProps, Ignore}; +use self::header::EarlyProps; #[cfg(test)] mod tests; @@ -50,7 +48,7 @@ fn main() { } log_config(&config); - run_tests(&config); + run_tests(config); } pub fn parse_config(args: Vec) -> Config { @@ -199,6 +197,7 @@ pub fn parse_config(args: Vec) -> Config { build_base: opt_path(matches, "build-base"), stage_id: matches.opt_str("stage-id").unwrap(), mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"), + debugger: None, run_ignored, filter: matches.free.first().cloned(), filter_exact: matches.opt_present("exact"), @@ -293,61 +292,7 @@ pub fn opt_str2(maybestr: Option) -> String { } } -pub fn run_tests(config: &Config) { - if config.target.contains("android") { - if config.mode == DebugInfoGdb || config.mode == DebugInfoGdbLldb { - println!( - "{} debug-info test uses tcp 5039 port.\ - please reserve it", - config.target - ); - - // android debug-info test uses remote debugger so, we test 1 thread - // at once as they're all sharing the same TCP port to communicate - // over. - // - // we should figure out how to lift this restriction! (run them all - // on different ports allocated dynamically). - env::set_var("RUST_TEST_THREADS", "1"); - } - } - - match config.mode { - // Note that we don't need to emit the gdb warning when - // DebugInfoGdbLldb, so it is ok to list that here. - DebugInfoGdbLldb | DebugInfoLldb => { - if let Some(lldb_version) = config.lldb_version.as_ref() { - if is_blacklisted_lldb_version(&lldb_version[..]) { - println!( - "WARNING: The used version of LLDB ({}) has a \ - known issue that breaks debuginfo tests. See \ - issue #32520 for more information. Skipping all \ - LLDB-based tests!", - lldb_version - ); - return; - } - } - - // Some older versions of LLDB seem to have problems with multiple - // instances running in parallel, so only run one test thread at a - // time. - env::set_var("RUST_TEST_THREADS", "1"); - } - - DebugInfoGdb => { - if config.remote_test_client.is_some() && !config.target.contains("android") { - println!( - "WARNING: debuginfo tests are not available when \ - testing with remote" - ); - return; - } - } - - DebugInfoCdb | _ => { /* proceed */ } - } - +pub fn run_tests(config: Config) { // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests. if let Mode::CodegenUnits = config.mode { let _ = fs::remove_dir_all("tmp/partitioning-tests"); @@ -366,8 +311,6 @@ pub fn run_tests(config: &Config) { } } - let opts = test_opts(config); - let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in // parallel (especially when we have lots and lots of child processes). // For context, see #8904 @@ -381,6 +324,25 @@ pub fn run_tests(config: &Config) { // Let tests know which target they're running as env::set_var("TARGET", &config.target); + let opts = test_opts(&config); + + let mut configs = Vec::new(); + if let Mode::DebugInfo = config.mode { + // Debugging emscripten code doesn't make sense today + if !config.target.contains("emscripten") { + configs.extend(configure_cdb(&config)); + configs.extend(configure_gdb(&config)); + configs.extend(configure_lldb(&config)); + } + } else { + configs.push(config); + }; + + let mut tests = Vec::new(); + for c in &configs { + make_tests(c, &mut tests); + } + let res = test::run_tests_console(&opts, tests); match res { Ok(true) => {} @@ -391,6 +353,72 @@ pub fn run_tests(config: &Config) { } } +fn configure_cdb(config: &Config) -> Option { + if config.cdb.is_none() { + return None; + } + + Some(Config { debugger: Some(Debugger::Cdb), ..config.clone() }) +} + +fn configure_gdb(config: &Config) -> Option { + if config.gdb_version.is_none() { + return None; + } + + if config.remote_test_client.is_some() && !config.target.contains("android") { + println!( + "WARNING: debuginfo tests are not available when \ + testing with remote" + ); + return None; + } + + if config.target.contains("android") { + println!( + "{} debug-info test uses tcp 5039 port.\ + please reserve it", + config.target + ); + + // android debug-info test uses remote debugger so, we test 1 thread + // at once as they're all sharing the same TCP port to communicate + // over. + // + // we should figure out how to lift this restriction! (run them all + // on different ports allocated dynamically). + env::set_var("RUST_TEST_THREADS", "1"); + } + + Some(Config { debugger: Some(Debugger::Gdb), ..config.clone() }) +} + +fn configure_lldb(config: &Config) -> Option { + if config.lldb_python_dir.is_none() { + return None; + } + + if let Some(lldb_version) = config.lldb_version.as_ref() { + if is_blacklisted_lldb_version(&lldb_version) { + println!( + "WARNING: The used version of LLDB ({}) has a \ + known issue that breaks debuginfo tests. See \ + issue #32520 for more information. Skipping all \ + LLDB-based tests!", + lldb_version + ); + return None; + } + } + + // Some older versions of LLDB seem to have problems with multiple + // instances running in parallel, so only run one test thread at a + // time. + env::set_var("RUST_TEST_THREADS", "1"); + + Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() }) +} + pub fn test_opts(config: &Config) -> test::TestOpts { test::TestOpts { exclude_should_panic: false, @@ -415,20 +443,18 @@ pub fn test_opts(config: &Config) -> test::TestOpts { } } -pub fn make_tests(config: &Config) -> Vec { +pub fn make_tests(config: &Config, tests: &mut Vec) { debug!("making tests from {:?}", config.src_base.display()); let inputs = common_inputs_stamp(config); - let mut tests = Vec::new(); collect_tests_from_dir( config, &config.src_base, &config.src_base, &PathBuf::new(), &inputs, - &mut tests, + tests, ) .expect(&format!("Could not read tests from {}", config.src_base.display())); - tests } /// Returns a stamp constructed from input files common to all test cases. @@ -570,13 +596,7 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec Vec format!("-{}", d), + None => String::new(), + }; let mode_suffix = match config.compare_mode { Some(ref mode) => format!(" ({})", mode.to_str()), None => String::new(), }; + test::DynTestName(format!( - "[{}{}] {}{}", + "[{}{}{}] {}{}", config.mode, + debugger, mode_suffix, path.display(), revision.map_or("".to_string(), |rev| format!("#{}", rev)) @@ -700,21 +726,10 @@ fn make_test_name( fn make_test_closure( config: &Config, - ignore: Ignore, testpaths: &TestPaths, revision: Option<&String>, ) -> test::TestFn { - let mut config = config.clone(); - if config.mode == DebugInfoGdbLldb { - // If both gdb and lldb were ignored, then the test as a whole - // would be ignored. - if !ignore.can_run_gdb() { - config.mode = DebugInfoLldb; - } else if !ignore.can_run_lldb() { - config.mode = DebugInfoGdb; - } - } - + let config = config.clone(); let testpaths = testpaths.clone(); let revision = revision.cloned(); test::DynTestFn(Box::new(move || { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3a114a0b71517..d1ee60d74e7e2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3,11 +3,10 @@ use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; use crate::common::{output_base_dir, output_base_name, output_testname_unique}; use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, Ui}; -use crate::common::{Codegen, CodegenUnits, Rustdoc}; +use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc}; use crate::common::{CompareMode, FailMode, PassMode}; use crate::common::{CompileFail, Pretty, RunFail, RunPassValgrind}; use crate::common::{Config, TestPaths}; -use crate::common::{DebugInfoCdb, DebugInfoGdb, DebugInfoGdbLldb, DebugInfoLldb}; use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT}; use crate::errors::{self, Error, ErrorKind}; use crate::header::TestProps; @@ -192,7 +191,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) { _ => { // android has its own gdb handling - if config.mode == DebugInfoGdb && config.gdb.is_none() { + if config.debugger == Some(Debugger::Gdb) && config.gdb.is_none() { panic!("gdb not available but debuginfo gdb debuginfo test requested"); } } @@ -234,21 +233,25 @@ pub fn compute_stamp_hash(config: &Config) -> String { let mut hash = DefaultHasher::new(); config.stage_id.hash(&mut hash); - if config.mode == DebugInfoCdb { - config.cdb.hash(&mut hash); - } + match config.debugger { + Some(Debugger::Cdb) => { + config.cdb.hash(&mut hash); + } - if config.mode == DebugInfoGdb || config.mode == DebugInfoGdbLldb { - match config.gdb { - None => env::var_os("PATH").hash(&mut hash), - Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash), - Some(ref s) => s.hash(&mut hash), - }; - } + Some(Debugger::Gdb) => { + config.gdb.hash(&mut hash); + env::var_os("PATH").hash(&mut hash); + env::var_os("PYTHONPATH").hash(&mut hash); + } - if config.mode == DebugInfoLldb || config.mode == DebugInfoGdbLldb { - env::var_os("PATH").hash(&mut hash); - env::var_os("PYTHONPATH").hash(&mut hash); + Some(Debugger::Lldb) => { + config.lldb_python.hash(&mut hash); + config.lldb_python_dir.hash(&mut hash); + env::var_os("PATH").hash(&mut hash); + env::var_os("PYTHONPATH").hash(&mut hash); + } + + None => {} } if let Ui = config.mode { @@ -309,13 +312,7 @@ impl<'test> TestCx<'test> { RunFail => self.run_rfail_test(), RunPassValgrind => self.run_valgrind_test(), Pretty => self.run_pretty_test(), - DebugInfoGdbLldb => { - self.run_debuginfo_gdb_test(); - self.run_debuginfo_lldb_test(); - } - DebugInfoCdb => self.run_debuginfo_cdb_test(), - DebugInfoGdb => self.run_debuginfo_gdb_test(), - DebugInfoLldb => self.run_debuginfo_lldb_test(), + DebugInfo => self.run_debuginfo_test(), Codegen => self.run_codegen_test(), Rustdoc => self.run_rustdoc_test(), CodegenUnits => self.run_codegen_units_test(), @@ -680,13 +677,20 @@ impl<'test> TestCx<'test> { self.compose_and_run_compiler(rustc, Some(src)) } + fn run_debuginfo_test(&self) { + match self.config.debugger.unwrap() { + Debugger::Cdb => self.run_debuginfo_cdb_test(), + Debugger::Gdb => self.run_debuginfo_gdb_test(), + Debugger::Lldb => self.run_debuginfo_lldb_test(), + } + } + fn run_debuginfo_cdb_test(&self) { assert!(self.revision.is_none(), "revisions not relevant here"); let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - mode: DebugInfoCdb, ..self.config.clone() }; @@ -765,7 +769,6 @@ impl<'test> TestCx<'test> { let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - mode: DebugInfoGdb, ..self.config.clone() }; @@ -999,7 +1002,6 @@ impl<'test> TestCx<'test> { let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - mode: DebugInfoLldb, ..self.config.clone() }; @@ -1887,8 +1889,8 @@ impl<'test> TestCx<'test> { rustc.arg(dir_opt); } - RunFail | RunPassValgrind | Pretty | DebugInfoCdb | DebugInfoGdbLldb | DebugInfoGdb - | DebugInfoLldb | Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest | Assembly => { + RunFail | RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RunMake + | CodegenUnits | JsDocTest | Assembly => { // do not use JSON output } } From fdef4f185ea6a1b560c1370c10ee561135af483d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 Jan 2020 13:14:33 -0500 Subject: [PATCH 0520/1253] Delete unused "next" variants from formatting infrastructure The formatting infrastructure stopped emitting these a while back, and in removing them we can simplify related code. --- src/libcore/fmt/mod.rs | 19 +++++++++++-------- src/libcore/fmt/rt/v1.rs | 6 ++++-- src/librustc_builtin_macros/format.rs | 13 +------------ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e68f3c58a3e07..64c270522d39d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -10,7 +10,6 @@ use crate::mem; use crate::num::flt2dec; use crate::ops::Deref; use crate::result; -use crate::slice; use crate::str; mod builders; @@ -234,7 +233,6 @@ pub struct Formatter<'a> { precision: Option, buf: &'a mut (dyn Write + 'a), - curarg: slice::Iter<'a, ArgumentV1<'a>>, args: &'a [ArgumentV1<'a>], } @@ -1044,7 +1042,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { align: rt::v1::Alignment::Unknown, fill: ' ', args: args.args, - curarg: args.args.iter(), }; let mut idx = 0; @@ -1117,7 +1114,6 @@ impl<'a> Formatter<'a> { // These only exist in the struct for the `run` method, // which won’t be used together with this method. - curarg: self.curarg.clone(), args: self.args, } } @@ -1134,9 +1130,17 @@ impl<'a> Formatter<'a> { self.precision = self.getcount(&arg.format.precision); // Extract the correct argument - let value = match arg.position { - rt::v1::Position::Next => *self.curarg.next().unwrap(), - rt::v1::Position::At(i) => self.args[i], + let value = { + #[cfg(bootstrap)] + { + match arg.position { + rt::v1::Position::At(i) => self.args[i], + } + } + #[cfg(not(bootstrap))] + { + self.args[arg.position] + } }; // Then actually do some printing @@ -1148,7 +1152,6 @@ impl<'a> Formatter<'a> { rt::v1::Count::Is(n) => Some(n), rt::v1::Count::Implied => None, rt::v1::Count::Param(i) => self.args[i].as_usize(), - rt::v1::Count::NextParam => self.curarg.next()?.as_usize(), } } diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs index 826ae36d2d100..fd81f93242b89 100644 --- a/src/libcore/fmt/rt/v1.rs +++ b/src/libcore/fmt/rt/v1.rs @@ -7,7 +7,10 @@ #[derive(Copy, Clone)] pub struct Argument { + #[cfg(bootstrap)] pub position: Position, + #[cfg(not(bootstrap))] + pub position: usize, pub format: FormatSpec, } @@ -37,12 +40,11 @@ pub enum Alignment { pub enum Count { Is(usize), Param(usize), - NextParam, Implied, } +#[cfg(bootstrap)] #[derive(Copy, Clone)] pub enum Position { - Next, At(usize), } diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index 6fca74e223944..3f4e24ca993db 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -590,17 +590,6 @@ impl<'a, 'b> Context<'a, 'b> { parse::NextArgument(ref arg) => { // Build the position let pos = { - let pos = |c, arg| { - let mut path = Context::rtpath(self.ecx, "Position"); - path.push(self.ecx.ident_of(c, sp)); - match arg { - Some(i) => { - let arg = self.ecx.expr_usize(sp, i); - self.ecx.expr_call_global(sp, path, vec![arg]) - } - None => self.ecx.expr_path(self.ecx.path_global(sp, path)), - } - }; match arg.position { parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => { // Map to index in final generated argument array @@ -615,7 +604,7 @@ impl<'a, 'b> Context<'a, 'b> { arg_idx } }; - pos("At", Some(arg_idx)) + self.ecx.expr_usize(sp, arg_idx) } // should never be the case, because names are already From 4919b96f81d9df0a7c0fe83ad5d66cef18ddfcfb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 Jan 2020 13:58:57 -0500 Subject: [PATCH 0521/1253] Move run/getcount to functions These are only called from one place and don't generally support being called from other places; furthermore, they're the only formatter functions that look at the `args` field (which a future commit will remove). --- src/libcore/fmt/mod.rs | 73 ++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 64c270522d39d..e76a8490f51fe 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1060,7 +1060,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { // a string piece. for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { formatter.buf.write_str(*piece)?; - formatter.run(arg)?; + run(&mut formatter, arg)?; idx += 1; } } @@ -1074,6 +1074,40 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Ok(()) } +fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument) -> Result { + // Fill in the format parameters into the formatter + fmt.fill = arg.format.fill; + fmt.align = arg.format.align; + fmt.flags = arg.format.flags; + fmt.width = getcount(&fmt.args, &arg.format.width); + fmt.precision = getcount(&fmt.args, &arg.format.precision); + + // Extract the correct argument + let value = { + #[cfg(bootstrap)] + { + match arg.position { + rt::v1::Position::At(i) => fmt.args[i], + } + } + #[cfg(not(bootstrap))] + { + fmt.args[arg.position] + } + }; + + // Then actually do some printing + (value.formatter)(value.value, fmt) +} + +fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option { + match *cnt { + rt::v1::Count::Is(n) => Some(n), + rt::v1::Count::Implied => None, + rt::v1::Count::Param(i) => args[i].as_usize(), + } +} + /// Padding after the end of something. Returned by `Formatter::padding`. #[must_use = "don't forget to write the post padding"] struct PostPadding { @@ -1118,43 +1152,6 @@ impl<'a> Formatter<'a> { } } - // First up is the collection of functions used to execute a format string - // at runtime. This consumes all of the compile-time statics generated by - // the format! syntax extension. - fn run(&mut self, arg: &rt::v1::Argument) -> Result { - // Fill in the format parameters into the formatter - self.fill = arg.format.fill; - self.align = arg.format.align; - self.flags = arg.format.flags; - self.width = self.getcount(&arg.format.width); - self.precision = self.getcount(&arg.format.precision); - - // Extract the correct argument - let value = { - #[cfg(bootstrap)] - { - match arg.position { - rt::v1::Position::At(i) => self.args[i], - } - } - #[cfg(not(bootstrap))] - { - self.args[arg.position] - } - }; - - // Then actually do some printing - (value.formatter)(value.value, self) - } - - fn getcount(&mut self, cnt: &rt::v1::Count) -> Option { - match *cnt { - rt::v1::Count::Is(n) => Some(n), - rt::v1::Count::Implied => None, - rt::v1::Count::Param(i) => self.args[i].as_usize(), - } - } - // Helper methods used for padding and processing formatting arguments that // all formatting traits can use. From 9ae32c9b27e5c13e6903c21856a403ec7067cadd Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 Jan 2020 14:09:50 -0500 Subject: [PATCH 0522/1253] Drop args from Formatter These are no longer used by Formatter methods. --- src/libcore/fmt/mod.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e76a8490f51fe..900ef63f1dfcc 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -233,7 +233,6 @@ pub struct Formatter<'a> { precision: Option, buf: &'a mut (dyn Write + 'a), - args: &'a [ArgumentV1<'a>], } // NB. Argument is essentially an optimized partially applied formatting function, @@ -1041,7 +1040,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { buf: output, align: rt::v1::Alignment::Unknown, fill: ' ', - args: args.args, }; let mut idx = 0; @@ -1060,7 +1058,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { // a string piece. for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { formatter.buf.write_str(*piece)?; - run(&mut formatter, arg)?; + run(&mut formatter, arg, &args.args)?; idx += 1; } } @@ -1074,25 +1072,24 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Ok(()) } -fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument) -> Result { - // Fill in the format parameters into the formatter +fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result { fmt.fill = arg.format.fill; fmt.align = arg.format.align; fmt.flags = arg.format.flags; - fmt.width = getcount(&fmt.args, &arg.format.width); - fmt.precision = getcount(&fmt.args, &arg.format.precision); + fmt.width = getcount(args, &arg.format.width); + fmt.precision = getcount(args, &arg.format.precision); // Extract the correct argument let value = { #[cfg(bootstrap)] { match arg.position { - rt::v1::Position::At(i) => fmt.args[i], + rt::v1::Position::At(i) => args[i], } } #[cfg(not(bootstrap))] { - fmt.args[arg.position] + args[arg.position] } }; @@ -1145,10 +1142,6 @@ impl<'a> Formatter<'a> { align: self.align, width: self.width, precision: self.precision, - - // These only exist in the struct for the `run` method, - // which won’t be used together with this method. - args: self.args, } } From 71450c7aadac3a94889744143127962c4e991f60 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Jan 2020 17:57:08 +0100 Subject: [PATCH 0523/1253] generalize bindings_with_variant_name lint --- .../hair/pattern/check_match.rs | 19 +++------- src/test/ui/lint/lint-uppercase-variables.rs | 10 +++++ .../ui/lint/lint-uppercase-variables.stderr | 38 ++++++++++++++++++- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index eac52da7ba4ae..ced0d5ed9359e 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -67,18 +67,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { hir::LocalSource::AwaitDesugar => ("`await` future binding", None), }; self.check_irrefutable(&loc.pat, msg, sp); - - // Check legality of move bindings and `@` patterns. self.check_patterns(false, &loc.pat); } - fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { - intravisit::walk_body(self, body); - - for param in body.params { - self.check_irrefutable(¶m.pat, "function argument", None); - self.check_patterns(false, ¶m.pat); - } + fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { + intravisit::walk_param(self, param); + self.check_irrefutable(¶m.pat, "function argument", None); + self.check_patterns(false, ¶m.pat); } } @@ -123,6 +118,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { if !self.tcx.features().bindings_after_at { check_legality_of_bindings_in_at_patterns(self, pat); } + check_for_bindings_named_same_as_variants(self, pat); } fn check_match( @@ -132,11 +128,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { source: hir::MatchSource, ) { for arm in arms { - // First, check legality of move bindings. + // Check the arm for some things unrelated to exhaustiveness. self.check_patterns(arm.guard.is_some(), &arm.pat); - - // Second, perform some lints. - check_for_bindings_named_same_as_variants(self, &arm.pat); } let module = self.tcx.hir().get_module_parent(scrut.hir_id); diff --git a/src/test/ui/lint/lint-uppercase-variables.rs b/src/test/ui/lint/lint-uppercase-variables.rs index 86a39502a81cc..a98b4f2fd4450 100644 --- a/src/test/ui/lint/lint-uppercase-variables.rs +++ b/src/test/ui/lint/lint-uppercase-variables.rs @@ -25,6 +25,16 @@ fn main() { //~^^^ WARN unused variable: `Foo` } + let Foo = foo::Foo::Foo; + //~^ ERROR variable `Foo` should have a snake case name + //~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo` + //~^^^ WARN unused variable: `Foo` + + fn in_param(Foo: foo::Foo) {} + //~^ ERROR variable `Foo` should have a snake case name + //~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo` + //~^^^ WARN unused variable: `Foo` + test(1); let _ = Something { X: 0 }; diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index b937832ac622d..a38f3e7626bca 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -6,6 +6,18 @@ LL | Foo => {} | = note: `#[warn(bindings_with_variant_name)]` on by default +warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` + --> $DIR/lint-uppercase-variables.rs:28:9 + | +LL | let Foo = foo::Foo::Foo; + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + +warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` + --> $DIR/lint-uppercase-variables.rs:33:17 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | @@ -19,6 +31,18 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` +warning: unused variable: `Foo` + --> $DIR/lint-uppercase-variables.rs:28:9 + | +LL | let Foo = foo::Foo::Foo; + | ^^^ help: consider prefixing with an underscore: `_Foo` + +warning: unused variable: `Foo` + --> $DIR/lint-uppercase-variables.rs:33:17 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: consider prefixing with an underscore: `_Foo` + error: structure field `X` should have a snake case name --> $DIR/lint-uppercase-variables.rs:10:5 | @@ -49,6 +73,18 @@ error: variable `Foo` should have a snake case name LL | Foo => {} | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo` -error: aborting due to 4 previous errors +error: variable `Foo` should have a snake case name + --> $DIR/lint-uppercase-variables.rs:28:9 + | +LL | let Foo = foo::Foo::Foo; + | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo` + +error: variable `Foo` should have a snake case name + --> $DIR/lint-uppercase-variables.rs:33:17 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0170`. From a804a455289cfa6d39ec92903959c4614c48d080 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 20 Jan 2020 12:17:12 -0500 Subject: [PATCH 0524/1253] Fix UI test fmt::Formatter is still not Send/Sync, but the UI test emitted two errors, for the dyn Write and the Void inside Formatter. As of this PR, the Void is now gone, but the dyn Write remains. --- src/test/ui/async-await/async-fn-nonsend.rs | 15 ++++++------ .../ui/async-await/async-fn-nonsend.stderr | 24 +------------------ 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs index 645c903c6bab2..ceeebbca5195a 100644 --- a/src/test/ui/async-await/async-fn-nonsend.rs +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -2,15 +2,15 @@ // edition:2018 // compile-flags: --crate-type lib -use std::{ - cell::RefCell, - fmt::Debug, - rc::Rc, -}; +use std::{cell::RefCell, fmt::Debug, rc::Rc}; -fn non_sync() -> impl Debug { RefCell::new(()) } +fn non_sync() -> impl Debug { + RefCell::new(()) +} -fn non_send() -> impl Debug { Rc::new(()) } +fn non_send() -> impl Debug { + Rc::new(()) +} fn take_ref(_: &T) {} @@ -53,5 +53,4 @@ pub fn pass_assert() { //~^ ERROR future cannot be sent between threads safely assert_send(non_sync_with_method_call()); //~^ ERROR future cannot be sent between threads safely - //~^^ ERROR future cannot be sent between threads safely } diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 5c870ca2d0276..105fd23ecfb66 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -62,27 +62,5 @@ LL | } LL | } | - `f` is later dropped here -error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:54:5 - | -LL | fn assert_send(_: impl Send) {} - | ----------- ---- required by this bound in `assert_send` -... -LL | assert_send(non_sync_with_method_call()); - | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` - | - = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` -note: future is not `Send` as this value is used across an await - --> $DIR/async-fn-nonsend.rs:43:9 - | -LL | let f: &mut std::fmt::Formatter = panic!(); - | - has type `&mut std::fmt::Formatter<'_>` -LL | if non_sync().fmt(f).unwrap() == () { -LL | fut().await; - | ^^^^^^^^^^^ await occurs here, with `f` maybe used later -LL | } -LL | } - | - `f` is later dropped here - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors From 3e0bfe1238e26ce57c2201172f0a4bb7cfbbba0a Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 20 Jan 2020 18:14:51 +0000 Subject: [PATCH 0525/1253] rustdoc: Correct order of `async` and `unsafe` in `async unsafe fn`s --- src/librustdoc/html/render.rs | 10 +++++----- src/test/rustdoc/async-fn.rs | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9406803825350..ab38eec5f3ea9 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2321,8 +2321,8 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func "{}{}{}{}{:#}fn {}{:#}", it.visibility.print_with_space(), f.header.constness.print_with_space(), - f.header.unsafety.print_with_space(), f.header.asyncness.print_with_space(), + f.header.unsafety.print_with_space(), print_abi_with_space(f.header.abi), it.name.as_ref().unwrap(), f.generics.print() @@ -2332,12 +2332,12 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func render_attributes(w, it, false); write!( w, - "{vis}{constness}{unsafety}{asyncness}{abi}fn \ + "{vis}{constness}{asyncness}{unsafety}{abi}fn \ {name}{generics}{decl}{where_clause}", vis = it.visibility.print_with_space(), constness = f.header.constness.print_with_space(), - unsafety = f.header.unsafety.print_with_space(), asyncness = f.header.asyncness.print_with_space(), + unsafety = f.header.unsafety.print_with_space(), abi = print_abi_with_space(f.header.abi), name = it.name.as_ref().unwrap(), generics = f.generics.print(), @@ -2832,8 +2832,8 @@ fn render_assoc_item( "{}{}{}{}{}{:#}fn {}{:#}", meth.visibility.print_with_space(), header.constness.print_with_space(), - header.unsafety.print_with_space(), header.asyncness.print_with_space(), + header.unsafety.print_with_space(), print_default_space(meth.is_default()), print_abi_with_space(header.abi), name, @@ -2854,8 +2854,8 @@ fn render_assoc_item( if parent == ItemType::Trait { " " } else { "" }, meth.visibility.print_with_space(), header.constness.print_with_space(), - header.unsafety.print_with_space(), header.asyncness.print_with_space(), + header.unsafety.print_with_space(), print_default_space(meth.is_default()), print_abi_with_space(header.abi), href = href, diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index 5f9708a39722a..5a03e821e8a2f 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -15,6 +15,11 @@ pub async fn baz(a: T) -> T { a } +// @has async_fn/fn.qux.html '//pre[@class="rust fn"]' 'pub async unsafe fn qux() -> char' +pub async unsafe fn qux() -> char { + '⚠' +} + trait Bar {} impl Bar for () {} @@ -26,8 +31,10 @@ pub async fn quux() -> impl Bar { // @has async_fn/struct.Foo.html // @matches - '//code' 'pub async fn f\(\)$' +// @matches - '//code' 'pub async unsafe fn g\(\)$' pub struct Foo; impl Foo { pub async fn f() {} + pub async unsafe fn g() {} } From 53924428692371a175afeaaa5fa410c44f0e06ae Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Mon, 20 Jan 2020 19:15:37 +0100 Subject: [PATCH 0526/1253] refactor fix using cfg_if! (fix build on Solaris) --- src/libstd/sys_common/net.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 7e603a8682ba5..135e8308afaea 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -44,6 +44,7 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris"))] { + use libc::c_uchar; type IpV4MultiCastType = c_uchar; } else { type IpV4MultiCastType = c_int; From 78f0c7fd6433c60d031311dacbf9a117b05e64b3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Jan 2020 19:46:06 +0100 Subject: [PATCH 0527/1253] check_match: unify some lowering code and fix some ICEs --- src/librustc_mir_build/hair/pattern/_match.rs | 9 ++--- .../hair/pattern/check_match.rs | 33 +++++++++++-------- .../issue-68393-let-pat-assoc-constant.rs | 26 +++++++++++++++ .../issue-68393-let-pat-assoc-constant.stderr | 15 +++++++++ .../issue-68394-let-pat-runtime-value.rs | 5 +++ .../issue-68394-let-pat-runtime-value.stderr | 9 +++++ .../ui/pattern/issue-68396-let-float-bug.rs | 7 ++++ .../pattern/issue-68396-let-float-bug.stderr | 15 +++++++++ 8 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs create mode 100644 src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr create mode 100644 src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs create mode 100644 src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr create mode 100644 src/test/ui/pattern/issue-68396-let-float-bug.rs create mode 100644 src/test/ui/pattern/issue-68396-let-float-bug.stderr diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 8fcaa1e8082fb..20183fd55c871 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -582,15 +582,12 @@ crate struct MatchCheckCtxt<'a, 'tcx> { } impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { - crate fn create_and_enter( + crate fn create_and_enter( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, module: DefId, - f: F, - ) -> R - where - F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R, - { + f: impl for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R, + ) -> R { let pattern_arena = TypedArena::default(); f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena }) diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index ced0d5ed9359e..5462d08e3cca9 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -121,6 +121,24 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { check_for_bindings_named_same_as_variants(self, pat); } + fn lower_pattern<'p>( + &self, + cx: &mut MatchCheckCtxt<'p, 'tcx>, + pat: &'tcx hir::Pat<'tcx>, + have_errors: &mut bool, + ) -> (&'p super::Pat<'tcx>, Ty<'tcx>) { + let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables); + patcx.include_lint_checks(); + let pattern = patcx.lower_pattern(pat); + let pattern_ty = pattern.ty; + let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern)); + if !patcx.errors.is_empty() { + *have_errors = true; + patcx.report_inlining_errors(pat.span); + } + (pattern, pattern_ty) + } + fn check_match( &mut self, scrut: &hir::Expr<'_>, @@ -139,14 +157,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { let inlined_arms: Vec<_> = arms .iter() .map(|arm| { - let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables); - patcx.include_lint_checks(); - let pattern = patcx.lower_pattern(&arm.pat); - let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern)); - if !patcx.errors.is_empty() { - patcx.report_inlining_errors(arm.pat.span); - have_errors = true; - } + let (pattern, _) = self.lower_pattern(cx, &arm.pat, &mut have_errors); (pattern, &*arm.pat, arm.guard.is_some()) }) .collect(); @@ -171,11 +182,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option) { let module = self.tcx.hir().get_module_parent(pat.hir_id); MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| { - let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables); - patcx.include_lint_checks(); - let pattern = patcx.lower_pattern(pat); - let pattern_ty = pattern.ty; - let pattern = cx.pattern_arena.alloc(expand_pattern(cx, pattern)); + let (pattern, pattern_ty) = self.lower_pattern(cx, pat, &mut false); let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect(); let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) { diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs new file mode 100644 index 0000000000000..95ead6b5d4a61 --- /dev/null +++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs @@ -0,0 +1,26 @@ +pub enum EFoo { + A, +} + +pub trait Foo { + const X: EFoo; +} + +struct Abc; + +impl Foo for Abc { + const X: EFoo = EFoo::A; +} + +struct Def; +impl Foo for Def { + const X: EFoo = EFoo::A; +} + +pub fn test(arg: EFoo, A::X: EFoo) { + //~^ ERROR associated consts cannot be referenced in patterns + let A::X = arg; + //~^ ERROR associated consts cannot be referenced in patterns +} + +fn main() {} diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr new file mode 100644 index 0000000000000..54ecc24981f80 --- /dev/null +++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr @@ -0,0 +1,15 @@ +error[E0158]: associated consts cannot be referenced in patterns + --> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40 + | +LL | pub fn test(arg: EFoo, A::X: EFoo) { + | ^^^^ + +error[E0158]: associated consts cannot be referenced in patterns + --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9 + | +LL | let A::X = arg; + | ^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0158`. diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs new file mode 100644 index 0000000000000..f10a7f2d8a54f --- /dev/null +++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 255u8; + let 0u8..=x = 0; + //~^ ERROR runtime values cannot be referenced in patterns +} diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr new file mode 100644 index 0000000000000..c1508bd71ff7a --- /dev/null +++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr @@ -0,0 +1,9 @@ +error[E0080]: runtime values cannot be referenced in patterns + --> $DIR/issue-68394-let-pat-runtime-value.rs:3:15 + | +LL | let 0u8..=x = 0; + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.rs b/src/test/ui/pattern/issue-68396-let-float-bug.rs new file mode 100644 index 0000000000000..afc599a4b22b6 --- /dev/null +++ b/src/test/ui/pattern/issue-68396-let-float-bug.rs @@ -0,0 +1,7 @@ +fn main() { + let 1234567890123456789012345678901234567890e-340: f64 = 0.0; + //~^ ERROR could not evaluate float literal (see issue #31407) + + fn param(1234567890123456789012345678901234567890e-340: f64) {} + //~^ ERROR could not evaluate float literal (see issue #31407) +} diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.stderr b/src/test/ui/pattern/issue-68396-let-float-bug.stderr new file mode 100644 index 0000000000000..618aa4b5021f1 --- /dev/null +++ b/src/test/ui/pattern/issue-68396-let-float-bug.stderr @@ -0,0 +1,15 @@ +error[E0080]: could not evaluate float literal (see issue #31407) + --> $DIR/issue-68396-let-float-bug.rs:2:9 + | +LL | let 1234567890123456789012345678901234567890e-340: f64 = 0.0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0080]: could not evaluate float literal (see issue #31407) + --> $DIR/issue-68396-let-float-bug.rs:5:14 + | +LL | fn param(1234567890123456789012345678901234567890e-340: f64) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. From 871e82b7d05435e6dc4ac5d0d4afe54396492ac7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Jan 2020 20:42:52 +0100 Subject: [PATCH 0528/1253] Add aliases attribute check --- src/test/rustdoc/auto_aliases.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/rustdoc/auto_aliases.rs diff --git a/src/test/rustdoc/auto_aliases.rs b/src/test/rustdoc/auto_aliases.rs new file mode 100644 index 0000000000000..7b52a69f5609f --- /dev/null +++ b/src/test/rustdoc/auto_aliases.rs @@ -0,0 +1,6 @@ +#![feature(optin_builtin_traits)] + +// @has auto_aliases/trait.Bar.html '//h3[@aliases="auto_aliases::Foo"]' 'impl Bar for Foo' +pub struct Foo; + +pub auto trait Bar {} From 4bb68828de9c424c572a7ec11417660478ca7501 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 18 Jan 2020 14:08:11 -0500 Subject: [PATCH 0529/1253] Read metadata from rmeta exclusively, if possible When we're producing an rlib, we do not need anything more than an rmeta file for each of our dependencies (this is indeed utilized by Cargo for pipelining). Previously, we were still storing the paths of possible rlib/dylib crates, which meant that they could still plausibly be accessed. With -Zbinary-dep-depinfo, that meant that Cargo thought that rustc was using both the rlib and an (earlier emitted) rmeta, and so needed a recompile, as the rlib may have finished writing *after* compilation started (for more detail, see issue 68149). This commit changes metadata loading to not store the filepaths of dylib/rlib if we're going to end up creating an rlib only. --- src/librustc_metadata/locator.rs | 44 +++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 4745ad02a3aa4..75182e32ae5b9 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -656,14 +656,36 @@ impl<'a> CrateLocator<'a> { dylibs: FxHashMap, ) -> Option<(Svh, Library)> { let mut slot = None; + // Order here matters, rmeta should come first. See comment in + // `extract_one` below. let source = CrateSource { - rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot), rmeta: self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot), + rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot), dylib: self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot), }; slot.map(|(svh, metadata)| (svh, Library { source, metadata })) } + fn needs_crate_flavor(&self, flavor: CrateFlavor) -> bool { + if flavor == CrateFlavor::Dylib && self.is_proc_macro == Some(true) { + return true; + } + + // The all loop is because `--crate-type=rlib --crate-type=rlib` is + // legal and produces both inside this type. + let is_rlib = self.sess.crate_types.borrow().iter().all(|c| *c == config::CrateType::Rlib); + let needs_object_code = self.sess.opts.output_types.should_codegen(); + // If we're producing an rlib, then we don't need object code. + // Or, if we're not producing object code, then we don't need it either + // (e.g., if we're a cdylib but emitting just metadata). + if is_rlib || !needs_object_code { + flavor == CrateFlavor::Rmeta + } else { + // we need all flavors (perhaps not true, but what we do for now) + true + } + } + // Attempts to extract *one* library from the set `m`. If the set has no // elements, `None` is returned. If the set has more than one element, then // the errors and notes are emitted about the set of libraries. @@ -681,12 +703,22 @@ impl<'a> CrateLocator<'a> { let mut ret: Option<(PathBuf, PathKind)> = None; let mut error = 0; + // If we are producing an rlib, and we've already loaded metadata, then + // we should not attempt to discover further crate sources (unless we're + // locating a proc macro; exact logic is in needs_crate_flavor). This means + // that under -Zbinary-dep-depinfo we will not emit a dependency edge on + // the *unused* rlib, and by returning `None` here immediately we + // guarantee that we do indeed not use it. + // + // See also #68149 which provides more detail on why emitting the + // dependency on the rlib is a bad thing. + // + // We currenty do not verify that these other sources are even in sync, + // and this is arguably a bug (see #10786), but because reading metadata + // is quite slow (especially from dylibs) we currently do not read it + // from the other crate sources. if slot.is_some() { - // FIXME(#10786): for an optimization, we only read one of the - // libraries' metadata sections. In theory we should - // read both, but reading dylib metadata is quite - // slow. - if m.is_empty() { + if m.is_empty() || !self.needs_crate_flavor(flavor) { return None; } else if m.len() == 1 { return Some(m.into_iter().next().unwrap()); From be663bf850fcdcedc678782e5e0945124d5791fb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 20 Jan 2020 15:35:43 -0500 Subject: [PATCH 0530/1253] Correct rmeta/rlib test --- src/test/ui/rmeta-rpass.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/test/ui/rmeta-rpass.rs b/src/test/ui/rmeta-rpass.rs index 5a63b5b8598bc..173a6a394eb05 100644 --- a/src/test/ui/rmeta-rpass.rs +++ b/src/test/ui/rmeta-rpass.rs @@ -1,6 +1,11 @@ // run-pass // Test that using rlibs and rmeta dep crates work together. Specifically, that -// there can be both an rmeta and an rlib file and rustc will prefer the rlib. +// there can be both an rmeta and an rlib file and rustc will prefer the rmeta +// file. +// +// This behavior is simply making sure this doesn't accidentally change; in this +// case we want to make sure that the rlib isn't being used as that would cause +// bugs in -Zbinary-dep-depinfo (see #68298). // aux-build:rmeta-rmeta.rs // aux-build:rmeta-rlib-rpass.rs @@ -9,5 +14,5 @@ extern crate rmeta_aux; use rmeta_aux::Foo; pub fn main() { - let _ = Foo { field: 42 }; + let _ = Foo { field2: 42 }; } From 2c0845c6ccfdee7fb255756918a22101376efa7e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 19 Jan 2020 22:08:15 +0100 Subject: [PATCH 0531/1253] Mark __msan_track_origins as an exported symbol for LTO --- src/librustc_codegen_ssa/back/symbol_export.rs | 8 +++++++- src/test/codegen/sanitizer-memory-track-orgins.rs | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index bd44b4a38fd58..c5989748560ce 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; -use rustc::session::config; +use rustc::session::config::{self, Sanitizer}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::Instance; @@ -206,6 +206,12 @@ fn exported_symbols_provider_local( })); } + if let Some(Sanitizer::Memory) = tcx.sess.opts.debugging_opts.sanitizer { + // Similar to profiling, preserve weak msan symbol during LTO. + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("__msan_track_origins")); + symbols.push((exported_symbol, SymbolExportLevel::C)); + } + if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) { let symbol_name = metadata_symbol_name(tcx); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name)); diff --git a/src/test/codegen/sanitizer-memory-track-orgins.rs b/src/test/codegen/sanitizer-memory-track-orgins.rs index fd8be0bced796..1fd496b35dfcc 100644 --- a/src/test/codegen/sanitizer-memory-track-orgins.rs +++ b/src/test/codegen/sanitizer-memory-track-orgins.rs @@ -4,17 +4,21 @@ // needs-sanitizer-support // only-linux // only-x86_64 -// revisions:MSAN-0 MSAN-1 MSAN-2 +// revisions:MSAN-0 MSAN-1 MSAN-2 MSAN-1-LTO MSAN-2-LTO // //[MSAN-0] compile-flags: -Zsanitizer=memory //[MSAN-1] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins=1 //[MSAN-2] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins +//[MSAN-1-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins=1 -C lto=fat +//[MSAN-2-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-memory-track-origins -C lto=fat #![crate_type="lib"] // MSAN-0-NOT: @__msan_track_origins // MSAN-1: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1 // MSAN-2: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2 +// MSAN-1-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1 +// MSAN-2-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2 // // MSAN-0-LABEL: define void @copy( // MSAN-1-LABEL: define void @copy( From 58eb03d20f08881d06334c38a3ae0da25a8924bc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Jan 2020 22:23:07 +0100 Subject: [PATCH 0532/1253] check_match: simplify check_arm --- Cargo.lock | 1 + src/librustc_mir_build/Cargo.toml | 1 + .../hair/pattern/check_match.rs | 103 +++++++----------- .../struct-pattern-match-useless.stderr | 4 +- 4 files changed, 46 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48bc269ebb654..cbb40f4e2a25e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3763,6 +3763,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_macros", + "rustc_session", "rustc_span", "rustc_target", "serialize", diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml index f0d1d4c6515ce..a22c4d18d516a 100644 --- a/src/librustc_mir_build/Cargo.toml +++ b/src/librustc_mir_build/Cargo.toml @@ -21,6 +21,7 @@ rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../libserialize", package = "serialize" } +rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 5462d08e3cca9..49b7c2d41fcbb 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -5,9 +5,6 @@ use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack} use super::{PatCtxt, PatKind, PatternError}; use rustc::hir::map::Map; -use rustc::lint; -use rustc::session::parse::feature_err; -use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -15,6 +12,10 @@ use rustc_hir::def::*; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{HirId, Pat}; +use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME; +use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS}; +use rustc_session::parse::feature_err; +use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::{MultiSpan, Span}; use syntax::ast::Mutability; @@ -156,9 +157,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { let inlined_arms: Vec<_> = arms .iter() - .map(|arm| { - let (pattern, _) = self.lower_pattern(cx, &arm.pat, &mut have_errors); - (pattern, &*arm.pat, arm.guard.is_some()) + .map(|hir::Arm { pat, guard, .. }| { + (self.lower_pattern(cx, pat, &mut have_errors).0, pat.hir_id, guard.is_some()) }) .collect(); @@ -285,7 +285,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa let ty_path = cx.tcx.def_path_str(edef.did); cx.tcx .struct_span_lint_hir( - lint::builtin::BINDINGS_WITH_VARIANT_NAME, + BINDINGS_WITH_VARIANT_NAME, p.hir_id, p.span, &format!( @@ -310,79 +310,63 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa } /// Checks for common cases of "catchall" patterns that may not be intended as such. -fn pat_is_catchall(pat: &Pat<'_>) -> bool { - match pat.kind { - hir::PatKind::Binding(.., None) => true, - hir::PatKind::Binding(.., Some(ref s)) => pat_is_catchall(s), - hir::PatKind::Ref(ref s, _) => pat_is_catchall(s), - hir::PatKind::Tuple(ref v, _) => v.iter().all(|p| pat_is_catchall(&p)), +fn pat_is_catchall(pat: &super::Pat<'_>) -> bool { + use super::PatKind::*; + match &*pat.kind { + Binding { subpattern: None, .. } => true, + Binding { subpattern: Some(s), .. } | Deref { subpattern: s } => pat_is_catchall(s), + Leaf { subpatterns: s } => s.iter().all(|p| pat_is_catchall(&p.pattern)), _ => false, } } +fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option) { + let mut err = tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern"); + if let Some(catchall) = catchall { + // We had a catchall pattern, hint at that. + err.span_label(span, "unreachable pattern"); + err.span_label(catchall, "matches any value"); + } + err.emit(); +} + +fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::MatchSource) { + let msg = match source { + hir::MatchSource::IfLetDesugar { .. } => "irrefutable if-let pattern", + hir::MatchSource::WhileLetDesugar => "irrefutable while-let pattern", + _ => bug!(), + }; + tcx.lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, msg); +} + /// Check for unreachable patterns. fn check_arms<'p, 'tcx>( cx: &mut MatchCheckCtxt<'p, 'tcx>, - arms: &[(&'p super::Pat<'tcx>, &hir::Pat<'_>, bool)], + arms: &[(&'p super::Pat<'tcx>, HirId, bool)], source: hir::MatchSource, ) -> Matrix<'p, 'tcx> { let mut seen = Matrix::empty(); let mut catchall = None; - for (arm_index, (pat, hir_pat, has_guard)) in arms.iter().enumerate() { + for (arm_index, (pat, id, has_guard)) in arms.iter().copied().enumerate() { let v = PatStack::from_pattern(pat); - - match is_useful(cx, &seen, &v, LeaveOutWitness, hir_pat.hir_id, true) { + match is_useful(cx, &seen, &v, LeaveOutWitness, id, true) { NotUseful => { match source { hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(), hir::MatchSource::IfLetDesugar { .. } | hir::MatchSource::WhileLetDesugar => { - // check which arm we're on. + // Check which arm we're on. match arm_index { // The arm with the user-specified pattern. - 0 => { - cx.tcx.lint_hir( - lint::builtin::UNREACHABLE_PATTERNS, - hir_pat.hir_id, - pat.span, - "unreachable pattern", - ); - } + 0 => unreachable_pattern(cx.tcx, pat.span, id, None), // The arm with the wildcard pattern. - 1 => { - let msg = match source { - hir::MatchSource::IfLetDesugar { .. } => { - "irrefutable if-let pattern" - } - hir::MatchSource::WhileLetDesugar => { - "irrefutable while-let pattern" - } - _ => bug!(), - }; - cx.tcx.lint_hir( - lint::builtin::IRREFUTABLE_LET_PATTERNS, - hir_pat.hir_id, - pat.span, - msg, - ); - } + 1 => irrefutable_let_pattern(cx.tcx, pat.span, id, source), _ => bug!(), } } hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => { - let mut err = cx.tcx.struct_span_lint_hir( - lint::builtin::UNREACHABLE_PATTERNS, - hir_pat.hir_id, - pat.span, - "unreachable pattern", - ); - // if we had a catchall pattern, hint at that - if let Some(catchall) = catchall { - err.span_label(pat.span, "unreachable pattern"); - err.span_label(catchall, "matches any value"); - } - err.emit(); + unreachable_pattern(cx.tcx, pat.span, id, catchall); } // Unreachable patterns in try and await expressions occur when one of @@ -392,19 +376,14 @@ fn check_arms<'p, 'tcx>( } Useful(unreachable_subpatterns) => { for pat in unreachable_subpatterns { - cx.tcx.lint_hir( - lint::builtin::UNREACHABLE_PATTERNS, - hir_pat.hir_id, - pat.span, - "unreachable pattern", - ); + unreachable_pattern(cx.tcx, pat.span, id, None); } } UsefulWithWitness(_) => bug!(), } if !has_guard { seen.push(v); - if catchall.is_none() && pat_is_catchall(hir_pat) { + if catchall.is_none() && pat_is_catchall(pat) { catchall = Some(pat.span); } } diff --git a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr index 5b0c9305448a7..0115fc081a970 100644 --- a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr +++ b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/struct-pattern-match-useless.rs:12:9 | +LL | Foo { x: _x, y: _y } => (), + | -------------------- matches any value LL | Foo { .. } => () - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern | note: lint level defined here --> $DIR/struct-pattern-match-useless.rs:1:9 From d8c661a88644ad710e309d3a8f0f27c5f74d705f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 21 Jan 2020 00:00:00 +0000 Subject: [PATCH 0533/1253] Mark __msan_keep_going as an exported symbol for LTO --- .../back/symbol_export.rs | 8 ++- src/test/codegen/sanitizer-recover.rs | 56 ++++++++++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index c5989748560ce..d680e14bbbd5b 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -208,8 +208,12 @@ fn exported_symbols_provider_local( if let Some(Sanitizer::Memory) = tcx.sess.opts.debugging_opts.sanitizer { // Similar to profiling, preserve weak msan symbol during LTO. - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("__msan_track_origins")); - symbols.push((exported_symbol, SymbolExportLevel::C)); + const MSAN_WEAK_SYMBOLS: [&str; 2] = ["__msan_track_origins", "__msan_keep_going"]; + + symbols.extend(MSAN_WEAK_SYMBOLS.iter().map(|sym| { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym)); + (exported_symbol, SymbolExportLevel::C) + })); } if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) { diff --git a/src/test/codegen/sanitizer-recover.rs b/src/test/codegen/sanitizer-recover.rs index a292332667b54..9a583725b0bf0 100644 --- a/src/test/codegen/sanitizer-recover.rs +++ b/src/test/codegen/sanitizer-recover.rs @@ -4,31 +4,47 @@ // needs-sanitizer-support // only-linux // only-x86_64 -// revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER +// revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER MSAN-RECOVER-LTO +// no-prefer-dynamic // -//[ASAN] compile-flags: -Zsanitizer=address -//[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -//[MSAN] compile-flags: -Zsanitizer=memory -//[MSAN-RECOVER] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory - -#![crate_type="lib"] +//[ASAN] compile-flags: -Zsanitizer=address +//[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address +//[MSAN] compile-flags: -Zsanitizer=memory +//[MSAN-RECOVER] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory +//[MSAN-RECOVER-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory -C lto=fat +// +// MSAN-NOT: @__msan_keep_going +// MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}} constant i32 1 +// MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}} constant i32 1 -// ASAN-LABEL: define i32 @penguin( +// ASAN-LABEL: define i32 @penguin( +// ASAN: call void @__asan_report_load4(i64 %0) +// ASAN: unreachable +// ASAN: } +// // ASAN-RECOVER-LABEL: define i32 @penguin( -// MSAN-LABEL: define i32 @penguin( +// ASAN-RECOVER: call void @__asan_report_load4_noabort( +// ASAN-RECOVER-NOT: unreachable +// ASAN: } +// +// MSAN-LABEL: define i32 @penguin( +// MSAN: call void @__msan_warning_noreturn() +// MSAN: unreachable +// MSAN: } +// // MSAN-RECOVER-LABEL: define i32 @penguin( +// MSAN-RECOVER: call void @__msan_warning() +// MSAN-RECOVER-NOT: unreachable +// MSAN-RECOVER: } +// +// MSAN-RECOVER-LTO-LABEL: define i32 @penguin( +// MSAN-RECOVER-LTO: call void @__msan_warning() +// MSAN-RECOVER-LTO-NOT: unreachable +// MSAN-RECOVER-LTO: } +// #[no_mangle] pub fn penguin(p: &mut i32) -> i32 { - // ASAN: call void @__asan_report_load4(i64 %0) - // ASAN: unreachable - // - // ASAN-RECOVER: call void @__asan_report_load4_noabort( - // ASAN-RECOVER-NOT: unreachable - // - // MSAN: call void @__msan_warning_noreturn() - // MSAN: unreachable - // - // MSAN-RECOVER: call void @__msan_warning() - // MSAN-RECOVER-NOT: unreachable *p } + +fn main() {} From dd0507c054ea27ae836025761908d339a478e0ab Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 20 Jan 2020 15:22:12 +0000 Subject: [PATCH 0534/1253] Make `TooGeneric` error in WF checking a proper error `TooGeneric` is encountered during WF checking when we cannot determine that a constant involving a generic parameter will always be evaluated successfully (rather than resulting in an error). In these cases, the burden of proof should be with the caller, so that we can avoid post-monomorphisation tim errors (which was the previous previous behaviour). This commit ensures that this situation produces a proper compiler error, rather than silently ignoring it or ICEing. --- src/librustc/traits/error_reporting/mod.rs | 34 +++++++++++++------ .../array-size-in-generic-struct-param.rs | 7 ++-- .../array-size-in-generic-struct-param.stderr | 20 ++++++++++- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 646cb80bffd94..f3dc79f0ff6b2 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -914,17 +914,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { report_object_safety_error(self.tcx, span, did, violations) } - // already reported in the query - ConstEvalFailure(err) => { - if let ErrorHandled::TooGeneric = err { - // Silence this error, as it can be produced during intermediate steps - // when a constant is not yet able to be evaluated (but will be later). - return; - } - self.tcx.sess.delay_span_bug( - span, - &format!("constant in type had an ignored error: {:?}", err), - ); + ConstEvalFailure(ErrorHandled::TooGeneric) => { + // In this instance, we have a const expression containing an unevaluated + // generic parameter. We have no idea whether this expression is valid or + // not (e.g. it might result in an error), but we don't want to just assume + // that it's okay, because that might result in post-monomorphisation time + // errors. The onus is really on the caller to provide values that it can + // prove are well-formed. + let mut err = self + .tcx + .sess + .struct_span_err(span, "constant expression depends on a generic parameter"); + // FIXME(const_generics): we should suggest to the user how they can resolve this + // issue. However, this is currently not actually possible + // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). + err.note("this may fail depending on what value the parameter takes"); + err + } + + // Already reported in the query. + ConstEvalFailure(ErrorHandled::Reported) => { + self.tcx + .sess + .delay_span_bug(span, &format!("constant in type had an ignored error")); return; } diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs index f3be7b56db589..d996bf56fcc10 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs @@ -1,10 +1,9 @@ -// run-pass - #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash #[allow(dead_code)] -struct ArithArrayLen([u32; 0 + N]); // ok +struct ArithArrayLen([u32; 0 + N]); +//~^ ERROR constant expression depends on a generic parameter #[derive(PartialEq, Eq)] struct Config { @@ -12,7 +11,7 @@ struct Config { } struct B { - arr: [u8; CFG.arr_size], // ok + arr: [u8; CFG.arr_size], //~ ERROR constant expression depends on a generic parameter } const C: Config = Config { arr_size: 5 }; diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr index 274f97697029e..6ae70c493b1dd 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr @@ -1,8 +1,26 @@ warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/array-size-in-generic-struct-param.rs:3:12 + --> $DIR/array-size-in-generic-struct-param.rs:1:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default +error: constant expression depends on a generic parameter + --> $DIR/array-size-in-generic-struct-param.rs:5:38 + | +LL | struct ArithArrayLen([u32; 0 + N]); + | ^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/array-size-in-generic-struct-param.rs:14:5 + | +LL | arr: [u8; CFG.arr_size], + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + From 1b800a567165ab4395daa82e215eaed84be5c8dc Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 21 Jan 2020 10:30:14 +0100 Subject: [PATCH 0535/1253] trade in outdated comments for correct ones --- src/liballoc/collections/btree/node.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f190209503d3e..37501a51e16e3 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -392,7 +392,6 @@ impl NodeRef { /// Borrows a view into the values stored in the node. /// The caller must ensure that the node is not the shared root. - /// This function is not public, so doesn't have to support shared roots like `keys` does. fn vals(&self) -> &[V] { self.reborrow().into_val_slice() } @@ -510,7 +509,6 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { } /// The caller must ensure that the node is not the shared root. - /// This function is not public, so doesn't have to support shared roots like `keys` does. fn keys_mut(&mut self) -> &mut [K] { unsafe { self.reborrow_mut().into_key_slice_mut() } } @@ -522,6 +520,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { } impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { + /// The caller must ensure that the node is not the shared root. fn into_key_slice(self) -> &'a [K] { debug_assert!(!self.is_shared_root()); // We cannot be the shared root, so `as_leaf` is okay. @@ -535,6 +534,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) } } + /// The caller must ensure that the node is not the shared root. fn into_slices(self) -> (&'a [K], &'a [V]) { let k = unsafe { ptr::read(&self) }; (k.into_key_slice(), self.into_val_slice()) From 6590339c31ab934add15ec49bc474ba9d78435e2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Jan 2020 13:33:48 +0100 Subject: [PATCH 0536/1253] Clean up E0205 explanation --- src/librustc_error_codes/error_codes/E0206.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0206.md b/src/librustc_error_codes/error_codes/E0206.md index fc4c0e07a16bf..da53b671ad0cc 100644 --- a/src/librustc_error_codes/error_codes/E0206.md +++ b/src/librustc_error_codes/error_codes/E0206.md @@ -1,12 +1,18 @@ -You can only implement `Copy` for a struct or enum. Both of the following -examples will fail, because neither `[u8; 256]` nor `&'static mut Bar` -(mutable reference to `Bar`) is a struct or enum: +The `Copy` trait was implemented on a type which is neither a struct nor an +enum. + +Erroneous code example: ```compile_fail,E0206 type Foo = [u8; 256]; -impl Copy for Foo { } // error +impl Copy for Foo { } // error! #[derive(Copy, Clone)] struct Bar; -impl Copy for &'static mut Bar { } // error + +impl Copy for &'static mut Bar { } // error! ``` + +You can only implement `Copy` for a struct or an enum. Both of the previous +examples will fail, because neither `[u8; 256]` nor `&'static mut Bar` +(mutable reference to `Bar`) is a struct or enum. From 6bd69a10921785aa8ab68e58d9c7a7ea1ff6ef96 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 21 Jan 2020 01:42:45 -0800 Subject: [PATCH 0537/1253] Add comment explaining `MaybeConstMaybe` lowering --- src/librustc_ast_lowering/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index bc922fa0f55a3..7163bf985ab97 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1254,6 +1254,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => { Some(this.lower_poly_trait_ref(ty, itctx.reborrow())) } + // `?const ?Bound` will cause an error during AST validation + // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait(_, TraitBoundModifier::Maybe) | GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => { None @@ -2301,6 +2303,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match f { TraitBoundModifier::None => hir::TraitBoundModifier::None, TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst, + + // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a + // placeholder for compilation to proceed. TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => { hir::TraitBoundModifier::Maybe } From c75a1f0e4dfd6e4a3929bc6496018734b5ef60c9 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Mon, 6 Jan 2020 13:04:14 +0100 Subject: [PATCH 0538/1253] Update RELEASES.md for 1.41.0 --- RELEASES.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index e3597473f62fd..0a5896a6665a7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,119 @@ +Version 1.41.0 (2020-01-30) +=========================== + +Language +-------- + +- [You can now pass type parameters to foreign items when implementing + traits.][65879] E.g. You can now write `impl From for Vec {}`. +- [You can now arbitrarily nest receiver types in the `self` position.][64325] E.g. you can + now write `fn foo(self: Box>) {}`. Previously only `Self`, `&Self`, + `&mut Self`, `Arc`, `Rc`, and `Box` were allowed. +- [You can now use any valid identifier in a `format_args` macro.][66847] + Previously identifiers starting with an underscore were not allowed. +- [Visibility modifiers (e.g. `pub`) are now syntactically allowed on trait items and + enum variants.][66183] These are still rejected semantically, but + can be seen and parsed by procedural macros and conditional compilation. + +Compiler +-------- + +- [Rustc will now warn if you have unused loop `'label`s.][66325] +- [Removed support for the `i686-unknown-dragonfly` target.][67255] +- [Added tier 3 support\* for the `riscv64gc-unknown-linux-gnu` target.][66661] +- [You can now pass an arguments file passing the `@path` syntax + to rustc.][66172] Note that the format differs somewhat from what is + found in other tooling; please see [the documentation][argfile-docs] for + more information. +- [You can now provide `--extern` flag without a path, indicating that it is + available from the search path or specified with an `-L` flag.][64882] + +\* Refer to Rust's [platform support page][forge-platform-support] for more +information on Rust's tiered platform support. + +[argfile-docs]: https://doc.rust-lang.org/nightly/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path + +Libraries +--------- + +- [The `core::panic` module is now stable.][66771] It was already stable + through `std`. +- [`NonZero*` numerics now implement `From` if it's a smaller integer + width.][66277] E.g. `NonZeroU16` now implements `From`. +- [`MaybeUninit` now implements `fmt::Debug`.][65013] + +Stabilized APIs +--------------- + +- [`Result::map_or`] +- [`Result::map_or_else`] +- [`std::rc::Weak::weak_count`] +- [`std::rc::Weak::strong_count`] +- [`std::sync::Weak::weak_count`] +- [`std::sync::Weak::strong_count`] + +Cargo +----- + +- [Cargo will now document all the private items for binary crates + by default.][cargo/7593] +- [`cargo-install` will now reinstall the package if it detects that it is out + of date.][cargo/7560] +- [Cargo.lock now uses a more git friendly format that should help to reduce + merge conflicts.][cargo/7579] +- [You can now override specific dependencies's build settings][cargo/7591] E.g. + `[profile.dev.overrides.image] opt-level = 2` sets the `image` crate's + optimisation level to `2` for debug builds. You can also use + `[profile..build_overrides]` to override build scripts and + their dependencies. + +Misc +---- + +- [You can now specify `edition` in documentation code blocks to compile the block + for that edition.][66238] E.g. `edition2018` tells rustdoc that the code sample + should be compiled the 2018 edition of Rust. +- [You can now provide custom themes to rustdoc with `--theme`, and check the + current theme with `--check-theme`.][54733] +- [You can use `#[doc(cfg(item))]` to document that a item is only available with + certain features.][61351] + +Compatibility Notes +------------------- + +- [As previously announced 1.41.0 will be the last tier 1 release for 32-bit + Apple targets.][apple-32bit-drop] This means that the source code is still + available to build, but the targets are no longer being tested and release + binaries for those platforms will no longer be distributed by the Rust project. + Please refer to the linked blog post for more information. + +[54733]: https://github.com/rust-lang/rust/pull/54733/ +[61351]: https://github.com/rust-lang/rust/pull/61351/ +[67255]: https://github.com/rust-lang/rust/pull/67255/ +[66661]: https://github.com/rust-lang/rust/pull/66661/ +[66771]: https://github.com/rust-lang/rust/pull/66771/ +[66847]: https://github.com/rust-lang/rust/pull/66847/ +[66238]: https://github.com/rust-lang/rust/pull/66238/ +[66277]: https://github.com/rust-lang/rust/pull/66277/ +[66325]: https://github.com/rust-lang/rust/pull/66325/ +[66172]: https://github.com/rust-lang/rust/pull/66172/ +[66183]: https://github.com/rust-lang/rust/pull/66183/ +[65879]: https://github.com/rust-lang/rust/pull/65879/ +[65013]: https://github.com/rust-lang/rust/pull/65013/ +[64882]: https://github.com/rust-lang/rust/pull/64882/ +[64325]: https://github.com/rust-lang/rust/pull/64325/ +[cargo/7560]: https://github.com/rust-lang/cargo/pull/7560/ +[cargo/7579]: https://github.com/rust-lang/cargo/pull/7579/ +[cargo/7591]: https://github.com/rust-lang/cargo/pull/7591/ +[cargo/7593]: https://github.com/rust-lang/cargo/pull/7593/ +[`Result::map_or_else`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or_else +[`Result::map_or`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or +[`std::rc::Weak::weak_count`]: https://doc.rust-lang.org/std/rc/struct.Weak.html#method.weak_count +[`std::rc::Weak::strong_count`]: https://doc.rust-lang.org/std/rc/struct.Weak.html#method.strong_count +[`std::sync::Weak::weak_count`]: https://doc.rust-lang.org/std/sync/struct.Weak.html#method.weak_count +[`std::sync::Weak::strong_count`]: https://doc.rust-lang.org/std/sync/struct.Weak.html#method.strong_count +[apple-32bit-drop]: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html + Version 1.40.0 (2019-12-19) =========================== From 14c002edb6a2e336dca09dca96df2b7228db95a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 15:33:17 +0100 Subject: [PATCH 0539/1253] tidy: fix most clippy warnings --- src/tools/tidy/src/debug_artifacts.rs | 2 +- src/tools/tidy/src/error_codes_check.rs | 4 ++-- src/tools/tidy/src/features.rs | 4 ++-- src/tools/tidy/src/features/version.rs | 2 +- src/tools/tidy/src/style.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs index 4664e2ef9a51c..408be83b926e2 100644 --- a/src/tools/tidy/src/debug_artifacts.rs +++ b/src/tools/tidy/src/debug_artifacts.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; -const GRAPHVIZ_POSTFLOW_MSG: &'static str = "`borrowck_graphviz_postflow` attribute in test"; +const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test"; pub fn check(path: &Path, bad: &mut bool) { let test_dir: PathBuf = path.join("test"); diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index ebaa81d2a8dbe..428c57d3ee822 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -53,7 +53,7 @@ fn extract_error_codes(f: &str, error_codes: &mut HashMap, path: & error_codes.insert(err_code.clone(), false); } // Now we extract the tests from the markdown file! - let md = some_or_continue!(s.splitn(2, "include_str!(\"").skip(1).next()); + let md = some_or_continue!(s.splitn(2, "include_str!(\"").nth(1)); let md_file_name = some_or_continue!(md.splitn(2, "\")").next()); let path = some_or_continue!(path.parent()).join(md_file_name); match read_to_string(&path) { @@ -84,7 +84,7 @@ fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap bool { } } } - return false; + false } pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features { @@ -344,7 +344,7 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features } None } else { - let s = issue_str.split('(').nth(1).unwrap().split(')').nth(0).unwrap(); + let s = issue_str.split('(').nth(1).unwrap().split(')').next().unwrap(); Some(s.parse().unwrap()) }; Some((name.to_owned(), Feature { level, since, has_gate_test: false, tracking_issue })) diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs index c8c39ad27e09f..620be2f985230 100644 --- a/src/tools/tidy/src/features/version.rs +++ b/src/tools/tidy/src/features/version.rs @@ -38,7 +38,7 @@ impl FromStr for Version { let parts = [part()?, part()?, part()?]; - if let Some(_) = iter.next() { + if iter.next().is_some() { // Ensure we don't have more than 3 parts. return Err(ParseVersionError::WrongNumberOfParts); } diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index b15c29921d2b2..4247fcb3b7f53 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -58,7 +58,7 @@ enum LIUState { fn line_is_url(columns: usize, line: &str) -> bool { // more basic check for error_codes.rs, to avoid complexity in implementing two state machines if columns == ERROR_CODE_COLS { - return line.starts_with("[") && line.contains("]:") && line.contains("http"); + return line.starts_with('[') && line.contains("]:") && line.contains("http"); } use self::LIUState::*; From 3e947ef031ae05c4ed56bbd6b3380bef644923f1 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 21 Jan 2020 16:12:19 +0100 Subject: [PATCH 0540/1253] Declare unsafe functions that can no longer handle shared roots --- src/liballoc/collections/btree/node.rs | 8 ++++---- src/liballoc/collections/btree/search.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 37501a51e16e3..d9cdebb4f7354 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -386,7 +386,7 @@ impl NodeRef { /// Borrows a view into the keys stored in the node. /// The caller must ensure that the node is not the shared root. - pub fn keys(&self) -> &[K] { + pub unsafe fn keys(&self) -> &[K] { self.reborrow().into_key_slice() } @@ -521,10 +521,10 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// The caller must ensure that the node is not the shared root. - fn into_key_slice(self) -> &'a [K] { + unsafe fn into_key_slice(self) -> &'a [K] { debug_assert!(!self.is_shared_root()); // We cannot be the shared root, so `as_leaf` is okay. - unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len()) } + slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len()) } /// The caller must ensure that the node is not the shared root. @@ -537,7 +537,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// The caller must ensure that the node is not the shared root. fn into_slices(self) -> (&'a [K], &'a [V]) { let k = unsafe { ptr::read(&self) }; - (k.into_key_slice(), self.into_val_slice()) + (unsafe { k.into_key_slice() }, self.into_val_slice()) } } diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 25e206f4f73db..579624cdd2b6a 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -64,9 +64,9 @@ where // Using `keys()` is fine here even if BorrowType is mutable, as all we return // is an index -- not a reference. let len = node.len(); - // Skip search for empty nodes because `keys()` does not work on shared roots. if len > 0 { - for (i, k) in node.keys().iter().enumerate() { + let keys = unsafe { node.keys() }; // safe because a non-empty node cannot be the shared root + for (i, k) in keys.iter().enumerate() { match key.cmp(k.borrow()) { Ordering::Greater => {} Ordering::Equal => return (i, true), From 32a81f774204dc77dbe11b011cbe769b4fd61476 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 21 Jan 2020 17:04:43 +0100 Subject: [PATCH 0541/1253] lowering: cleanup some hofs --- src/librustc_ast_lowering/expr.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index a24bb52150a72..5dc855e935c07 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -848,10 +848,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn with_catch_scope(&mut self, catch_id: NodeId, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_catch_scope(&mut self, catch_id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { let len = self.catch_scopes.len(); self.catch_scopes.push(catch_id); @@ -867,10 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> { result } - fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_loop_scope(&mut self, loop_id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { // We're no longer in the base loop's condition; we're in another loop. let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; @@ -892,10 +886,7 @@ impl<'hir> LoweringContext<'_, 'hir> { result } - fn with_loop_condition_scope(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { + fn with_loop_condition_scope(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = true; From 8abbd0beae79de5186158a759b08cb73d175b5ad Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 21 Jan 2020 17:18:37 +0100 Subject: [PATCH 0542/1253] for now, do not build rust-std for the armv7a-none-eabihf target it needs some upstream changes in the build script of the compiler-builtins crate --- src/ci/docker/dist-various-1/Dockerfile | 3 ++- src/tools/build-manifest/src/main.rs | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 9da18d600ba2f..2a68a25be21b3 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -161,7 +161,6 @@ ENV TARGETS=$TARGETS,armv7r-none-eabi ENV TARGETS=$TARGETS,armv7r-none-eabihf ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf ENV TARGETS=$TARGETS,armv7a-none-eabi -ENV TARGETS=$TARGETS,armv7a-none-eabihf # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not @@ -177,6 +176,8 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ CC_armv7a_none_eabi=arm-none-eabi-gcc \ CC_armv7a_none_eabihf=arm-none-eabi-gcc \ + CFLAGS_armv7a_none_eabi=-march=armv7-a \ + CFLAGS_armv7a_none_eabihf=-march=armv7-a+vfpv3 \ CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \ diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8281d20e4c886..c8d6580f7a1a5 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -70,7 +70,6 @@ static TARGETS: &[&str] = &[ "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "armv7a-none-eabi", - "armv7a-none-eabihf", "thumbv7neon-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", From d47673d3d7351c16aa8528edabfc886d2228fbb0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 21 Jan 2020 17:37:11 +0100 Subject: [PATCH 0543/1253] typeck: use diverges.replace(..) --- src/librustc_typeck/check/_match.rs | 6 ++---- src/librustc_typeck/check/expr.rs | 6 ++---- src/librustc_typeck/check/mod.rs | 7 ++----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index bd84547d45f9e..a6f8a82a480f2 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -50,10 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.warn_arms_when_scrutinee_diverges(arms, match_src); - // Otherwise, we have to union together the types that the - // arms produce and so forth. - let scrut_diverges = self.diverges.get(); - self.diverges.set(Diverges::Maybe); + // Otherwise, we have to union together the types that the arms produce and so forth. + let scrut_diverges = self.diverges.replace(Diverges::Maybe); // rust-lang/rust#55810: Typecheck patterns first (via eager // collection into `Vec`), so we get types for all bindings. diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 201a09fdc63fa..b4c2b85241f96 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -165,10 +165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Hide the outer diverging and has_errors flags. - let old_diverges = self.diverges.get(); - let old_has_errors = self.has_errors.get(); - self.diverges.set(Diverges::Maybe); - self.has_errors.set(false); + let old_diverges = self.diverges.replace(Diverges::Maybe); + let old_has_errors = self.has_errors.replace(false); let ty = self.check_expr_kind(expr, expected, needs); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f7df630fb90b1..7c0500c1c7425 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4418,10 +4418,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement"); // Hide the outer diverging and `has_errors` flags. - let old_diverges = self.diverges.get(); - let old_has_errors = self.has_errors.get(); - self.diverges.set(Diverges::Maybe); - self.has_errors.set(false); + let old_diverges = self.diverges.replace(Diverges::Maybe); + let old_has_errors = self.has_errors.replace(false); match stmt.kind { hir::StmtKind::Local(ref l) => { @@ -4431,7 +4429,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::StmtKind::Item(_) => {} hir::StmtKind::Expr(ref expr) => { // Check with expected type of `()`. - self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| { self.suggest_semicolon_at_end(expr.span, err); }); From 1240a3180d474f064791686602e324fe683a0645 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 21 Jan 2020 18:24:25 +0100 Subject: [PATCH 0544/1253] typeck: remove redundant diverges code --- src/librustc_typeck/check/_match.rs | 31 ++++++++--------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index a6f8a82a480f2..d339e3dbf5d68 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -53,25 +53,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise, we have to union together the types that the arms produce and so forth. let scrut_diverges = self.diverges.replace(Diverges::Maybe); - // rust-lang/rust#55810: Typecheck patterns first (via eager - // collection into `Vec`), so we get types for all bindings. - let all_arm_pats_diverge: Vec<_> = arms - .iter() - .map(|arm| { - let mut all_pats_diverge = Diverges::WarnedAlways; - self.diverges.set(Diverges::Maybe); - self.check_pat_top(&arm.pat, scrut_ty, Some(scrut.span), true); - all_pats_diverge &= self.diverges.get(); - - // As discussed with @eddyb, this is for disabling unreachable_code - // warnings on patterns (they're now subsumed by unreachable_patterns - // warnings). - match all_pats_diverge { - Diverges::Maybe => Diverges::Maybe, - Diverges::Always { .. } | Diverges::WarnedAlways => Diverges::WarnedAlways, - } - }) - .collect(); + // #55810: Type check patterns first so we get types for all bindings. + for arm in arms { + self.check_pat_top(&arm.pat, scrut_ty, Some(scrut.span), true); + } // Now typecheck the blocks. // @@ -102,11 +87,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { CoerceMany::with_coercion_sites(coerce_first, arms) }; - let mut other_arms = vec![]; // used only for diagnostics + let mut other_arms = vec![]; // Used only for diagnostics. let mut prior_arm_ty = None; - for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() { + for (i, arm) in arms.iter().enumerate() { if let Some(g) = &arm.guard { - self.diverges.set(pats_diverge); + self.diverges.set(Diverges::Maybe); match g { hir::Guard::If(e) => { self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {}) @@ -114,7 +99,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; } - self.diverges.set(pats_diverge); + self.diverges.set(Diverges::Maybe); let arm_ty = if source_if && if_no_else && i != 0 From 49d78fcd901700c5a14e19a6679db1646b5ca901 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Tue, 21 Jan 2020 13:13:26 +0100 Subject: [PATCH 0545/1253] Add GitHub issue templates --- .github/ISSUE_TEMPLATE/blank_issue.md | 4 ++ .github/ISSUE_TEMPLATE/bug_report.md | 44 ++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/ice.md | 52 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/tracking_issue.md | 58 ++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/blank_issue.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/ice.md create mode 100644 .github/ISSUE_TEMPLATE/tracking_issue.md diff --git a/.github/ISSUE_TEMPLATE/blank_issue.md b/.github/ISSUE_TEMPLATE/blank_issue.md new file mode 100644 index 0000000000000..9aef3ebe637a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank_issue.md @@ -0,0 +1,4 @@ +--- +name: Blank Issue +about: Create a blank issue. +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000000..5675579bc964a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,44 @@ +--- +name: Bug Report +about: Create a bug report for Rust. +labels: C-bug +--- + + +I tried this code: + +```rust + +``` + +I expected to see this happen: *explanation* + +Instead, this happened: *explanation* + +### Meta + + +`rustc --version --verbose`: +``` + +``` + + +
Backtrace +

+ +``` + +``` + +

+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000..bd7dc0ac95c1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Rust Programming Language Forum + url: https://users.rust-lang.org + about: Please ask and answer questions about Rust here. diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md new file mode 100644 index 0000000000000..e669e4912f8c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ice.md @@ -0,0 +1,52 @@ +--- +name: Internal Compiler Error +about: Create a report for an internal compiler error in rustc. +labels: C-bug, I-ICE, T-compiler +--- + + +### Code + +``` + +``` + + +### Meta + + +`rustc --version --verbose`: +``` + +``` + +### Error output + +``` + +``` + + +
Backtrace +

+ +``` + +``` + +

+
+ diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md new file mode 100644 index 0000000000000..f93591204cd98 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -0,0 +1,58 @@ +--- +name: Tracking Issue +about: A tracking issue for a feature in Rust. +title: Tracking Issue for XXX +labels: C-tracking-issue +--- + + +This is a tracking issue for the RFC "XXX" (rust-lang/rfcs#NNN). +The feature gate for the issue is `#![feature(FFF)]`. + +### About tracking issues + +Tracking issues are used to record the overall progress of implementation. +They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions. +A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature. +Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. + +### Steps + + +- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring + instructions?) +- [ ] Adjust documentation ([see instructions on rustc-guide][doc-guide]) +- [ ] Stabilization PR ([see instructions on rustc-guide][stabilization-guide]) + +[stabilization-guide]: https://rust-lang.github.io/rustc-guide/stabilization_guide.html#stabilization-pr +[doc-guide]: https://rust-lang.github.io/rustc-guide/stabilization_guide.html#documentation-prs + +### Unresolved Questions + + +XXX --- list all the "unresolved questions" found in the RFC to ensure they are +not forgotten + +### Implementation history + + From 7dceff9b5b2e41855ff3ba2fab3a2ae41e965df5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 21 Jan 2020 18:47:58 +0100 Subject: [PATCH 0546/1253] typeck: remove redundant diverges check --- src/librustc_typeck/check/_match.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index d339e3dbf5d68..686cdfbc089b4 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -183,16 +183,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arms: &'tcx [hir::Arm<'tcx>], source: hir::MatchSource, ) { - if self.diverges.get().is_always() { - use hir::MatchSource::*; - let msg = match source { - IfDesugar { .. } | IfLetDesugar { .. } => "block in `if` expression", - WhileDesugar { .. } | WhileLetDesugar { .. } => "block in `while` expression", - _ => "arm", - }; - for arm in arms { - self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg); - } + use hir::MatchSource::*; + let msg = match source { + IfDesugar { .. } | IfLetDesugar { .. } => "block in `if` expression", + WhileDesugar { .. } | WhileLetDesugar { .. } => "block in `while` expression", + _ => "arm", + }; + for arm in arms { + self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg); } } From 5dee7dddf24a022184a743b714b5062e83516a87 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:49:23 +0100 Subject: [PATCH 0547/1253] Handle methods in try diagnostic The diagnostic for diagnostic for methods and trait provided methods would only show the empty string: error[E0277]: the `?` operator can only be used in that returns `Result` or `Option` (or another type that implements `std::ops::Try`) Handle the missing cases so it reads ``a method'' / ``an async method'' / ``a trait method'' respectively. Signed-off-by: Philipp Gesang --- .../traits/error_reporting/on_unimplemented.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs index 9f3fc91548b21..8f55540cae38a 100644 --- a/src/librustc/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -67,6 +67,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "a function" }) }) + } else if let hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| Some("a trait method")) + } else if let hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Method(sig, body_id), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async method" + } else { + "a method" + }) + }) } else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), .. From d45d8b1c7b6b725ab9d4f1d987a45a76c7510a47 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 21 Jan 2020 09:55:43 -0800 Subject: [PATCH 0548/1253] Update cargo, books --- Cargo.lock | 14 ++++++++++---- src/doc/book | 2 +- src/doc/embedded-book | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/tools/cargo | 2 +- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48bc269ebb654..741f2c532cd20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -307,7 +307,7 @@ dependencies = [ "glob", "hex 0.4.0", "home", - "humantime", + "humantime 2.0.0", "ignore", "im-rc", "jobserver", @@ -1013,7 +1013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" dependencies = [ "atty", - "humantime", + "humantime 1.3.0", "log", "regex", "termcolor", @@ -1026,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", - "humantime", + "humantime 1.3.0", "log", "regex", "termcolor", @@ -1454,6 +1454,12 @@ dependencies = [ "quick-error", ] +[[package]] +name = "humantime" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b6c53306532d3c8e8087b44e6580e10db51a023cf9b433cea2ac38066b92da" + [[package]] name = "hyper" version = "0.12.31" @@ -2647,7 +2653,7 @@ dependencies = [ "clap", "derive_more", "env_logger 0.6.2", - "humantime", + "humantime 1.3.0", "lazy_static 1.3.0", "log", "rls-span", diff --git a/src/doc/book b/src/doc/book index 5c5cfd2e94cd4..87dd684367857 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 5c5cfd2e94cd42632798d9bd3d1116133e128ac9 +Subproject commit 87dd6843678575f8dda962f239d14ef4be14b352 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 9493b7d4dc97e..4d78994915af1 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 9493b7d4dc97eda439bd8780f05ad7b234cd1cd7 +Subproject commit 4d78994915af1bde9a95c04a8c27d8dca066232a diff --git a/src/doc/reference b/src/doc/reference index e1157538e86d8..11e893fc1357b 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit e1157538e86d83df0cf95d5e33bd943f80d0248f +Subproject commit 11e893fc1357bc688418ddf1087c2b7aa25d154d diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 1d59403cb5269..1c2bd024d13f8 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 1d59403cb5269c190cc52a95584ecc280345495a +Subproject commit 1c2bd024d13f8011307e13386cf1fea2180352b5 diff --git a/src/tools/cargo b/src/tools/cargo index ad3dbe10e1e65..f6449ba236db3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ad3dbe10e1e654fb1f032a5dd9481d7cbaa00d65 +Subproject commit f6449ba236db31995255ac5e4cad4ab88296a7c6 From 02e66baac6882ef30e607d2bca98929f01758957 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:51:13 +0100 Subject: [PATCH 0549/1253] Test try diagnostics for impl and trait methods Signed-off-by: Philipp Gesang --- src/test/ui/try-on-option-diagnostics.rs | 29 ++++++++++++++++++++ src/test/ui/try-on-option-diagnostics.stderr | 28 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/test/ui/try-on-option-diagnostics.rs b/src/test/ui/try-on-option-diagnostics.rs index 65d5e29ec2f13..63d17414c313b 100644 --- a/src/test/ui/try-on-option-diagnostics.rs +++ b/src/test/ui/try-on-option-diagnostics.rs @@ -16,3 +16,32 @@ fn a_closure() -> u32 { }; a_closure() } + +fn a_method() -> u32 { + struct S; + + impl S { + fn a_method() { + let x: Option = None; + x?; //~ ERROR the `?` operator + } + } + + S::a_method(); + 22 +} + +fn a_trait_method() -> u32 { + struct S; + trait T { + fn a_trait_method() { + let x: Option = None; + x?; //~ ERROR the `?` operator + } + } + + impl T for S { } + + S::a_trait_method(); + 22 +} diff --git a/src/test/ui/try-on-option-diagnostics.stderr b/src/test/ui/try-on-option-diagnostics.stderr index ce3aca39fb8fb..c9dc3f1b87969 100644 --- a/src/test/ui/try-on-option-diagnostics.stderr +++ b/src/test/ui/try-on-option-diagnostics.stderr @@ -27,6 +27,32 @@ LL | | }; = help: the trait `std::ops::Try` is not implemented for `{integer}` = note: required by `std::ops::Try::from_error` -error: aborting due to 2 previous errors +error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `std::ops::Try`) + --> $DIR/try-on-option-diagnostics.rs:26:13 + | +LL | / fn a_method() { +LL | | let x: Option = None; +LL | | x?; + | | ^^ cannot use the `?` operator in a method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `std::ops::Try` is not implemented for `()` + = note: required by `std::ops::Try::from_error` + +error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `std::ops::Try`) + --> $DIR/try-on-option-diagnostics.rs:39:13 + | +LL | / fn a_trait_method() { +LL | | let x: Option = None; +LL | | x?; + | | ^^ cannot use the `?` operator in a trait method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `std::ops::Try` is not implemented for `()` + = note: required by `std::ops::Try::from_error` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. From ce7172da5142e3914f9461f7e968897959cab338 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 14 Jan 2020 00:42:19 +0100 Subject: [PATCH 0550/1253] Fix thumb target CI --- src/test/run-make/thumb-none-cortex-m/Makefile | 8 +++----- src/test/run-make/thumb-none-qemu/Makefile | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/run-make/thumb-none-cortex-m/Makefile b/src/test/run-make/thumb-none-cortex-m/Makefile index 6791c8ccdf138..36e51bcab6de2 100644 --- a/src/test/run-make/thumb-none-cortex-m/Makefile +++ b/src/test/run-make/thumb-none-cortex-m/Makefile @@ -10,10 +10,7 @@ # - thumbv7em-none-eabihf (Bare Cortex-M4F, M7F, FPU, hardfloat) # - thumbv7m-none-eabi (Bare Cortex-M3) -# only-thumbv6m-none-eabi -# only-thumbv7em-none-eabi -# only-thumbv7em-none-eabihf -# only-thumbv7m-none-eabi +# only-thumb # For cargo setting RUSTC := $(RUSTC_ORIGINAL) @@ -27,7 +24,8 @@ CRATE := cortex-m CRATE_URL := https://github.com/rust-embedded/cortex-m CRATE_SHA1 := a448e9156e2cb1e556e5441fd65426952ef4b927 # 0.5.0 -export RUSTFLAGS := --cap-lints=allow +# Don't make lints fatal, but they need to at least warn or they break Cargo's target info parsing. +export RUSTFLAGS := --cap-lints=warn all: env diff --git a/src/test/run-make/thumb-none-qemu/Makefile b/src/test/run-make/thumb-none-qemu/Makefile index cb1ff8591221e..ab8b90e154eab 100644 --- a/src/test/run-make/thumb-none-qemu/Makefile +++ b/src/test/run-make/thumb-none-qemu/Makefile @@ -1,7 +1,6 @@ -include ../../run-make-fulldeps/tools.mk -# only-thumbv7m-none-eabi -# only-thumbv6m-none-eabi +# only-thumb # How to run this # $ ./x.py clean From ef5f929471c7b9769aac4d3e4aae5deeb7acaa3c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 14 Jan 2020 00:56:11 +0100 Subject: [PATCH 0551/1253] Account for run-make tests in `is_up_to_date` --- src/tools/compiletest/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index efa9d05f16c38..1f0b42d1786c1 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -624,7 +624,8 @@ fn is_up_to_date( // Check timestamps. let mut inputs = inputs.clone(); - inputs.add_path(&testpaths.file); + // Use `add_dir` to account for run-make tests, which use their individual directory + inputs.add_dir(&testpaths.file); for aux in &props.aux { let path = testpaths.file.parent().unwrap().join("auxiliary").join(aux); From ce36c98e5b732e64947a11fc233823716f16c2be Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jan 2020 11:11:28 +0100 Subject: [PATCH 0552/1253] Use the right runners for all thumb targets --- .../thumb-none-qemu/example/.cargo/config | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/test/run-make/thumb-none-qemu/example/.cargo/config b/src/test/run-make/thumb-none-qemu/example/.cargo/config index 0d6b19c124b1e..815004242e5f8 100644 --- a/src/test/run-make/thumb-none-qemu/example/.cargo/config +++ b/src/test/run-make/thumb-none-qemu/example/.cargo/config @@ -1,11 +1,24 @@ +[target.thumbv6m-none-eabi] +runner = "qemu-system-arm -cpu cortex-m0 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + [target.thumbv7m-none-eabi] -# uncomment this to make `cargo run` execute programs on QEMU runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" -[target.thumbv6m-none-eabi] -# uncomment this to make `cargo run` execute programs on QEMU -# For now, we use cortex-m3 instead of cortex-m0 which are not supported by QEMU -runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" +[target.thumbv7em-none-eabi] +runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv7em-none-eabihf] +runner = "qemu-system-arm -cpu cortex-m4 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv8m.base-none-eabi] +# FIXME: Should be the Cortex-M23, bt Qemu does not currently support it +runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv8m.main-none-eabi] +runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv8m.main-none-eabihf] +runner = "qemu-system-arm -cpu cortex-m33 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # uncomment ONE of these three option to make `cargo run` start a GDB session @@ -28,4 +41,4 @@ rustflags = [ # "-C", "linker=arm-none-eabi-gcc", # "-C", "link-arg=-Wl,-Tlink.x", # "-C", "link-arg=-nostartfiles", -] \ No newline at end of file +] From 36e230fe221571584bf8b09070fe36665c0628eb Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jan 2020 11:12:17 +0100 Subject: [PATCH 0553/1253] Update dependencies This fixes a linkage issue that was fixed a while ago, and adds thumbv8 support. --- src/test/run-make/thumb-none-qemu/example/Cargo.toml | 4 ++-- src/test/run-make/thumb-none-qemu/example/src/main.rs | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/test/run-make/thumb-none-qemu/example/Cargo.toml b/src/test/run-make/thumb-none-qemu/example/Cargo.toml index 73fdee71f0c0b..051d41bbae549 100644 --- a/src/test/run-make/thumb-none-qemu/example/Cargo.toml +++ b/src/test/run-make/thumb-none-qemu/example/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Hideki Sekine "] edition = "2018" [dependencies] -cortex-m = "0.5.4" -cortex-m-rt = "=0.5.4" +cortex-m = "0.6.2" +cortex-m-rt = "0.6.11" panic-halt = "0.2.0" cortex-m-semihosting = "0.3.1" diff --git a/src/test/run-make/thumb-none-qemu/example/src/main.rs b/src/test/run-make/thumb-none-qemu/example/src/main.rs index 4a08419a07e14..2abfde8e75f04 100644 --- a/src/test/run-make/thumb-none-qemu/example/src/main.rs +++ b/src/test/run-make/thumb-none-qemu/example/src/main.rs @@ -1,4 +1,3 @@ -// #![feature(stdsimd)] #![no_main] #![no_std] use core::fmt::Write; @@ -6,12 +5,9 @@ use cortex_m::asm; use cortex_m_rt::entry; use cortex_m_semihosting as semihosting; -//FIXME: This imports the provided #[panic_handler]. -#[allow(rust_2018_idioms)] -extern crate panic_halt; - -entry!(main); +use panic_halt as _; +#[entry] fn main() -> ! { let x = 42; From 6175f447b57bd8c36647707ede7db2652883ee36 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jan 2020 11:37:02 +0100 Subject: [PATCH 0554/1253] Check in lockfile --- .../thumb-none-qemu/example/Cargo.lock | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 src/test/run-make/thumb-none-qemu/example/Cargo.lock diff --git a/src/test/run-make/thumb-none-qemu/example/Cargo.lock b/src/test/run-make/thumb-none-qemu/example/Cargo.lock new file mode 100644 index 0000000000000..687b962a8b6fe --- /dev/null +++ b/src/test/run-make/thumb-none-qemu/example/Cargo.lock @@ -0,0 +1,199 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aligned" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "as-slice" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-rt" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m-rt-macros 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-semihosting" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "example" +version = "0.1.0" +dependencies = [ + "cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "generic-array" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "panic-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "r0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vcell" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94" +"checksum as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04" +"checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +"checksum cortex-m 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763" +"checksum cortex-m-rt 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "33a716cd7d8627fae3892c2eede9249e50d2d79aedfb43ca28dad9a2b23876d9" +"checksum cortex-m-rt-macros 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "72b1073338d1e691b3b7aaf6bd61993e589ececce9242a02dfa5453e1b98918d" +"checksum cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +"checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" +"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" From d022e01caa8cb6dd93aa15662417cf954c2c5795 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jan 2020 14:35:04 +0100 Subject: [PATCH 0555/1253] Do not use Cortex-M0 since Qemu is too old --- src/test/run-make/thumb-none-qemu/example/.cargo/config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/run-make/thumb-none-qemu/example/.cargo/config b/src/test/run-make/thumb-none-qemu/example/.cargo/config index 815004242e5f8..8b30310e7d432 100644 --- a/src/test/run-make/thumb-none-qemu/example/.cargo/config +++ b/src/test/run-make/thumb-none-qemu/example/.cargo/config @@ -1,5 +1,6 @@ [target.thumbv6m-none-eabi] -runner = "qemu-system-arm -cpu cortex-m0 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" +# FIXME: Should be Cortex-M0, but Qemu used by CI is too old +runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" [target.thumbv7m-none-eabi] runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" From 5918e9f02595a4b9ffacc4ecf5a0d470528a3824 Mon Sep 17 00:00:00 2001 From: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> Date: Tue, 21 Jan 2020 19:12:39 +0100 Subject: [PATCH 0556/1253] Update RELEASES.md --- RELEASES.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 0a5896a6665a7..02edb0cf83c98 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -75,8 +75,7 @@ Misc should be compiled the 2018 edition of Rust. - [You can now provide custom themes to rustdoc with `--theme`, and check the current theme with `--check-theme`.][54733] -- [You can use `#[doc(cfg(item))]` to document that a item is only available with - certain features.][61351] +- [You can use `#[cfg(doc)]` to compile an item when building documentation.][61351] Compatibility Notes ------------------- From c775927d7fee06743631d138eac91a862c8f6faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jan 2020 11:11:00 -0800 Subject: [PATCH 0557/1253] Suggest borrowing `Vec` in for loop Partially address #64167. --- .../borrow_check/diagnostics/move_errors.rs | 11 +++++++++++ src/test/ui/suggestions/for-i-in-vec.fixed | 15 +++++++++++++++ src/test/ui/suggestions/for-i-in-vec.rs | 15 +++++++++++++++ src/test/ui/suggestions/for-i-in-vec.stderr | 12 ++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 src/test/ui/suggestions/for-i-in-vec.fixed create mode 100644 src/test/ui/suggestions/for-i-in-vec.rs create mode 100644 src/test/ui/suggestions/for-i-in-vec.stderr diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index eb6db7c145c3c..c016cc90b1b86 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -1,6 +1,7 @@ use rustc::mir::*; use rustc::ty; use rustc_errors::{Applicability, DiagnosticBuilder}; +use rustc_span::source_map::DesugaringKind; use rustc_span::Span; use crate::borrow_check::diagnostics::UseSpans; @@ -397,6 +398,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { format!("{}.as_ref()", snippet), Applicability::MaybeIncorrect, ); + } else if span.is_desugaring(DesugaringKind::ForLoop) + && move_ty.starts_with("std::vec::Vec") + { + // FIXME: suggest for anything that implements `IntoIterator`. + err.span_suggestion( + span, + "consider iterating over a slice of the `Vec`'s content", + format!("&{}", snippet), + Applicability::MaybeIncorrect, + ); } } err diff --git a/src/test/ui/suggestions/for-i-in-vec.fixed b/src/test/ui/suggestions/for-i-in-vec.fixed new file mode 100644 index 0000000000000..ec7358bd08ad2 --- /dev/null +++ b/src/test/ui/suggestions/for-i-in-vec.fixed @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code)] + +struct Foo { + v: Vec, +} + +impl Foo { + fn bar(&self) { + for _ in &self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference + } + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/for-i-in-vec.rs b/src/test/ui/suggestions/for-i-in-vec.rs new file mode 100644 index 0000000000000..304fe8cc81f1a --- /dev/null +++ b/src/test/ui/suggestions/for-i-in-vec.rs @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code)] + +struct Foo { + v: Vec, +} + +impl Foo { + fn bar(&self) { + for _ in self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference + } + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/for-i-in-vec.stderr b/src/test/ui/suggestions/for-i-in-vec.stderr new file mode 100644 index 0000000000000..0fd10489bd0df --- /dev/null +++ b/src/test/ui/suggestions/for-i-in-vec.stderr @@ -0,0 +1,12 @@ +error[E0507]: cannot move out of `self.v` which is behind a shared reference + --> $DIR/for-i-in-vec.rs:10:18 + | +LL | for _ in self.v { + | ^^^^^^ + | | + | move occurs because `self.v` has type `std::vec::Vec`, which does not implement the `Copy` trait + | help: consider iterating over a slice of the `Vec`'s content: `&self.v` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From db3b40c2a1fe6129a7bbc12df6260b7197731153 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 21 Jan 2020 21:46:38 +0100 Subject: [PATCH 0558/1253] Cleanup: rewrite conditional as match As suggested by @Centril. Signed-off-by: Philipp Gesang --- .../error_reporting/on_unimplemented.rs | 66 +++++++++---------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs index 8f55540cae38a..2ba12baaf6d6e 100644 --- a/src/librustc/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -59,49 +59,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { let hir = &self.tcx.hir(); let node = hir.find(hir_id)?; - if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { - self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async function" - } else { - "a function" + match &node { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async function" + } else { + "a function" + }) }) - }) - } else if let hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| Some("a trait method")) - } else if let hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Method(sig, body_id), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { + } + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)), + .. + }) => self.describe_generator(*body_id).or_else(|| Some("a trait method")), + hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Method(sig, body_id), + .. + }) => self.describe_generator(*body_id).or_else(|| { Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { "an async method" } else { "a method" }) - }) - } else if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { + }), + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), + .. + }) => self.describe_generator(*body_id).or_else(|| { Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) - }) - } else if let hir::Node::Expr(hir::Expr { .. }) = &node { - let parent_hid = hir.get_parent_node(hir_id); - if parent_hid != hir_id { - return self.describe_enclosure(parent_hid); - } else { - None + }), + hir::Node::Expr(hir::Expr { .. }) => { + let parent_hid = hir.get_parent_node(hir_id); + if parent_hid != hir_id { + return self.describe_enclosure(parent_hid); + } else { + None + } } - } else { - None + _ => None, } } From d1bb7e16e0d0ad4e568df14eceedc5b0dd484214 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:50:22 -0500 Subject: [PATCH 0559/1253] Privatize private fields of OutputFilenames --- src/librustc_interface/util.rs | 33 ++++++++++++++------------------- src/librustc_session/config.rs | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 21f9fa4816591..3e65da9c47b7e 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -550,13 +550,13 @@ pub fn build_output_filenames( .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) .unwrap_or_else(|| input.filestem().to_owned()); - OutputFilenames { - out_directory: dirpath, - out_filestem: stem, - single_output_file: None, - extra: sess.opts.cg.extra_filename.clone(), - outputs: sess.opts.output_types.clone(), - } + OutputFilenames::new( + dirpath, + stem, + None, + sess.opts.cg.extra_filename.clone(), + sess.opts.output_types.clone(), + ) } Some(ref out_file) => { @@ -578,18 +578,13 @@ pub fn build_output_filenames( sess.warn("ignoring --out-dir flag due to -o flag"); } - OutputFilenames { - out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), - out_filestem: out_file - .file_stem() - .unwrap_or_default() - .to_str() - .unwrap() - .to_string(), - single_output_file: ofile, - extra: sess.opts.cg.extra_filename.clone(), - outputs: sess.opts.output_types.clone(), - } + OutputFilenames::new( + out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), + out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(), + ofile, + sess.opts.cg.extra_filename.clone(), + sess.opts.output_types.clone(), + ) } } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index b6b22e298ca62..08960cd44984b 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -447,9 +447,9 @@ impl Input { #[derive(Clone, Hash)] pub struct OutputFilenames { pub out_directory: PathBuf, - pub out_filestem: String, + out_filestem: String, pub single_output_file: Option, - pub extra: String, + extra: String, pub outputs: OutputTypes, } @@ -458,6 +458,16 @@ impl_stable_hash_via_hash!(OutputFilenames); pub const RUST_CGU_EXT: &str = "rcgu"; impl OutputFilenames { + pub fn new( + out_directory: PathBuf, + out_filestem: String, + single_output_file: Option, + extra: String, + outputs: OutputTypes, + ) -> Self { + OutputFilenames { out_directory, out_filestem, single_output_file, extra, outputs } + } + pub fn path(&self, flavor: OutputType) -> PathBuf { self.outputs .get(&flavor) From 8c6067c24e181aa388619ca0f39100e5c9a1f509 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:54:58 -0500 Subject: [PATCH 0560/1253] Store filestem in a pre-formatted form --- src/librustc_session/config.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 08960cd44984b..81e8e47445859 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -447,9 +447,8 @@ impl Input { #[derive(Clone, Hash)] pub struct OutputFilenames { pub out_directory: PathBuf, - out_filestem: String, + filestem: String, pub single_output_file: Option, - extra: String, pub outputs: OutputTypes, } @@ -465,7 +464,12 @@ impl OutputFilenames { extra: String, outputs: OutputTypes, ) -> Self { - OutputFilenames { out_directory, out_filestem, single_output_file, extra, outputs } + OutputFilenames { + out_directory, + single_output_file, + outputs, + filestem: format!("{}{}", out_filestem, extra), + } } pub fn path(&self, flavor: OutputType) -> PathBuf { @@ -487,7 +491,7 @@ impl OutputFilenames { /// Like temp_path, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { - let base = self.out_directory.join(&self.filestem()); + let base = self.out_directory.join(&self.filestem); let mut extension = String::new(); @@ -505,16 +509,11 @@ impl OutputFilenames { extension.push_str(ext); } - let path = base.with_extension(&extension[..]); - path + base.with_extension(extension) } pub fn with_extension(&self, extension: &str) -> PathBuf { - self.out_directory.join(&self.filestem()).with_extension(extension) - } - - pub fn filestem(&self) -> String { - format!("{}{}", self.out_filestem, self.extra) + self.out_directory.join(&self.filestem).with_extension(extension) } } From dc97181a0966cd1686a70ce06849a19c196f72eb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jan 2020 09:57:50 -0500 Subject: [PATCH 0561/1253] Do not base path to append extension We already have ownership of the base path, so no need to clone it (within Path::with_extension). --- src/librustc_session/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 81e8e47445859..c7fcd04c45a0a 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -491,8 +491,6 @@ impl OutputFilenames { /// Like temp_path, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { - let base = self.out_directory.join(&self.filestem); - let mut extension = String::new(); if let Some(codegen_unit_name) = codegen_unit_name { @@ -509,11 +507,13 @@ impl OutputFilenames { extension.push_str(ext); } - base.with_extension(extension) + self.with_extension(&extension) } pub fn with_extension(&self, extension: &str) -> PathBuf { - self.out_directory.join(&self.filestem).with_extension(extension) + let mut path = self.out_directory.join(&self.filestem); + path.set_extension(extension); + path } } From 13a91a82ff08fecf33a6ad94acce80ebb0612967 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 16 Jan 2020 16:18:51 -0800 Subject: [PATCH 0562/1253] Update LLVM Fixes #67855 (rust-lang/llvm-project#31) Fixes #66036 (rust-lang/llvm-project#32) --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index cd87134ab77e6..a6f4c1bb07d58 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit cd87134ab77e6bacb2128137065b328b9c35e0e5 +Subproject commit a6f4c1bb07d58df5956d2c49be68547143f77b18 From 4ee4287b1da13f56d063fa5b4234780def0d5af1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 21 Jan 2020 18:49:01 -0500 Subject: [PATCH 0563/1253] Account for non-types in substs for opaque type error messages Fixes #68368 Previously, I assumed that the substs contained only types, which caused the computed index number to be wrong. --- src/librustc_typeck/collect.rs | 11 +++++++++-- .../issue-68368-non-defining-use.rs | 13 +++++++++++++ .../issue-68368-non-defining-use.stderr | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 5821977391b0a..843872d0ff99a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1673,8 +1673,15 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { ty::Param(_) => true, _ => false, }; - let bad_substs: Vec<_> = - substs.types().enumerate().filter(|(_, ty)| !is_param(ty)).collect(); + let bad_substs: Vec<_> = substs + .iter() + .enumerate() + .filter_map(|(i, k)| { + if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None } + }) + .filter(|(_, ty)| !is_param(ty)) + .collect(); + if !bad_substs.is_empty() { let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id); for (i, bad_subst) in bad_substs { diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs new file mode 100644 index 0000000000000..d00f8d7a90119 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -0,0 +1,13 @@ +// Regression test for issue #68368 +// Ensures that we don't ICE when emitting an error +// for a non-defining use when lifetimes are involved + +#![feature(type_alias_impl_trait)] +trait Trait {} +type Alias<'a, U> = impl Trait; //~ ERROR could not find defining uses +fn f<'a>() -> Alias<'a, ()> {} +//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U` + +fn main() {} + +impl Trait<()> for () {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr new file mode 100644 index 0000000000000..b585942406fd4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -0,0 +1,14 @@ +error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()` + --> $DIR/issue-68368-non-defining-use.rs:8:1 + | +LL | fn f<'a>() -> Alias<'a, ()> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: could not find defining uses + --> $DIR/issue-68368-non-defining-use.rs:7:1 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From c7b23e275284cf88fd71df57b4fc203979299d97 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 22 Jan 2020 08:53:31 +0900 Subject: [PATCH 0564/1253] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index fd0428f622fee..3e74853d1f989 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit fd0428f622feee209e6014b802f5717d48d9e978 +Subproject commit 3e74853d1f9893cf2a47f28b658711d8f9f97b6b From eb2da27af27c010bf5501bbe85341ccd457dc3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 01:02:32 +0100 Subject: [PATCH 0565/1253] bootstrap: update clippy subcmd decription Clarify where the clippy used in `./x.py clippy` is coming from. It uses whatever clippy binary was installed via rustup, cargo-install or otherwise and does NOT use the binary generated by `./x.py build src/tools/clippy`. --- src/bootstrap/flags.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 1fbdd50a51133..2101ef27f9d42 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -104,7 +104,7 @@ Usage: x.py [options] [...] Subcommands: build Compile either the compiler or libraries check Compile either the compiler or libraries, using cargo check - clippy Run clippy + clippy Run clippy (uses rustup/cargo-installed clippy binary) fix Run cargo fix fmt Run rustfmt test Build and run some test suites From 7962ccb216e993b52f67986f7944fba5fc38482c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 22 Jan 2020 01:38:05 +0100 Subject: [PATCH 0566/1253] pprust: use as_deref --- src/libsyntax/print/pprust.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bc67980c454c0..6b21224b9b64c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1643,7 +1643,7 @@ impl<'a> State<'a> { self.print_expr_as_cond(i); self.s.space(); self.print_block(then); - self.print_else(e.as_ref().map(|e| &**e)) + self.print_else(e.as_deref()) } // Final `else` block. ast::ExprKind::Block(ref b, _) => { @@ -1947,7 +1947,7 @@ impl<'a> State<'a> { self.print_let(pat, scrutinee); } ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(test, blk, elseopt.as_ref().map(|e| &**e)); + self.print_if(test, blk, elseopt.as_deref()) } ast::ExprKind::While(ref test, ref blk, opt_label) => { if let Some(label) = opt_label { From 94fcda0e1346f284c44a27c5c07c2b0999e5bc29 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 Jan 2020 14:25:35 +0100 Subject: [PATCH 0567/1253] clean up E0214 explanation --- src/librustc_error_codes/error_codes/E0214.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0214.md b/src/librustc_error_codes/error_codes/E0214.md index f78c1c0cd0137..b64ee80e284d5 100644 --- a/src/librustc_error_codes/error_codes/E0214.md +++ b/src/librustc_error_codes/error_codes/E0214.md @@ -1,12 +1,17 @@ A generic type was described using parentheses rather than angle brackets. -For example: + +Erroneous code example: ```compile_fail,E0214 -fn main() { - let v: Vec(&str) = vec!["foo"]; -} +let v: Vec(&str) = vec!["foo"]; ``` This is not currently supported: `v` should be defined as `Vec<&str>`. Parentheses are currently only used with generic types when defining parameters for `Fn`-family traits. + +The previous code example fixed: + +``` +let v: Vec<&str> = vec!["foo"]; +``` From 71370c87f74fa38a6976bec27ebe4f449058872c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 17:19:26 +0100 Subject: [PATCH 0568/1253] librustc_mir: don't allocate vectors where slices will do. --- src/librustc_mir/transform/generator.rs | 4 ++-- src/librustc_mir/transform/instcombine.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 825ac4a28d869..8ac7772ea4818 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -117,7 +117,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { place, Place { local: self_arg(), - projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), + projection: self.tcx().intern_place_elems(&[ProjectionElem::Deref]), }, self.tcx, ); @@ -153,7 +153,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { place, Place { local: self_arg(), - projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field( + projection: self.tcx().intern_place_elems(&[ProjectionElem::Field( Field::new(0), self.ref_gen_ty, )]), diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 69eedb1ae1876..afe42e6357128 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -51,7 +51,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { let new_place = match rvalue { Rvalue::Ref(_, _, place) => { if let &[ref proj_l @ .., proj_r] = place.projection.as_ref() { - place.projection = self.tcx().intern_place_elems(&vec![proj_r.clone()]); + place.projection = self.tcx().intern_place_elems(&[proj_r.clone()]); Place { // Replace with dummy From 9d3e84432dae2e96a5e0f97be18ee09b5a2217b1 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 22 Jan 2020 20:28:28 +0000 Subject: [PATCH 0569/1253] Avoid overflow in `std::iter::Skip::count` The call to `count` on the inner iterator can overflow even if `Skip` itself would return less that `usize::max_value()` items. --- src/libcore/iter/adapters/mod.rs | 10 ++++++++-- src/test/ui/iterators/skip-count-overflow.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/iterators/skip-count-overflow.rs diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 6eb837ed0fed8..5787b9174edab 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1815,8 +1815,14 @@ where } #[inline] - fn count(self) -> usize { - self.iter.count().saturating_sub(self.n) + fn count(mut self) -> usize { + if self.n > 0 { + // nth(n) skips n+1 + if self.iter.nth(self.n - 1).is_none() { + return 0; + } + } + self.iter.count() } #[inline] diff --git a/src/test/ui/iterators/skip-count-overflow.rs b/src/test/ui/iterators/skip-count-overflow.rs new file mode 100644 index 0000000000000..d8efc948664ff --- /dev/null +++ b/src/test/ui/iterators/skip-count-overflow.rs @@ -0,0 +1,8 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// compile-flags: -C overflow-checks -C opt-level=3 + +fn main() { + let i = (0..usize::max_value()).chain(0..10).skip(usize::max_value()); + assert_eq!(i.count(), 10); +} From 4210409f443a40c72876e5e8398e8652a47a2ba6 Mon Sep 17 00:00:00 2001 From: Aaron Green Date: Wed, 15 Jan 2020 15:48:53 -0800 Subject: [PATCH 0570/1253] Enable ASan on Fuchsia This change adds the x86_64-fuchsia and aarch64-fuchsia LLVM targets to those allowed to invoke -Zsanitizer. Currently, the only overlap between compiler_rt sanitizers supported by both rustc and Fuchsia is ASan. --- src/bootstrap/native.rs | 18 ++++++++++++++++++ src/librustc_codegen_ssa/back/link.rs | 2 +- src/librustc_session/session.rs | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 89e1a7319cf59..5bbd9f47fc907 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -659,6 +659,24 @@ fn supported_sanitizers(out_dir: &Path, target: Interned) -> Vec { + for s in &["asan"] { + result.push(SanitizerRuntime { + cmake_target: format!("clang_rt.{}-x86_64", s), + path: out_dir.join(&format!("build/lib/fuchsia/libclang_rt.{}-x86_64.a", s)), + name: format!("librustc_rt.{}.a", s), + }); + } + } + "aarch64-fuchsia" => { + for s in &["asan"] { + result.push(SanitizerRuntime { + cmake_target: format!("clang_rt.{}-aarch64", s), + path: out_dir.join(&format!("build/lib/fuchsia/libclang_rt.{}-aarch64.a", s)), + name: format!("librustc_rt.{}.a", s), + }); + } + } _ => {} } result diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 53ee5996432ce..f56a4170c0a4b 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -777,7 +777,7 @@ fn link_sanitizer_runtime(sess: &Session, crate_type: config::CrateType, linker: linker.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]); linker.link_dylib(Symbol::intern(&libname)); } - "x86_64-unknown-linux-gnu" => { + "x86_64-unknown-linux-gnu" | "x86_64-fuchsia" | "aarch64-fuchsia" => { let filename = format!("librustc_rt.{}.a", name); let path = default_tlib.join(&filename); linker.link_whole_rlib(&path); diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index d979247b46d3a..527d85f69658c 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -1128,7 +1128,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // Sanitizers can only be used on some tested platforms. if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer { const ASAN_SUPPORTED_TARGETS: &[&str] = - &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-fuchsia", "aarch64-fuchsia" ]; const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; const LSAN_SUPPORTED_TARGETS: &[&str] = From 192650a9aac7a2e006afbbafb83088eaf0d9d820 Mon Sep 17 00:00:00 2001 From: Aaron Green Date: Wed, 22 Jan 2020 15:34:39 -0800 Subject: [PATCH 0571/1253] Fix tidy warnings --- src/librustc_session/session.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 527d85f69658c..a40d6451b958c 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -1127,8 +1127,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // Sanitizers can only be used on some tested platforms. if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer { - const ASAN_SUPPORTED_TARGETS: &[&str] = - &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-fuchsia", "aarch64-fuchsia" ]; + const ASAN_SUPPORTED_TARGETS: &[&str] = &[ + "x86_64-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-fuchsia", + "aarch64-fuchsia", + ]; const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; const LSAN_SUPPORTED_TARGETS: &[&str] = From 5c73d21eaa48b7c94bedcc5352fcbc7d749ed48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 23 Jan 2020 00:00:00 +0000 Subject: [PATCH 0572/1253] Use check-pass mode for nll tests --- .../closure-requirements/propagate-despite-same-free-region.rs | 2 +- src/test/ui/nll/constant.rs | 2 +- src/test/ui/nll/drop-may-dangle.rs | 2 +- src/test/ui/nll/extra-unused-mut.rs | 2 +- src/test/ui/nll/generator-distinct-lifetime.rs | 2 +- src/test/ui/nll/maybe-initialized-drop-uninitialized.rs | 2 +- src/test/ui/nll/projection-return.rs | 2 +- src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs | 2 +- src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs | 2 +- src/test/ui/nll/ty-outlives/projection-body.rs | 2 +- .../projection-one-region-trait-bound-static-closure.rs | 2 +- src/test/ui/nll/ty-outlives/projection-where-clause-env.rs | 2 +- src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs | 2 +- src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs | 2 +- src/test/ui/nll/user-annotations/downcast-infer.rs | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs index 1df7c6114eeae..ac182be155607 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs @@ -4,7 +4,7 @@ // regions is erased. // compile-flags:-Zborrowck=mir -Zverbose -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/constant.rs b/src/test/ui/nll/constant.rs index b1ea2c906da88..039b6aaaf0a70 100644 --- a/src/test/ui/nll/constant.rs +++ b/src/test/ui/nll/constant.rs @@ -2,7 +2,7 @@ // arbitrary types without ICEs. // compile-flags:-Zborrowck=mir -// build-pass (FIXME(62277): could be check-pass?) +// check-pass const HI: &str = "hi"; diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs index 0f3d27d066560..1897589bd5885 100644 --- a/src/test/ui/nll/drop-may-dangle.rs +++ b/src/test/ui/nll/drop-may-dangle.rs @@ -3,7 +3,7 @@ // including) the call to `use_x`. The `else` branch is not included. // compile-flags:-Zborrowck=mir -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(warnings)] #![feature(dropck_eyepatch)] diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs index e9c8df46213b5..db056a2285509 100644 --- a/src/test/ui/nll/extra-unused-mut.rs +++ b/src/test/ui/nll/extra-unused-mut.rs @@ -1,6 +1,6 @@ // extra unused mut lint tests for #51918 -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(generators, nll)] #![deny(unused_mut)] diff --git a/src/test/ui/nll/generator-distinct-lifetime.rs b/src/test/ui/nll/generator-distinct-lifetime.rs index 1bd39db35d9aa..3102562cd0ab2 100644 --- a/src/test/ui/nll/generator-distinct-lifetime.rs +++ b/src/test/ui/nll/generator-distinct-lifetime.rs @@ -6,7 +6,7 @@ // over a yield -- because the data that is borrowed (`*x`) is not // stored on the stack. -// build-pass (FIXME(62277): could be check-pass?) +// check-pass fn foo(x: &mut u32) { move || { diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs index 72212e9e70c0f..e81479495c4d7 100644 --- a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs +++ b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs @@ -1,5 +1,5 @@ // compile-flags: -Zborrowck=mir -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(warnings)] diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs index 5c340434691f1..017f53d1457d8 100644 --- a/src/test/ui/nll/projection-return.rs +++ b/src/test/ui/nll/projection-return.rs @@ -1,5 +1,5 @@ // compile-flags:-Zborrowck=mir -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs index 1bbc896c270a1..527cca133956c 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs @@ -6,7 +6,7 @@ // another -- effectively, the single lifetime `'a` is just inferred // to be the intersection of the two distinct lifetimes. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs index 4e8599b2e3fbe..3a46188d11911 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -2,7 +2,7 @@ // function returning always its first argument can be upcast to one // that returns either first or second argument. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/ty-outlives/projection-body.rs b/src/test/ui/nll/ty-outlives/projection-body.rs index 148120d848bc0..b03a539ebdbe9 100644 --- a/src/test/ui/nll/ty-outlives/projection-body.rs +++ b/src/test/ui/nll/ty-outlives/projection-body.rs @@ -1,7 +1,7 @@ // Test that when we infer the lifetime to a subset of the fn body, it // works out. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs index b9c9611e38c2c..be1b653c384b7 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs @@ -3,7 +3,7 @@ // we don't even propagate constraints from the closures to the callers. // compile-flags:-Zborrowck=mir -Zverbose -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs index 4613dd29ef8f0..a411162325dc4 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs @@ -4,7 +4,7 @@ // // Regression test for #53121. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs index 89328c2ef1b33..8d0c10a639ee5 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs @@ -4,7 +4,7 @@ // MyTrait<'a>>::Output: 'a` outlives `'a` (because the trait says // so). // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass trait MyTrait<'a> { type Output: 'a; diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs index a68c3cf12fd71..6547ae3981773 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs @@ -1,5 +1,5 @@ // compile-flags:-Zborrowck=mir -Zverbose -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // Test that we assume that universal types like `T` outlive the // function body. diff --git a/src/test/ui/nll/user-annotations/downcast-infer.rs b/src/test/ui/nll/user-annotations/downcast-infer.rs index 3efea7136307c..b27429f4d190f 100644 --- a/src/test/ui/nll/user-annotations/downcast-infer.rs +++ b/src/test/ui/nll/user-annotations/downcast-infer.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // Check that we don't try to downcast `_` when type-checking the annotation. fn main() { From d915c016c986d3060d6275f472b8a6e4c22b56ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 23 Jan 2020 00:00:00 +0000 Subject: [PATCH 0573/1253] Use check-pass mode for lint tests --- src/test/ui/lint/command-line-lint-group-allow.rs | 2 +- src/test/ui/lint/dead-code/tuple-struct-field.rs | 2 +- src/test/ui/lint/inclusive-range-pattern-syntax.fixed | 2 +- src/test/ui/lint/inclusive-range-pattern-syntax.rs | 2 +- src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs | 2 +- src/test/ui/lint/lint-non-camel-case-variant.rs | 2 +- .../ui/lint/lint-non-camel-case-with-trailing-underscores.rs | 2 +- src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs | 2 +- src/test/ui/lint/lint-nonstandard-style-unicode.rs | 2 +- src/test/ui/lint/lint-output-format-2.rs | 2 +- src/test/ui/lint/lint-stability-deprecated.rs | 2 +- src/test/ui/lint/lints-in-foreign-macros.rs | 2 +- src/test/ui/lint/reasons.rs | 2 +- src/test/ui/lint/type-overflow.rs | 2 +- src/test/ui/lint/unused_labels.rs | 2 +- src/test/ui/lint/use-redundant.rs | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/test/ui/lint/command-line-lint-group-allow.rs b/src/test/ui/lint/command-line-lint-group-allow.rs index f26e157bc706e..21c0df0288fa0 100644 --- a/src/test/ui/lint/command-line-lint-group-allow.rs +++ b/src/test/ui/lint/command-line-lint-group-allow.rs @@ -1,5 +1,5 @@ // compile-flags: -A bad-style -// build-pass (FIXME(62277): could be check-pass?) +// check-pass fn main() { let _InappropriateCamelCasing = true; diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs index 92a67950986b0..c8fd32c64d6db 100644 --- a/src/test/ui/lint/dead-code/tuple-struct-field.rs +++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(dead_code)] diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed index 9fce66a0a83cc..d6e5033a0c4c2 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.rs b/src/test/ui/lint/inclusive-range-pattern-syntax.rs index f886e778b5938..773eea14fd790 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.rs +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs index 95da4efa59041..d085db43aa94a 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // Issue #7526: lowercase static constants in patterns look like bindings // This is similar to lint-lowercase-static-const-pattern.rs, except it diff --git a/src/test/ui/lint/lint-non-camel-case-variant.rs b/src/test/ui/lint/lint-non-camel-case-variant.rs index 434e24c1d278c..2b1a52f25be87 100644 --- a/src/test/ui/lint/lint-non-camel-case-variant.rs +++ b/src/test/ui/lint/lint-non-camel-case-variant.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(non_camel_case_types)] diff --git a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs index d025ee948546a..b832e4bcd6223 100644 --- a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs +++ b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(dead_code)] // This is ok because we often use the trailing underscore to mean 'prime' diff --git a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs index 5bec82ce1a6f5..710eebe4b6525 100644 --- a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs +++ b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode.rs b/src/test/ui/lint/lint-nonstandard-style-unicode.rs index 40f0a676381b4..9f16cb20fb32c 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(dead_code)] diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs index 32a41179965f3..521472d99b17d 100644 --- a/src/test/ui/lint/lint-output-format-2.rs +++ b/src/test/ui/lint/lint-output-format-2.rs @@ -1,7 +1,7 @@ // aux-build:lint_output_format.rs #![feature(unstable_test_feature)] -// build-pass (FIXME(62277): could be check-pass?) +// check-pass extern crate lint_output_format; use lint_output_format::{foo, bar}; diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 0bac9bb3d99cd..4b407a29f64b3 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs diff --git a/src/test/ui/lint/lints-in-foreign-macros.rs b/src/test/ui/lint/lints-in-foreign-macros.rs index e381c81453b10..c96b8f1a5cf4a 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.rs +++ b/src/test/ui/lint/lints-in-foreign-macros.rs @@ -1,5 +1,5 @@ // aux-build:lints-in-foreign-macros.rs -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![warn(unused_imports)] //~ missing documentation for crate [missing_docs] #![warn(missing_docs)] diff --git a/src/test/ui/lint/reasons.rs b/src/test/ui/lint/reasons.rs index fa9f012c9262c..4722e85673c2b 100644 --- a/src/test/ui/lint/reasons.rs +++ b/src/test/ui/lint/reasons.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(lint_reasons)] diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index 79ffc82d32963..e40321e56bf15 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![warn(overflowing_literals)] fn main() { diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index d234a2fb1a02c..8a3568f65f63e 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -2,7 +2,7 @@ // should also deal with the edge cases where a label is shadowed, // within nested loops -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(label_break_value)] #![warn(unused_labels)] diff --git a/src/test/ui/lint/use-redundant.rs b/src/test/ui/lint/use-redundant.rs index 3b00424d2f3fa..53315dcf638ae 100644 --- a/src/test/ui/lint/use-redundant.rs +++ b/src/test/ui/lint/use-redundant.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![warn(unused_imports)] use crate::foo::Bar; From 6a6ebb4403683e1e12d3916cabc1a4898ce798cf Mon Sep 17 00:00:00 2001 From: Victor Ding Date: Sat, 21 Dec 2019 21:37:15 +1100 Subject: [PATCH 0574/1253] Add `-Z no-link` flag Adds a compiler option to allow rustc compile a crate without linking. With this flag, rustc serializes codegen_results into a .rlink file. --- Cargo.lock | 1 + src/librustc/middle/cstore.rs | 5 ++-- src/librustc/middle/dependency_format.rs | 2 +- src/librustc_codegen_llvm/Cargo.toml | 1 + src/librustc_codegen_llvm/lib.rs | 14 ++++++++++ src/librustc_codegen_ssa/back/linker.rs | 1 + src/librustc_codegen_ssa/lib.rs | 14 +++++++--- src/librustc_hir/def_id.rs | 34 ++++++++++++++++++++---- src/librustc_session/config.rs | 2 +- src/librustc_session/options.rs | 2 ++ src/librustc_session/search_paths.rs | 2 +- 11 files changed, 65 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a76aabc3a312..237b3dda670df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3428,6 +3428,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "serialize", "smallvec 1.0.0", "syntax", ] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 5b1e7673629b1..0e7ff3a3393ef 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -27,7 +27,7 @@ pub use rustc_session::utils::NativeLibraryKind; /// Where a crate came from on the local filesystem. One of these three options /// must be non-None. -#[derive(PartialEq, Clone, Debug, HashStable)] +#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)] pub struct CrateSource { pub dylib: Option<(PathBuf, PathKind)>, pub rlib: Option<(PathBuf, PathKind)>, @@ -75,7 +75,7 @@ impl DepKind { } } -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum LibSource { Some(PathBuf), MetadataOnly, @@ -160,6 +160,7 @@ pub enum ExternCrateSource { Path, } +#[derive(RustcEncodable, RustcDecodable)] pub struct EncodedMetadata { pub raw_data: Vec, } diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 8b2bf55ccc120..6ece51fe86674 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -19,7 +19,7 @@ pub type DependencyList = Vec; /// This is local to the tcx, and is generally relevant to one session. pub type Dependencies = Vec<(config::CrateType, DependencyList)>; -#[derive(Copy, Clone, PartialEq, Debug, HashStable)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)] pub enum Linkage { NotLinked, IncludedFromDylib, diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 3ff5495e29136..dd9eadde098ec 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -28,6 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_index = { path = "../librustc_index" } rustc_llvm = { path = "../librustc_llvm" } rustc_session = { path = "../librustc_session" } +rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_target = { path = "../librustc_target" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index a6168128c4d44..70e3874035b60 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -33,6 +33,7 @@ use rustc_codegen_ssa::CompiledModule; use rustc_errors::{FatalError, Handler}; use std::any::Any; use std::ffi::CStr; +use std::fs; use std::sync::Arc; use syntax::expand::allocator::AllocatorKind; @@ -44,6 +45,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_serialize::json; mod back { pub mod archive; @@ -298,6 +300,18 @@ impl CodegenBackend for LlvmCodegenBackend { return Ok(()); } + if sess.opts.debugging_opts.no_link { + // FIXME: use a binary format to encode the `.rlink` file + let rlink_data = json::encode(&codegen_results).map_err(|err| { + sess.fatal(&format!("failed to encode rlink: {}", err)); + })?; + let rlink_file = outputs.with_extension("rlink"); + fs::write(&rlink_file, rlink_data).map_err(|err| { + sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err)); + })?; + return Ok(()); + } + // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. sess.time("link_crate", || { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 4679f6501336c..695f171dfb49c 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -20,6 +20,7 @@ use rustc_target::spec::{LinkerFlavor, LldFlavor}; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. +#[derive(RustcEncodable, RustcDecodable)] pub struct LinkerInfo { exports: FxHashMap>, } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index aba77231268e7..b69def5428ccf 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -87,7 +87,7 @@ impl ModuleCodegen { } } -#[derive(Debug)] +#[derive(Debug, RustcEncodable, RustcDecodable)] pub struct CompiledModule { pub name: String, pub kind: ModuleKind, @@ -101,7 +101,7 @@ pub struct CachedModuleCodegen { pub source: WorkProduct, } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] pub enum ModuleKind { Regular, Metadata, @@ -117,7 +117,14 @@ bitflags::bitflags! { } /// Misc info we load from metadata to persist beyond the tcx. -#[derive(Debug)] +/// +/// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo` +/// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where +/// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from +/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own +/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource` +/// and the corresponding properties without referencing information outside of a `CrateInfo`. +#[derive(Debug, RustcEncodable, RustcDecodable)] pub struct CrateInfo { pub panic_runtime: Option, pub compiler_builtins: Option, @@ -135,6 +142,7 @@ pub struct CrateInfo { pub dependency_formats: Lrc, } +#[derive(RustcEncodable, RustcDecodable)] pub struct CodegenResults { pub crate_name: Symbol, pub modules: Vec, diff --git a/src/librustc_hir/def_id.rs b/src/librustc_hir/def_id.rs index f8cacdc6238e8..7ee778ddd8ec7 100644 --- a/src/librustc_hir/def_id.rs +++ b/src/librustc_hir/def_id.rs @@ -1,7 +1,8 @@ use rustc_data_structures::AtomicRef; use rustc_index::vec::Idx; +use rustc_serialize::{Decoder, Encoder}; use std::fmt; -use std::u32; +use std::{u32, u64}; rustc_index::newtype_index! { pub struct CrateId { @@ -86,8 +87,18 @@ impl fmt::Display for CrateNum { } } -impl rustc_serialize::UseSpecializedEncodable for CrateNum {} -impl rustc_serialize::UseSpecializedDecodable for CrateNum {} +/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx. +/// Therefore, make sure to include the context when encode a `CrateNum`. +impl rustc_serialize::UseSpecializedEncodable for CrateNum { + fn default_encode(&self, e: &mut E) -> Result<(), E::Error> { + e.emit_u32(self.as_u32()) + } +} +impl rustc_serialize::UseSpecializedDecodable for CrateNum { + fn default_decode(d: &mut D) -> Result { + Ok(CrateNum::from_u32(d.read_u32()?)) + } +} rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a @@ -135,8 +146,21 @@ impl DefId { } } -impl rustc_serialize::UseSpecializedEncodable for DefId {} -impl rustc_serialize::UseSpecializedDecodable for DefId {} +impl rustc_serialize::UseSpecializedEncodable for DefId { + fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { + let krate = u64::from(self.krate.as_u32()); + let index = u64::from(self.index.as_u32()); + s.emit_u64((krate << 32) | index) + } +} +impl rustc_serialize::UseSpecializedDecodable for DefId { + fn default_decode(d: &mut D) -> Result { + let def_id = d.read_u64()?; + let krate = CrateNum::from_u32((def_id >> 32) as u32); + let index = DefIndex::from_u32((def_id & 0xffffffff) as u32); + Ok(DefId { krate, index }) + } +} pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish() diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index b6b22e298ca62..b1ba81aa95b19 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -619,7 +619,7 @@ pub enum EntryFnType { impl_stable_hash_via_hash!(EntryFnType); -#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)] +#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum CrateType { Executable, Dylib, diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 2a0ed27b63b08..34da2188a51d2 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -950,4 +950,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, (such as entering an empty infinite loop) by inserting llvm.sideeffect"), deduplicate_diagnostics: Option = (None, parse_opt_bool, [UNTRACKED], "deduplicate identical diagnostics"), + no_link: bool = (false, parse_bool, [TRACKED], + "compile without linking"), } diff --git a/src/librustc_session/search_paths.rs b/src/librustc_session/search_paths.rs index b15f4e8f6c18e..06f408b4a8d64 100644 --- a/src/librustc_session/search_paths.rs +++ b/src/librustc_session/search_paths.rs @@ -9,7 +9,7 @@ pub struct SearchPath { pub files: Vec, } -#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)] +#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, RustcEncodable, RustcDecodable)] pub enum PathKind { Native, Crate, From 6f7e89ffe3824be03ea75a602dc46e711d16cb25 Mon Sep 17 00:00:00 2001 From: Tyler Lanphear Date: Thu, 23 Jan 2020 00:42:35 -0500 Subject: [PATCH 0575/1253] unused-parens: implement for block return values --- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc_data_structures/sorted_map.rs | 2 +- src/librustc_lint/unused.rs | 16 ++++++--- src/librustc_mir_build/hair/pattern/_match.rs | 2 +- src/librustc_span/source_map.rs | 4 +-- src/libsyntax/print/pprust.rs | 6 +--- src/test/ui/lint/lint-unnecessary-parens.rs | 7 ++++ .../ui/lint/lint-unnecessary-parens.stderr | 36 ++++++++++++------- 9 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0470ab20dc464..e67131b916413 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2410,7 +2410,7 @@ impl<'tcx> AdtDef { #[inline] pub fn variant_range(&self) -> Range { - (VariantIdx::new(0)..VariantIdx::new(self.variants.len())) + VariantIdx::new(0)..VariantIdx::new(self.variants.len()) } /// Computes the discriminant value used by a specific variant. diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 13f623aadb1a3..837b2fcc50068 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -529,7 +529,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR let num_variants = tcx.generator_layout(def_id).variant_fields.len(); - (VariantIdx::new(0)..VariantIdx::new(num_variants)) + VariantIdx::new(0)..VariantIdx::new(num_variants) } /// The discriminant for the given variant. Panics if the `variant_index` is diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs index b29ffd7594008..08706aac11e41 100644 --- a/src/librustc_data_structures/sorted_map.rs +++ b/src/librustc_data_structures/sorted_map.rs @@ -132,7 +132,7 @@ impl SortedMap { R: RangeBounds, { let (start, end) = self.range_slice_indices(range); - (&self.data[start..end]) + &self.data[start..end] } #[inline] diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 15158c09af074..bb2c4fa1aaff6 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -544,12 +544,20 @@ impl EarlyLintPass for UnusedParens { } fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { - if let ast::StmtKind::Local(ref local) = s.kind { - self.check_unused_parens_pat(cx, &local.pat, false, false); + use ast::StmtKind::*; - if let Some(ref value) = local.init { - self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None); + match s.kind { + Local(ref local) => { + self.check_unused_parens_pat(cx, &local.pat, false, false); + + if let Some(ref value) = local.init { + self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None); + } } + Expr(ref expr) => { + self.check_unused_parens_expr(cx, &expr, "block return value", false, None, None); + } + _ => {} } } diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 20183fd55c871..a2ce224904b29 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -1530,7 +1530,7 @@ impl<'tcx> IntRange<'tcx> { // 2 -------- // 2 ------- let (lo, hi) = self.boundaries(); let (other_lo, other_hi) = other.boundaries(); - (lo == other_hi || hi == other_lo) + lo == other_hi || hi == other_lo } fn to_pat(&self, tcx: TyCtxt<'tcx>) -> Pat<'tcx> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index 9c7c0f0c8b0ec..e0b93b9ce2555 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -774,10 +774,10 @@ impl SourceMap { // searching forwards for boundaries we've got somewhere to search. let snippet = if let Some(ref src) = local_begin.sf.src { let len = src.len(); - (&src[start_index..len]) + &src[start_index..len] } else if let Some(src) = src.get_source() { let len = src.len(); - (&src[start_index..len]) + &src[start_index..len] } else { return 1; }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f0ef33e2f622d..d6f18fda8b25c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -548,11 +548,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere let st = match style { ast::StrStyle::Cooked => (format!("\"{}\"", st.escape_debug())), ast::StrStyle::Raw(n) => { - (format!( - "r{delim}\"{string}\"{delim}", - delim = "#".repeat(n as usize), - string = st - )) + format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = st) } }; self.word(st) diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs index 12ffb6d3c6655..4e8339a8e6bf1 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.rs +++ b/src/test/ui/lint/lint-unnecessary-parens.rs @@ -17,6 +17,13 @@ fn unused_parens_around_return_type() -> (u32) { //~ ERROR unnecessary parenthes panic!() } +fn unused_parens_around_block_return() -> u32 { + let foo = { + (5) //~ ERROR unnecessary parentheses around block return value + }; + (5) //~ ERROR unnecessary parentheses around block return value +} + trait Trait { fn test(&self); } diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr index 541ae7aa4b54a..ea58220d20c9f 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.stderr +++ b/src/test/ui/lint/lint-unnecessary-parens.stderr @@ -22,26 +22,38 @@ error: unnecessary parentheses around type LL | fn unused_parens_around_return_type() -> (u32) { | ^^^^^ help: remove these parentheses +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:22:9 + | +LL | (5) + | ^^^ help: remove these parentheses + +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:24:5 + | +LL | (5) + | ^^^ help: remove these parentheses + error: unnecessary parentheses around function argument - --> $DIR/lint-unnecessary-parens.rs:36:9 + --> $DIR/lint-unnecessary-parens.rs:43:9 | LL | bar((true)); | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `if` condition - --> $DIR/lint-unnecessary-parens.rs:38:8 + --> $DIR/lint-unnecessary-parens.rs:45:8 | LL | if (true) {} | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `while` condition - --> $DIR/lint-unnecessary-parens.rs:39:11 + --> $DIR/lint-unnecessary-parens.rs:46:11 | LL | while (true) {} | ^^^^^^ help: remove these parentheses warning: denote infinite loops with `loop { ... }` - --> $DIR/lint-unnecessary-parens.rs:39:5 + --> $DIR/lint-unnecessary-parens.rs:46:5 | LL | while (true) {} | ^^^^^^^^^^^^ help: use `loop` @@ -49,46 +61,46 @@ LL | while (true) {} = note: `#[warn(while_true)]` on by default error: unnecessary parentheses around `match` head expression - --> $DIR/lint-unnecessary-parens.rs:41:11 + --> $DIR/lint-unnecessary-parens.rs:48:11 | LL | match (true) { | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:44:16 + --> $DIR/lint-unnecessary-parens.rs:51:16 | LL | if let 1 = (1) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:45:19 + --> $DIR/lint-unnecessary-parens.rs:52:19 | LL | while let 1 = (2) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around method argument - --> $DIR/lint-unnecessary-parens.rs:59:24 + --> $DIR/lint-unnecessary-parens.rs:66:24 | LL | X { y: false }.foo((true)); | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:61:18 + --> $DIR/lint-unnecessary-parens.rs:68:18 | LL | let mut _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:62:10 + --> $DIR/lint-unnecessary-parens.rs:69:10 | LL | _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:63:11 + --> $DIR/lint-unnecessary-parens.rs:70:11 | LL | _a += (1); | ^^^ help: remove these parentheses -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors From 5c384ab00c7b4b39e457b75d385e9cbe12e699f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 23 Jan 2020 00:00:00 +0000 Subject: [PATCH 0576/1253] compiletest: Do not run debuginfo tests with gdb on msvc targets --- src/tools/compiletest/src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 0c8f4dd5eaaa1..72c2332fec4d3 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -366,6 +366,10 @@ fn configure_gdb(config: &Config) -> Option { return None; } + if util::matches_env(&config.target, "msvc") { + return None; + } + if config.remote_test_client.is_some() && !config.target.contains("android") { println!( "WARNING: debuginfo tests are not available when \ From 29951edbdfcb3e65e689e43c997a98d8aad5e273 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 20 Jan 2020 15:54:40 +0100 Subject: [PATCH 0577/1253] Clarify some methods around instance instantiation via comments and clearer names. --- src/librustc/mir/mono.rs | 6 +++--- src/librustc/ty/instance.rs | 18 +++++++++++++++--- src/librustc_codegen_llvm/attributes.rs | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 51ce575e51f3b..475c77adebd10 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -79,7 +79,7 @@ impl<'tcx> MonoItem<'tcx> { } pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode { - let inline_in_all_cgus = tcx + let generate_cgu_internal_copies = tcx .sess .opts .debugging_opts @@ -93,7 +93,7 @@ impl<'tcx> MonoItem<'tcx> { // If this function isn't inlined or otherwise has explicit // linkage, then we'll be creating a globally shared version. if self.explicit_linkage(tcx).is_some() - || !instance.def.requires_local(tcx) + || !instance.def.generates_cgu_internal_copy(tcx) || Some(instance.def_id()) == entry_def_id { return InstantiationMode::GloballyShared { may_conflict: false }; @@ -102,7 +102,7 @@ impl<'tcx> MonoItem<'tcx> { // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll // be creating a local copy per CGU - if inline_in_all_cgus { + if generate_cgu_internal_copies { return InstantiationMode::LocalCopy; } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 1ea695e40b255..c4770184612cb 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -114,7 +114,12 @@ impl<'tcx> InstanceDef<'tcx> { tcx.get_attrs(self.def_id()) } - pub fn is_inline(&self, tcx: TyCtxt<'tcx>) -> bool { + /// Returns `true` if the LLVM version of this instance is unconditionally + /// marked with `inline`. This implies that a copy of this instance is + /// generated in every codegen unit. + /// Note that this is only a hint. See the documentation for + /// `generates_cgu_internal_copy` for more information. + pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use crate::hir::map::DefPathData; let def_id = match *self { ty::InstanceDef::Item(def_id) => def_id, @@ -127,8 +132,15 @@ impl<'tcx> InstanceDef<'tcx> { } } - pub fn requires_local(&self, tcx: TyCtxt<'tcx>) -> bool { - if self.is_inline(tcx) { + /// Returns `true` if the machine code for this instance is instantiated in + /// each codegen unit that references it. + /// Note that this is only a hint! The compiler can globally decide to *not* + /// do this in order to speed up compilation. CGU-internal copies are + /// only exist to enable inlining. If inlining is not performed (e.g. at + /// `-Copt-level=0`) then the time for generating them is wasted and it's + /// better to create a single copy with external linkage. + pub fn generates_cgu_internal_copy(&self, tcx: TyCtxt<'tcx>) -> bool { + if self.requires_inline(tcx) { return true; } if let ty::InstanceDef::DropGlue(..) = *self { diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 4ed4e8ac6efab..fc1b365cf90ce 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -246,7 +246,7 @@ pub fn from_fn_attrs( } // FIXME(eddyb) consolidate these two `inline` calls (and avoid overwrites). - if instance.def.is_inline(cx.tcx) { + if instance.def.requires_inline(cx.tcx) { inline(cx, llfn, attributes::InlineAttr::Hint); } From 0c366cdeaf6cfc2780bae118268eec5c675d6c43 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 20 Jan 2020 15:56:06 +0100 Subject: [PATCH 0578/1253] Make ExportedSymbols type more local because it's not supposed to be used outside of the LLVM backend. --- src/librustc_codegen_ssa/back/symbol_export.rs | 4 +--- src/librustc_codegen_ssa/back/write.rs | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index d680e14bbbd5b..12b826332454a 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -17,8 +17,6 @@ use rustc_hir::Node; use rustc_index::vec::IndexVec; use syntax::expand::allocator::ALLOCATOR_METHODS; -pub type ExportedSymbols = FxHashMap>>; - pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(&tcx.sess.crate_types.borrow()) } @@ -96,7 +94,7 @@ fn reachable_non_generics_provider( if !generics.requires_monomorphization(tcx) && // Functions marked with #[inline] are only ever codegened // with "internal" linkage and are never exported. - !Instance::mono(tcx, def_id).def.requires_local(tcx) + !Instance::mono(tcx, def_id).def.generates_cgu_internal_copy(tcx) { Some(def_id) } else { diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 049faff7c49ee..841827d15fef4 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -2,7 +2,8 @@ use super::command::Command; use super::link::{self, get_linker, remove}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; -use super::symbol_export::{symbol_name_for_instance_in_crate, ExportedSymbols}; +use super::symbol_export::symbol_name_for_instance_in_crate; + use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION, @@ -12,6 +13,7 @@ use crate::traits::*; use jobserver::{Acquired, Client}; use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId}; use rustc::middle::cstore::EncodedMetadata; +use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{ self, Lto, OutputFilenames, OutputType, Passes, Sanitizer, SwitchWithOptPath, }; @@ -205,6 +207,8 @@ impl Clone for TargetMachineFactory { } } +pub type ExportedSymbols = FxHashMap>>; + /// Additional resources used by optimize_and_codegen (not module specific) #[derive(Clone)] pub struct CodegenContext { From 190f0c0b0babaef16c97aea87189f89fa0481fba Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Jan 2020 14:29:42 +0100 Subject: [PATCH 0579/1253] Always just use symbol name for sorting exported symbols. --- src/librustc/middle/exported_symbols.rs | 38 ------------------------- 1 file changed, 38 deletions(-) diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index a349b34eb1a0c..511a77bf830e5 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -3,7 +3,6 @@ use crate::ty::subst::SubstsRef; use crate::ty::{self, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use std::cmp; use std::mem; /// The SymbolExportLevel of a symbols specifies from which kinds of crates @@ -43,43 +42,6 @@ impl<'tcx> ExportedSymbol<'tcx> { ExportedSymbol::NoDefId(symbol_name) => symbol_name, } } - - pub fn compare_stable(&self, tcx: TyCtxt<'tcx>, other: &ExportedSymbol<'tcx>) -> cmp::Ordering { - match *self { - ExportedSymbol::NonGeneric(self_def_id) => match *other { - ExportedSymbol::NonGeneric(other_def_id) => { - tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id)) - } - ExportedSymbol::Generic(..) | ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, - }, - ExportedSymbol::Generic(self_def_id, self_substs) => match *other { - ExportedSymbol::NonGeneric(_) => cmp::Ordering::Greater, - ExportedSymbol::Generic(other_def_id, other_substs) => { - // We compare the symbol names because they are cached as query - // results which makes them relatively cheap to access repeatedly. - // - // It might be even faster to build a local cache of stable IDs - // for sorting. Exported symbols are really only sorted once - // in order to make the `exported_symbols` query result stable. - let self_symbol_name = - tcx.symbol_name(ty::Instance::new(self_def_id, self_substs)); - let other_symbol_name = - tcx.symbol_name(ty::Instance::new(other_def_id, other_substs)); - - self_symbol_name.cmp(&other_symbol_name) - } - ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, - }, - ExportedSymbol::NoDefId(self_symbol_name) => match *other { - ExportedSymbol::NonGeneric(_) | ExportedSymbol::Generic(..) => { - cmp::Ordering::Greater - } - ExportedSymbol::NoDefId(ref other_symbol_name) => { - self_symbol_name.cmp(other_symbol_name) - } - }, - } - } } pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String { From 2ceb92bc53a849e36341c3fd619cb49470e224e2 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 20 Jan 2020 16:38:42 +0100 Subject: [PATCH 0580/1253] Make drop-glue take advantage of -Zshare-generics. --- .../back/symbol_export.rs | 28 +++++++++++++------ src/librustc_mir/monomorphize/collector.rs | 10 +++++-- src/librustc_mir/monomorphize/partitioning.rs | 2 +- .../auxiliary/shared_generics_aux.rs | 16 ++++++++++- .../partitioning/shared-generics.rs | 12 ++++++-- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 12b826332454a..7e888a271e316 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -5,7 +5,7 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; use rustc::session::config::{self, Sanitizer}; use rustc::ty::query::Providers; -use rustc::ty::subst::SubstsRef; +use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::Instance; use rustc::ty::{SymbolName, TyCtxt}; use rustc_codegen_utils::symbol_names; @@ -248,19 +248,31 @@ fn exported_symbols_provider_local( continue; } - if let &MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) = mono_item { - if substs.non_erasable_generics().next().is_some() { - symbols - .push((ExportedSymbol::Generic(def_id, substs), SymbolExportLevel::Rust)); + match *mono_item { + MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => { + if substs.non_erasable_generics().next().is_some() { + let symbol = ExportedSymbol::Generic(def_id, substs); + symbols.push((symbol, SymbolExportLevel::Rust)); + } + } + MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), substs }) => { + // A little sanity-check + debug_assert_eq!( + substs.non_erasable_generics().next(), + Some(GenericArgKind::Type(ty)) + ); + let symbol = ExportedSymbol::Generic(def_id, substs); + symbols.push((symbol, SymbolExportLevel::Rust)); + } + _ => { + // Any other symbols don't qualify for sharing } } } } // Sort so we get a stable incr. comp. hash. - symbols.sort_unstable_by(|&(ref symbol1, ..), &(ref symbol2, ..)| { - symbol1.compare_stable(tcx, symbol2) - }); + symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx)); Arc::new(symbols) } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f4611c32e0a32..91e685babbcdd 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -713,7 +713,8 @@ fn visit_instance_use<'tcx>( // need a mono item. fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { let def_id = match instance.def { - ty::InstanceDef::Item(def_id) => def_id, + ty::InstanceDef::Item(def_id) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id, + ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::ClosureOnceShim { .. } @@ -725,12 +726,14 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx }; if tcx.is_foreign_item(def_id) { - // We can always link to foreign items. + // Foreign items are always linked against, there's no way of + // instantiating them. return false; } if def_id.is_local() { - // Local items cannot be referred to locally without monomorphizing them locally. + // Local items cannot be referred to locally without + // monomorphizing them locally. return true; } @@ -745,6 +748,7 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx if !tcx.is_mir_available(def_id) { bug!("cannot create local mono-item for {:?}", def_id) } + return true; fn is_available_upstream_generic<'tcx>( diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 0def51a6a33e5..8bcf420e2aa37 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -324,7 +324,7 @@ fn mono_item_visibility( }; let def_id = match instance.def { - InstanceDef::Item(def_id) => def_id, + InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, // These are all compiler glue and such, never exported, always hidden. InstanceDef::VtableShim(..) diff --git a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs index 9050e8f1671d9..ffbd0dc548449 100644 --- a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs +++ b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs @@ -1,4 +1,6 @@ -// compile-flags:-Zshare-generics=yes +// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels +// prevent drop-glue from participating in share-generics. +// compile-flags:-Zshare-generics=yes -Copt-level=0 // no-prefer-dynamic #![crate_type="rlib"] @@ -8,5 +10,17 @@ pub fn generic_fn(x: T, y: T) -> (T, T) { } pub fn use_generic_fn_f32() -> (f32, f32) { + // This line causes drop glue for Foo to be instantiated. We want to make + // sure that this crate exports an instance to be re-used by share-generics. + let _ = Foo(0); + generic_fn(0.0f32, 1.0f32) } + +pub struct Foo(pub u32); + +impl Drop for Foo { + fn drop(&mut self) { + println!("foo"); + } +} diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs index 58e485be00321..47ff94437ff37 100644 --- a/src/test/codegen-units/partitioning/shared-generics.rs +++ b/src/test/codegen-units/partitioning/shared-generics.rs @@ -1,6 +1,8 @@ // ignore-tidy-linelength // no-prefer-dynamic -// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe +// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels +// prevent drop-glue from participating in share-generics. +// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe -Copt-level=0 #![crate_type="rlib"] @@ -16,6 +18,10 @@ pub fn foo() { // This should not generate a monomorphization because it's already // available in `shared_generics_aux`. let _ = shared_generics_aux::generic_fn(0.0f32, 3.0f32); -} -// MONO_ITEM drop-glue i8 + // The following line will drop an instance of `Foo`, generating a call to + // Foo's drop-glue function. However, share-generics should take care of + // reusing the drop-glue from the upstream crate, so we do not expect a + // mono item for the drop-glue + let _ = shared_generics_aux::Foo(1); +} From 3850d96379126087240b640470632362a5d32234 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Jan 2020 13:29:15 +0100 Subject: [PATCH 0581/1253] clean up error codes explanation --- src/librustc_error_codes/error_codes/E0220.md | 3 ++- src/librustc_error_codes/error_codes/E0221.md | 3 ++- src/librustc_error_codes/error_codes/E0222.md | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0220.md b/src/librustc_error_codes/error_codes/E0220.md index 43e075b522b4e..4ab52b642d500 100644 --- a/src/librustc_error_codes/error_codes/E0220.md +++ b/src/librustc_error_codes/error_codes/E0220.md @@ -1,4 +1,5 @@ -You used an associated type which isn't defined in the trait. +A used associated type wasn't defined in the trait. + Erroneous code example: ```compile_fail,E0220 diff --git a/src/librustc_error_codes/error_codes/E0221.md b/src/librustc_error_codes/error_codes/E0221.md index 53fabf490e2c3..26111ca429333 100644 --- a/src/librustc_error_codes/error_codes/E0221.md +++ b/src/librustc_error_codes/error_codes/E0221.md @@ -1,5 +1,6 @@ An attempt was made to retrieve an associated type, but the type was ambiguous. -For example: + +Erroneous code example: ```compile_fail,E0221 trait T1 {} diff --git a/src/librustc_error_codes/error_codes/E0222.md b/src/librustc_error_codes/error_codes/E0222.md index 66b6c4d712b70..fbf1b8d703314 100644 --- a/src/librustc_error_codes/error_codes/E0222.md +++ b/src/librustc_error_codes/error_codes/E0222.md @@ -1,5 +1,6 @@ An attempt was made to constrain an associated type. -For example: + +Erroneous code example: ```compile_fail,E0222 pub trait Vehicle { From 0f5ed4d2cdc3678cdd3a5c2dceb85a0ac8564f87 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 Jan 2020 13:53:39 +0100 Subject: [PATCH 0582/1253] Clean up E0207 explanation --- src/librustc_error_codes/error_codes/E0207.md | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0207.md b/src/librustc_error_codes/error_codes/E0207.md index 67b2063504c07..21e7e461c753b 100644 --- a/src/librustc_error_codes/error_codes/E0207.md +++ b/src/librustc_error_codes/error_codes/E0207.md @@ -1,3 +1,19 @@ +A type or lifetime parameter that is specified for `impl` is not constrained. + +Erroneous code example: + +```compile_fail,E0207 +struct Foo; + +impl Foo { + // error: the type parameter `T` is not constrained by the impl trait, self + // type, or predicates [E0207] + fn get(&self) -> T { + ::default() + } +} +``` + Any type parameter or lifetime parameter of an `impl` must meet at least one of the following criteria: @@ -10,19 +26,7 @@ the following criteria: ### Error example 1 Suppose we have a struct `Foo` and we would like to define some methods for it. -The following definition leads to a compiler error: - -```compile_fail,E0207 -struct Foo; - -impl Foo { -// error: the type parameter `T` is not constrained by the impl trait, self -// type, or predicates [E0207] - fn get(&self) -> T { - ::default() - } -} -``` +The previous code example has a definition which leads to a compiler error: The problem is that the parameter `T` does not appear in the implementing type (`Foo`) of the impl. In this case, we can fix the error by moving the type From 06064b99fd62116c3c96d60b4b1cc78dbac4669d Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 23 Jan 2020 13:27:36 +0100 Subject: [PATCH 0583/1253] Add my (@flip1995) name to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 1634c2da518cc..6ab6be26cf101 100644 --- a/.mailmap +++ b/.mailmap @@ -211,6 +211,7 @@ Peter Liniker Phil Dawes Phil Dawes Philipp Brüschweiler Philipp Brüschweiler +Philipp Krones flip1995 Philipp Matthias Schäfer Przemysław Wesołek Przemek Wesołek Rafael Ávila de Espíndola Rafael Avila de Espindola From ad1cdecaeb64fa020c46ce43d87a8e33fc3fdafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuomas=20Lappetel=C3=A4inen?= Date: Thu, 23 Jan 2020 15:16:16 +0200 Subject: [PATCH 0584/1253] add a test for #60976 The test fails on 1.36.0 but passes on master. --- src/test/ui/use/auxiliary/extern-use-primitive-type-lib.rs | 3 +++ src/test/ui/use/issue-60976-extern-use-primitive-type.rs | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 src/test/ui/use/auxiliary/extern-use-primitive-type-lib.rs create mode 100644 src/test/ui/use/issue-60976-extern-use-primitive-type.rs diff --git a/src/test/ui/use/auxiliary/extern-use-primitive-type-lib.rs b/src/test/ui/use/auxiliary/extern-use-primitive-type-lib.rs new file mode 100644 index 0000000000000..3c7756ef7e679 --- /dev/null +++ b/src/test/ui/use/auxiliary/extern-use-primitive-type-lib.rs @@ -0,0 +1,3 @@ +// compile-flags: --edition=2018 + +pub use u32; diff --git a/src/test/ui/use/issue-60976-extern-use-primitive-type.rs b/src/test/ui/use/issue-60976-extern-use-primitive-type.rs new file mode 100644 index 0000000000000..4cd458302a498 --- /dev/null +++ b/src/test/ui/use/issue-60976-extern-use-primitive-type.rs @@ -0,0 +1,7 @@ +// Regression test for #60976: ICE (with <=1.36.0) when another file had `use ;`. +// check-pass +// aux-build:extern-use-primitive-type-lib.rs + +extern crate extern_use_primitive_type_lib; + +fn main() {} From 197cc1e43afba388a0266a08d2b946a187b766bb Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 22 Jan 2020 12:17:21 +0100 Subject: [PATCH 0585/1253] Add projection query for upstream drop-glue instances. This reduces the amount of invalidated data when new types are add to upstream crates. --- src/librustc/middle/exported_symbols.rs | 30 +++------ src/librustc/query/mod.rs | 34 ++++++++++ src/librustc/ty/instance.rs | 36 ++++++++++- src/librustc/ty/query/keys.rs | 9 +++ src/librustc_codegen_llvm/callee.rs | 7 +-- .../back/symbol_export.rs | 63 ++++++++++++++----- src/librustc_codegen_utils/symbol_names.rs | 25 +------- src/librustc_mir/monomorphize/collector.rs | 32 +--------- 8 files changed, 138 insertions(+), 98 deletions(-) diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index 511a77bf830e5..1f4318fa53751 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -1,9 +1,7 @@ -use crate::ich::StableHashingContext; use crate::ty::subst::SubstsRef; -use crate::ty::{self, TyCtxt}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use std::mem; +use rustc_macros::HashStable; /// The SymbolExportLevel of a symbols specifies from which kinds of crates /// the symbol will be exported. `C` symbols will be exported from any @@ -23,10 +21,11 @@ impl SymbolExportLevel { } } -#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)] +#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum ExportedSymbol<'tcx> { NonGeneric(DefId), Generic(DefId, SubstsRef<'tcx>), + DropGlue(Ty<'tcx>), NoDefId(ty::SymbolName), } @@ -39,6 +38,9 @@ impl<'tcx> ExportedSymbol<'tcx> { ExportedSymbol::Generic(def_id, substs) => { tcx.symbol_name(ty::Instance::new(def_id, substs)) } + ExportedSymbol::DropGlue(ty) => { + tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty)) + } ExportedSymbol::NoDefId(symbol_name) => symbol_name, } } @@ -51,21 +53,3 @@ pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String { tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex() ) } - -impl<'a, 'tcx> HashStable> for ExportedSymbol<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - ExportedSymbol::NonGeneric(def_id) => { - def_id.hash_stable(hcx, hasher); - } - ExportedSymbol::Generic(def_id, substs) => { - def_id.hash_stable(hcx, hasher); - substs.hash_stable(hcx, hasher); - } - ExportedSymbol::NoDefId(symbol_name) => { - symbol_name.hash_stable(hcx, hasher); - } - } - } -} diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index deb2d6ac630ac..37d5e23535b81 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -776,13 +776,47 @@ rustc_queries! { } Codegen { + /// The entire set of monomorphizations the local crate can safely link + /// to because they are exported from upstream crates. Do not depend on + /// this directly, as its value changes anytime a monomorphization gets + /// added or removed in any upstream crate. Instead use the narrower + /// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even + /// better, `Instance::upstream_monomorphization()`. query upstream_monomorphizations( k: CrateNum ) -> &'tcx DefIdMap, CrateNum>> { desc { "collecting available upstream monomorphizations `{:?}`", k } } + + /// Returns the set of upstream monomorphizations available for the + /// generic function identified by the given `def_id`. The query makes + /// sure to make a stable selection if the same monomorphization is + /// available in multiple upstream crates. + /// + /// You likely want to call `Instance::upstream_monomorphization()` + /// instead of invoking this query directly. query upstream_monomorphizations_for(_: DefId) -> Option<&'tcx FxHashMap, CrateNum>> {} + + /// Returns the upstream crate that exports drop-glue for the given + /// type (`substs` is expected to be a single-item list containing the + /// type one wants drop-glue for). + /// + /// This is a subset of `upstream_monomorphizations_for` in order to + /// increase dep-tracking granularity. Otherwise adding or removing any + /// type with drop-glue in any upstream crate would invalidate all + /// functions calling drop-glue of an upstream type. + /// + /// You likely want to call `Instance::upstream_monomorphization()` + /// instead of invoking this query directly. + /// + /// NOTE: This query could easily be extended to also support other + /// common functions that have are large set of monomorphizations + /// (like `Clone::clone` for example). + query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option { + desc { "available upstream drop-glue for `{:?}`", substs } + no_force + } } Other { diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index c4770184612cb..51a18f8eae274 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -4,7 +4,7 @@ use crate::traits; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable}; use rustc_hir::def::Namespace; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{CrateNum, DefId}; use rustc_macros::HashStable; use rustc_target::spec::abi::Abi; @@ -91,6 +91,40 @@ impl<'tcx> Instance<'tcx> { let ty = tcx.type_of(self.def.def_id()); tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty) } + + /// Finds a crate that contains a monomorphization of this instance that + /// can be linked to from the local crate. A return value of `None` means + /// no upstream crate provides such an exported monomorphization. + /// + /// This method already takes into account the global `-Zshare-generics` + /// setting, always returning `None` if `share-generics` is off. + pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option { + // If we are not in share generics mode, we don't link to upstream + // monomorphizations but always instantiate our own internal versions + // instead. + if !tcx.sess.opts.share_generics() { + return None; + } + + // If this is an item that is defined in the local crate, no upstream + // crate can know about it/provide a monomorphization. + if self.def_id().is_local() { + return None; + } + + // If this a non-generic instance, it cannot be a shared monomorphization. + if self.substs.non_erasable_generics().next().is_none() { + return None; + } + + match self.def { + InstanceDef::Item(def_id) => tcx + .upstream_monomorphizations_for(def_id) + .and_then(|monos| monos.get(&self.substs).cloned()), + InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs), + _ => None, + } + } } impl<'tcx> InstanceDef<'tcx> { diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index cbf335ad607ef..c1c88e96f94b5 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -116,6 +116,15 @@ impl Key for (DefId, SimplifiedType) { } } +impl<'tcx> Key for SubstsRef<'tcx> { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { fn query_crate(&self) -> CrateNum { self.0.krate diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 78dd6fc8ffe75..04d92142266ee 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -130,12 +130,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value } else { // This is a monomorphization of a generic function // defined in an upstream crate. - if cx - .tcx - .upstream_monomorphizations_for(instance_def_id) - .map(|set| set.contains_key(instance.substs)) - .unwrap_or(false) - { + if instance.upstream_monomorphization(tcx).is_some() { // This is instantiated in another crate. It cannot // be `hidden`. } else { diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 7e888a271e316..a6cd0c09684dd 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -255,14 +255,13 @@ fn exported_symbols_provider_local( symbols.push((symbol, SymbolExportLevel::Rust)); } } - MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), substs }) => { + MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => { // A little sanity-check debug_assert_eq!( substs.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)) ); - let symbol = ExportedSymbol::Generic(def_id, substs); - symbols.push((symbol, SymbolExportLevel::Rust)); + symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportLevel::Rust)); } _ => { // Any other symbols don't qualify for sharing @@ -298,24 +297,41 @@ fn upstream_monomorphizations_provider( cnum_stable_ids }; + let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn(); + for &cnum in cnums.iter() { for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { - if let &ExportedSymbol::Generic(def_id, substs) = exported_symbol { - let substs_map = instances.entry(def_id).or_default(); - - match substs_map.entry(substs) { - Occupied(mut e) => { - // If there are multiple monomorphizations available, - // we select one deterministically. - let other_cnum = *e.get(); - if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { - e.insert(cnum); - } + let (def_id, substs) = match *exported_symbol { + ExportedSymbol::Generic(def_id, substs) => (def_id, substs), + ExportedSymbol::DropGlue(ty) => { + if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id { + (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()])) + } else { + // `drop_in_place` in place does not exist, don't try + // to use it. + continue; } - Vacant(e) => { + } + ExportedSymbol::NonGeneric(..) | ExportedSymbol::NoDefId(..) => { + // These are no monomorphizations + continue; + } + }; + + let substs_map = instances.entry(def_id).or_default(); + + match substs_map.entry(substs) { + Occupied(mut e) => { + // If there are multiple monomorphizations available, + // we select one deterministically. + let other_cnum = *e.get(); + if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { e.insert(cnum); } } + Vacant(e) => { + e.insert(cnum); + } } } } @@ -331,6 +347,17 @@ fn upstream_monomorphizations_for_provider( tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } +fn upstream_drop_glue_for_provider<'tcx>( + tcx: TyCtxt<'tcx>, + substs: SubstsRef<'tcx>, +) -> Option { + if let Some(def_id) = tcx.lang_items().drop_in_place_fn() { + tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned()) + } else { + None + } +} + fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { !tcx.reachable_set(LOCAL_CRATE).contains(&hir_id) @@ -345,6 +372,7 @@ pub fn provide(providers: &mut Providers<'_>) { providers.exported_symbols = exported_symbols_provider_local; providers.upstream_monomorphizations = upstream_monomorphizations_provider; providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; + providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; } pub fn provide_extern(providers: &mut Providers<'_>) { @@ -405,6 +433,11 @@ pub fn symbol_name_for_instance_in_crate<'tcx>( Instance::new(def_id, substs), instantiating_crate, ), + ExportedSymbol::DropGlue(ty) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::resolve_drop_in_place(tcx, ty), + instantiating_crate, + ), ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 96a74f96fcf60..6713459f627ef 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -126,29 +126,10 @@ fn symbol_name_provider(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::Symb // This closure determines the instantiating crate for instances that // need an instantiating-crate-suffix for their symbol name, in order // to differentiate between local copies. - // - // For generics we might find re-usable upstream instances. For anything - // else we rely on their being a local copy available. - if is_generic(instance.substs) { - let def_id = instance.def_id(); - - if !def_id.is_local() && tcx.sess.opts.share_generics() { - // If we are re-using a monomorphization from another crate, - // we have to compute the symbol hash accordingly. - let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id); - - upstream_monomorphizations - .and_then(|monos| monos.get(&instance.substs).cloned()) - // If there is no instance available upstream, there'll be - // one in the current crate. - .unwrap_or(LOCAL_CRATE) - } else { - // For generic functions defined in the current crate, there - // can be no upstream instances. Also, if we don't share - // generics, we'll instantiate a local copy too. - LOCAL_CRATE - } + // For generics we might find re-usable upstream instances. If there + // is one, we rely on the symbol being instantiated locally. + instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE) } else { // For non-generic things that need to avoid naming conflicts, we // always instantiate a copy in the local crate. diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 91e685babbcdd..dd2071a6c596a 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -737,9 +737,7 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx return true; } - if tcx.is_reachable_non_generic(def_id) - || is_available_upstream_generic(tcx, def_id, instance.substs) - { + if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(tcx).is_some() { // We can link to the item in question, no instance needed // in this crate. return false; @@ -750,34 +748,6 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx } return true; - - fn is_available_upstream_generic<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: DefId, - substs: SubstsRef<'tcx>, - ) -> bool { - debug_assert!(!def_id.is_local()); - - // If we are not in share generics mode, we don't link to upstream - // monomorphizations but always instantiate our own internal versions - // instead. - if !tcx.sess.opts.share_generics() { - return false; - } - - // If this instance has non-erasable parameters, it cannot be a shared - // monomorphization. Non-generic instances are already handled above - // by `is_reachable_non_generic()`. - if substs.non_erasable_generics().next().is_none() { - return false; - } - - // Take a look at the available monomorphizations listed in the metadata - // of upstream crates. - tcx.upstream_monomorphizations_for(def_id) - .map(|set| set.contains_key(substs)) - .unwrap_or(false) - } } /// For a given pair of source and target type that occur in an unsizing coercion, From 6eaf59dfc8be4ee5647f9c090c5a7668682f30c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 23 Jan 2020 11:51:56 -0800 Subject: [PATCH 0586/1253] use `diagnostic_item` and modify wording --- src/libcore/option.rs | 1 + src/libcore/result.rs | 1 + .../borrow_check/diagnostics/move_errors.rs | 22 ++++++++++++++----- src/test/ui/suggestions/for-i-in-vec.stderr | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index a471b174534aa..cb4247d98745e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -151,6 +151,7 @@ use crate::{ /// The `Option` type. See [the module level documentation](index.html) for more. #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[rustc_diagnostic_item = "option_type"] #[stable(feature = "rust1", since = "1.0.0")] pub enum Option { /// No value diff --git a/src/libcore/result.rs b/src/libcore/result.rs index c657ce33f60ad..bc70dbd62eb52 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -242,6 +242,7 @@ use crate::ops::{self, Deref, DerefMut}; /// [`Err`]: enum.Result.html#variant.Err #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[must_use = "this `Result` may be an `Err` variant, which should be handled"] +#[rustc_diagnostic_item = "result_type"] #[stable(feature = "rust1", since = "1.0.0")] pub enum Result { /// Contains the success value diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index c016cc90b1b86..43121b38da01a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -2,7 +2,7 @@ use rustc::mir::*; use rustc::ty; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_span::source_map::DesugaringKind; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::borrow_check::diagnostics::UseSpans; use crate::borrow_check::prefixes::PrefixSet; @@ -384,10 +384,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } }; - let move_ty = format!("{:?}", move_place.ty(*self.body, self.infcx.tcx).ty,); if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { - let is_option = move_ty.starts_with("std::option::Option"); - let is_result = move_ty.starts_with("std::result::Result"); + let def_id = match move_place.ty(*self.body, self.infcx.tcx).ty.kind { + ty::Adt(self_def, _) => self_def.did, + ty::Foreign(def_id) + | ty::FnDef(def_id, _) + | ty::Closure(def_id, _) + | ty::Generator(def_id, ..) + | ty::Opaque(def_id, _) => def_id, + _ => return err, + }; + let is_option = + self.infcx.tcx.is_diagnostic_item(Symbol::intern("option_type"), def_id); + let is_result = + self.infcx.tcx.is_diagnostic_item(Symbol::intern("result_type"), def_id); if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) { err.span_suggestion( span, @@ -399,12 +409,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } else if span.is_desugaring(DesugaringKind::ForLoop) - && move_ty.starts_with("std::vec::Vec") + && self.infcx.tcx.is_diagnostic_item(Symbol::intern("vec_type"), def_id) { // FIXME: suggest for anything that implements `IntoIterator`. err.span_suggestion( span, - "consider iterating over a slice of the `Vec`'s content", + "consider iterating over a slice of the `Vec<_>`'s content", format!("&{}", snippet), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/suggestions/for-i-in-vec.stderr b/src/test/ui/suggestions/for-i-in-vec.stderr index 0fd10489bd0df..576a7cc2f6043 100644 --- a/src/test/ui/suggestions/for-i-in-vec.stderr +++ b/src/test/ui/suggestions/for-i-in-vec.stderr @@ -5,7 +5,7 @@ LL | for _ in self.v { | ^^^^^^ | | | move occurs because `self.v` has type `std::vec::Vec`, which does not implement the `Copy` trait - | help: consider iterating over a slice of the `Vec`'s content: `&self.v` + | help: consider iterating over a slice of the `Vec<_>`'s content: `&self.v` error: aborting due to previous error From b5ff8064a4fe5b2bc70ee209b19d129b8ffc3ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Jan 2020 22:16:52 +0100 Subject: [PATCH 0587/1253] Add MIN/MAX associated constants to the integer types --- src/libcore/num/mod.rs | 70 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 072966abf2c40..e717d0e42bb00 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -245,42 +245,54 @@ macro_rules! int_impl { $reversed:expr, $le_bytes:expr, $be_bytes:expr, $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { doc_comment! { - concat!("Returns the smallest value that can be represented by this integer type. + concat!("The smallest value that can be represented by this integer type. # Examples Basic usage: ``` -", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), ", stringify!($Min), ");", +", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");", $EndFeature, " ```"), - #[stable(feature = "rust1", since = "1.0.0")] - #[inline(always)] - #[rustc_promotable] - #[rustc_const_stable(feature = "const_min_value", since = "1.32.0")] - pub const fn min_value() -> Self { - !0 ^ ((!0 as $UnsignedT) >> 1) as Self - } + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self; } doc_comment! { - concat!("Returns the largest value that can be represented by this integer type. + concat!("The largest value that can be represented by this integer type. # Examples Basic usage: ``` -", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ", stringify!($Max), ");", +", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");", $EndFeature, " ```"), + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX: Self = !Self::MIN; + } + + doc_comment! { + "Returns the smallest value that can be represented by this integer type.", + #[stable(feature = "rust1", since = "1.0.0")] + #[inline(always)] + #[rustc_promotable] + #[rustc_const_stable(feature = "const_min_value", since = "1.32.0")] + pub const fn min_value() -> Self { + Self::MIN + } + } + + doc_comment! { + "Returns the largest value that can be represented by this integer type.", #[stable(feature = "rust1", since = "1.0.0")] #[inline(always)] #[rustc_promotable] #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] pub const fn max_value() -> Self { - !Self::min_value() + Self::MAX } } @@ -2342,38 +2354,50 @@ macro_rules! uint_impl { $reversed:expr, $le_bytes:expr, $be_bytes:expr, $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { doc_comment! { - concat!("Returns the smallest value that can be represented by this integer type. + concat!("The smallest value that can be represented by this integer type. # Examples Basic usage: ``` -", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), 0);", $EndFeature, " +", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, 0);", $EndFeature, " ```"), - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_promotable] - #[inline(always)] - #[rustc_const_stable(feature = "const_min_value", since = "1.32.0")] - pub const fn min_value() -> Self { 0 } + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN: Self = 0; } doc_comment! { - concat!("Returns the largest value that can be represented by this integer type. + concat!("The largest value that can be represented by this integer type. # Examples Basic usage: ``` -", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ", -stringify!($MaxV), ");", $EndFeature, " +", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");", +$EndFeature, " ```"), + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX: Self = !0; + } + + doc_comment! { + "Returns the smallest value that can be represented by this integer type.", + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_promotable] + #[inline(always)] + #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] + pub const fn min_value() -> Self { Self::MIN } + } + + doc_comment! { + "Returns the largest value that can be represented by this integer type.", #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[inline(always)] #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] - pub const fn max_value() -> Self { !0 } + pub const fn max_value() -> Self { Self::MAX } } doc_comment! { From 22dcfa1d8d18687d7ca0b91974bce4202d3383e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Jan 2020 20:39:15 +0100 Subject: [PATCH 0588/1253] Add relevant associated constants to the float types --- src/libcore/num/f32.rs | 82 ++++++++++++++++++++++++++++++++++-------- src/libcore/num/f64.rs | 81 +++++++++++++++++++++++++++++++++-------- 2 files changed, 135 insertions(+), 28 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 505484c2a49dc..da8dd9acd9f48 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -15,14 +15,14 @@ use crate::num::FpCategory; /// The radix or base of the internal representation of `f32`. #[stable(feature = "rust1", since = "1.0.0")] -pub const RADIX: u32 = 2; +pub const RADIX: u32 = f32::RADIX; /// Number of significant digits in base 2. #[stable(feature = "rust1", since = "1.0.0")] -pub const MANTISSA_DIGITS: u32 = 24; +pub const MANTISSA_DIGITS: u32 = f32::MANTISSA_DIGITS; /// Approximate number of significant digits in base 10. #[stable(feature = "rust1", since = "1.0.0")] -pub const DIGITS: u32 = 6; +pub const DIGITS: u32 = f32::DIGITS; /// [Machine epsilon] value for `f32`. /// @@ -30,41 +30,41 @@ pub const DIGITS: u32 = 6; /// /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon #[stable(feature = "rust1", since = "1.0.0")] -pub const EPSILON: f32 = 1.1920929e-7_f32; +pub const EPSILON: f32 = f32::EPSILON; /// Smallest finite `f32` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN: f32 = -3.40282347e+38_f32; +pub const MIN: f32 = f32::MIN; /// Smallest positive normal `f32` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; +pub const MIN_POSITIVE: f32 = f32::MIN_POSITIVE; /// Largest finite `f32` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX: f32 = 3.40282347e+38_f32; +pub const MAX: f32 = f32::MAX; /// One greater than the minimum possible normal power of 2 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_EXP: i32 = -125; +pub const MIN_EXP: i32 = f32::MIN_EXP; /// Maximum possible power of 2 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX_EXP: i32 = 128; +pub const MAX_EXP: i32 = f32::MAX_EXP; /// Minimum possible normal power of 10 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_10_EXP: i32 = -37; +pub const MIN_10_EXP: i32 = f32::MIN_10_EXP; /// Maximum possible power of 10 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX_10_EXP: i32 = 38; +pub const MAX_10_EXP: i32 = f32::MAX_10_EXP; /// Not a Number (NaN). #[stable(feature = "rust1", since = "1.0.0")] -pub const NAN: f32 = 0.0_f32 / 0.0_f32; +pub const NAN: f32 = f32::NAN; /// Infinity (∞). #[stable(feature = "rust1", since = "1.0.0")] -pub const INFINITY: f32 = 1.0_f32 / 0.0_f32; +pub const INFINITY: f32 = f32::INFINITY; /// Negative infinity (−∞). #[stable(feature = "rust1", since = "1.0.0")] -pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32; +pub const NEG_INFINITY: f32 = f32::NEG_INFINITY; /// Basic mathematical constants. #[stable(feature = "rust1", since = "1.0.0")] @@ -153,6 +153,60 @@ pub mod consts { #[lang = "f32"] #[cfg(not(test))] impl f32 { + /// The radix or base of the internal representation of `f32`. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const RADIX: u32 = 2; + + /// Number of significant digits in base 2. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MANTISSA_DIGITS: u32 = 24; + + /// Approximate number of significant digits in base 10. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const DIGITS: u32 = 6; + + /// [Machine epsilon] value for `f32`. + /// + /// This is the difference between `1.0` and the next larger representable number. + /// + /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const EPSILON: f32 = 1.19209290e-07_f32; + + /// Smallest finite `f32` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN: f32 = -3.40282347e+38_f32; + /// Smallest positive normal `f32` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; + /// Largest finite `f32` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX: f32 = 3.40282347e+38_f32; + + /// One greater than the minimum possible normal power of 2 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_EXP: i32 = -125; + /// Maximum possible power of 2 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX_EXP: i32 = 128; + + /// Minimum possible normal power of 10 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_10_EXP: i32 = -37; + /// Maximum possible power of 10 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX_10_EXP: i32 = 38; + + /// Not a Number (NaN). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const NAN: f32 = 0.0_f32 / 0.0_f32; + /// Infinity (∞). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const INFINITY: f32 = 1.0_f32 / 0.0_f32; + /// Negative infinity (-∞). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32; + /// Returns `true` if this value is `NaN`. /// /// ``` diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 8f3af42d25d80..a6081f184ab22 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -15,14 +15,14 @@ use crate::num::FpCategory; /// The radix or base of the internal representation of `f64`. #[stable(feature = "rust1", since = "1.0.0")] -pub const RADIX: u32 = 2; +pub const RADIX: u32 = f64::RADIX; /// Number of significant digits in base 2. #[stable(feature = "rust1", since = "1.0.0")] -pub const MANTISSA_DIGITS: u32 = 53; +pub const MANTISSA_DIGITS: u32 = f64::MANTISSA_DIGITS; /// Approximate number of significant digits in base 10. #[stable(feature = "rust1", since = "1.0.0")] -pub const DIGITS: u32 = 15; +pub const DIGITS: u32 = f64::DIGITS; /// [Machine epsilon] value for `f64`. /// @@ -30,41 +30,41 @@ pub const DIGITS: u32 = 15; /// /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon #[stable(feature = "rust1", since = "1.0.0")] -pub const EPSILON: f64 = 2.2204460492503131e-16_f64; +pub const EPSILON: f64 = f64::EPSILON; /// Smallest finite `f64` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN: f64 = -1.7976931348623157e+308_f64; +pub const MIN: f64 = f64::MIN; /// Smallest positive normal `f64` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; +pub const MIN_POSITIVE: f64 = f64::MIN_POSITIVE; /// Largest finite `f64` value. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX: f64 = 1.7976931348623157e+308_f64; +pub const MAX: f64 = f64::MAX; /// One greater than the minimum possible normal power of 2 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_EXP: i32 = -1021; +pub const MIN_EXP: i32 = f64::MIN_EXP; /// Maximum possible power of 2 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX_EXP: i32 = 1024; +pub const MAX_EXP: i32 = f64::MAX_EXP; /// Minimum possible normal power of 10 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MIN_10_EXP: i32 = -307; +pub const MIN_10_EXP: i32 = f64::MIN_10_EXP; /// Maximum possible power of 10 exponent. #[stable(feature = "rust1", since = "1.0.0")] -pub const MAX_10_EXP: i32 = 308; +pub const MAX_10_EXP: i32 = f64::MAX_10_EXP; /// Not a Number (NaN). #[stable(feature = "rust1", since = "1.0.0")] -pub const NAN: f64 = 0.0_f64 / 0.0_f64; +pub const NAN: f64 = f64::NAN; /// Infinity (∞). #[stable(feature = "rust1", since = "1.0.0")] -pub const INFINITY: f64 = 1.0_f64 / 0.0_f64; +pub const INFINITY: f64 = f64::INFINITY; /// Negative infinity (−∞). #[stable(feature = "rust1", since = "1.0.0")] -pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64; +pub const NEG_INFINITY: f64 = f64::NEG_INFINITY; /// Basic mathematical constants. #[stable(feature = "rust1", since = "1.0.0")] @@ -153,6 +153,59 @@ pub mod consts { #[lang = "f64"] #[cfg(not(test))] impl f64 { + /// The radix or base of the internal representation of `f64`. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const RADIX: u32 = 2; + + /// Number of significant digits in base 2. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MANTISSA_DIGITS: u32 = 53; + /// Approximate number of significant digits in base 10. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const DIGITS: u32 = 15; + + /// [Machine epsilon] value for `f64`. + /// + /// This is the difference between `1.0` and the next larger representable number. + /// + /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const EPSILON: f64 = 2.2204460492503131e-16_f64; + + /// Smallest finite `f64` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN: f64 = -1.7976931348623157e+308_f64; + /// Smallest positive normal `f64` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; + /// Largest finite `f64` value. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX: f64 = 1.7976931348623157e+308_f64; + + /// One greater than the minimum possible normal power of 2 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_EXP: i32 = -1021; + /// Maximum possible power of 2 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX_EXP: i32 = 1024; + + /// Minimum possible normal power of 10 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MIN_10_EXP: i32 = -307; + /// Maximum possible power of 10 exponent. + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const MAX_10_EXP: i32 = 308; + + /// Not a Number (NaN). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const NAN: f64 = 0.0_f64 / 0.0_f64; + /// Infinity (∞). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const INFINITY: f64 = 1.0_f64 / 0.0_f64; + /// Negative infinity (-∞). + #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] + pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64; + /// Returns `true` if this value is `NaN`. /// /// ``` From 9d257579fcaa44f69c8f7d5f668b05ae89e4507b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Jan 2020 20:49:33 +0100 Subject: [PATCH 0589/1253] Fix some float operations to work together with the assoc consts --- src/libcore/num/dec2flt/rawfp.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/num/dec2flt/rawfp.rs b/src/libcore/num/dec2flt/rawfp.rs index a127c6c3fa7ce..0ab15b23e5337 100644 --- a/src/libcore/num/dec2flt/rawfp.rs +++ b/src/libcore/num/dec2flt/rawfp.rs @@ -129,15 +129,15 @@ macro_rules! other_constants { ($type: ident) => { const EXPLICIT_SIG_BITS: u8 = Self::SIG_BITS - 1; const MAX_EXP: i16 = (1 << (Self::EXP_BITS - 1)) - 1; - const MIN_EXP: i16 = -Self::MAX_EXP + 1; - const MAX_EXP_INT: i16 = Self::MAX_EXP - (Self::SIG_BITS as i16 - 1); + const MIN_EXP: i16 = -::MAX_EXP + 1; + const MAX_EXP_INT: i16 = ::MAX_EXP - (Self::SIG_BITS as i16 - 1); const MAX_ENCODED_EXP: i16 = (1 << Self::EXP_BITS) - 1; - const MIN_EXP_INT: i16 = Self::MIN_EXP - (Self::SIG_BITS as i16 - 1); + const MIN_EXP_INT: i16 = ::MIN_EXP - (Self::SIG_BITS as i16 - 1); const MAX_SIG: u64 = (1 << Self::SIG_BITS) - 1; const MIN_SIG: u64 = 1 << (Self::SIG_BITS - 1); - const INFINITY: Self = $crate::$type::INFINITY; - const NAN: Self = $crate::$type::NAN; + const INFINITY: Self = $type::INFINITY; + const NAN: Self = $type::NAN; const ZERO: Self = 0.0; }; } From 6ce16cfa42dcb1acd2c823a1d45269132d372409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Jan 2020 23:01:42 +0100 Subject: [PATCH 0590/1253] Remove no longer valid test --- src/test/ui/issues/issue-22933-3.rs | 4 ---- src/test/ui/issues/issue-22933-3.stderr | 14 -------------- 2 files changed, 18 deletions(-) delete mode 100644 src/test/ui/issues/issue-22933-3.rs delete mode 100644 src/test/ui/issues/issue-22933-3.stderr diff --git a/src/test/ui/issues/issue-22933-3.rs b/src/test/ui/issues/issue-22933-3.rs deleted file mode 100644 index fbcce4b834467..0000000000000 --- a/src/test/ui/issues/issue-22933-3.rs +++ /dev/null @@ -1,4 +0,0 @@ -const FOO: [u32; u8::MIN as usize] = []; -//~^ ERROR no associated item named `MIN` found - -fn main() {} diff --git a/src/test/ui/issues/issue-22933-3.stderr b/src/test/ui/issues/issue-22933-3.stderr deleted file mode 100644 index 72bca3b040839..0000000000000 --- a/src/test/ui/issues/issue-22933-3.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0599]: no associated item named `MIN` found for type `u8` in the current scope - --> $DIR/issue-22933-3.rs:1:22 - | -LL | const FOO: [u32; u8::MIN as usize] = []; - | ^^^ associated item not found in `u8` - | -help: you are looking for the module in `std`, not the primitive type - | -LL | const FOO: [u32; std::u8::MIN as usize] = []; - | ^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. From 9fcbaa4158948324f395ff2eb8061abdf6dbc21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 19 Jan 2020 01:51:18 +0100 Subject: [PATCH 0591/1253] Fix broken show-const-contents test --- src/test/rustdoc/show-const-contents.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/rustdoc/show-const-contents.rs b/src/test/rustdoc/show-const-contents.rs index e84f6e52c75aa..064c026e6a078 100644 --- a/src/test/rustdoc/show-const-contents.rs +++ b/src/test/rustdoc/show-const-contents.rs @@ -47,9 +47,9 @@ pub struct MyTypeWithStr(&'static str); // @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //' pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this"); -// @has show_const_contents/constant.EPSILON.html '1.1920929e-7f32;' -// @!has show_const_contents/constant.EPSILON.html '; //' -pub use std::f32::EPSILON; +// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;' +// @has show_const_contents/constant.PI.html '; // 3.14159274f32' +pub use std::f32::consts::PI; // @has show_const_contents/constant.MAX.html '= i32::max_value(); // 2_147_483_647i32' pub use std::i32::MAX; From 4d9e90d2a5146e3f8639b53f29e210be94b30933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 19 Jan 2020 23:06:07 +0100 Subject: [PATCH 0592/1253] Unlock assoc_int_consts in core+std --- src/libcore/lib.rs | 1 + src/libstd/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f77b4d7461e74..ce7ddffd82584 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -134,6 +134,7 @@ #![feature(const_type_id)] #![feature(const_caller_location)] #![cfg_attr(bootstrap, feature(slice_patterns))] +#![feature(assoc_int_consts)] #[prelude_import] #[allow(unused)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index dc93ac90482fb..bc07c6b487b17 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -237,6 +237,7 @@ #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] +#![feature(assoc_int_consts)] #![feature(associated_type_bounds)] #![feature(box_syntax)] #![feature(c_variadic)] From 002c7897a6c92397f6682bf7e9e86c9b4efd5c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Wed, 22 Jan 2020 23:37:03 +0100 Subject: [PATCH 0593/1253] Unlock assoc_int_consts in documentation examples using it --- src/libcore/num/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index e717d0e42bb00..7480e93421b54 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -252,6 +252,7 @@ macro_rules! int_impl { Basic usage: ``` +#![feature(assoc_int_consts)] ", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");", $EndFeature, " ```"), @@ -267,6 +268,7 @@ $EndFeature, " Basic usage: ``` +#![feature(assoc_int_consts)] ", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");", $EndFeature, " ```"), @@ -2361,6 +2363,7 @@ macro_rules! uint_impl { Basic usage: ``` +#![feature(assoc_int_consts)] ", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, 0);", $EndFeature, " ```"), #[unstable(feature = "assoc_int_consts", reason = "recently added", issue = "68490")] @@ -2375,6 +2378,7 @@ Basic usage: Basic usage: ``` +#![feature(assoc_int_consts)] ", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");", $EndFeature, " ```"), From 61fecfb82fe088af6d3a7832b72f298064398aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Thu, 23 Jan 2020 20:10:43 +0100 Subject: [PATCH 0594/1253] Add test accessing the module level int/float consts --- src/test/ui/use-module-level-int-consts.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/test/ui/use-module-level-int-consts.rs diff --git a/src/test/ui/use-module-level-int-consts.rs b/src/test/ui/use-module-level-int-consts.rs new file mode 100644 index 0000000000000..758fb414eadf2 --- /dev/null +++ b/src/test/ui/use-module-level-int-consts.rs @@ -0,0 +1,11 @@ +// run-pass + +// Make sure the module level constants are still there and accessible even after +// the corresponding associated constants have been added, and later stabilized. +use std::{u16, f32}; + +fn main() { + let _ = u16::MAX; + let _ = f32::EPSILON; + let _ = std::f64::MANTISSA_DIGITS; +} From 72aaa3a414d17aa0c4f19feafa5bab5f84b60e63 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 21 Jan 2020 22:47:03 -0800 Subject: [PATCH 0595/1253] rustc: Allow cdylibs to link against dylibs Previously, rustc mandated that cdylibs could only link against rlibs as dependencies (not dylibs). This commit disables that restriction and tests that it works in a simple case. --- src/librustc_metadata/dependency_format.rs | 20 +++++++------- .../cdylib-dylib-linkage/Makefile | 27 +++++++++++++++++++ .../cdylib-dylib-linkage/bar.rs | 5 ++++ .../cdylib-dylib-linkage/foo.c | 10 +++++++ .../cdylib-dylib-linkage/foo.rs | 13 +++++++++ src/test/ui/auxiliary/cdylib-dep.rs | 1 - src/test/ui/cdylib-deps-must-be-static.rs | 10 ------- src/test/ui/cdylib-deps-must-be-static.stderr | 4 --- 8 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 src/test/run-make-fulldeps/cdylib-dylib-linkage/Makefile create mode 100644 src/test/run-make-fulldeps/cdylib-dylib-linkage/bar.rs create mode 100644 src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.c create mode 100644 src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.rs delete mode 100644 src/test/ui/auxiliary/cdylib-dep.rs delete mode 100644 src/test/ui/cdylib-deps-must-be-static.rs delete mode 100644 src/test/ui/cdylib-deps-must-be-static.stderr diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index 3427de19daa80..375f372005f7c 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -83,14 +83,17 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { } let preferred_linkage = match ty { - // cdylibs must have all static dependencies. - config::CrateType::Cdylib => Linkage::Static, - // Generating a dylib without `-C prefer-dynamic` means that we're going // to try to eagerly statically link all dependencies. This is normally // done for end-product dylibs, not intermediate products. - config::CrateType::Dylib if !sess.opts.cg.prefer_dynamic => Linkage::Static, - config::CrateType::Dylib => Linkage::Dynamic, + // + // Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may + // be code-size conscious, but without it, it makes sense to statically + // link a cdylib. + config::CrateType::Dylib | config::CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => { + Linkage::Static + } + config::CrateType::Dylib | config::CrateType::Cdylib => Linkage::Dynamic, // If the global prefer_dynamic switch is turned off, or the final // executable will be statically linked, prefer static crate linkage. @@ -122,10 +125,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { return v; } - // Staticlibs, cdylibs, and static executables must have all static - // dependencies. If any are not found, generate some nice pretty errors. - if ty == config::CrateType::Cdylib - || ty == config::CrateType::Staticlib + // Staticlibs and static executables must have all static dependencies. + // If any are not found, generate some nice pretty errors. + if ty == config::CrateType::Staticlib || (ty == config::CrateType::Executable && sess.crt_static() && !sess.target.target.options.crt_static_allows_dylibs) diff --git a/src/test/run-make-fulldeps/cdylib-dylib-linkage/Makefile b/src/test/run-make-fulldeps/cdylib-dylib-linkage/Makefile new file mode 100644 index 0000000000000..5c9b2d1bb2f1e --- /dev/null +++ b/src/test/run-make-fulldeps/cdylib-dylib-linkage/Makefile @@ -0,0 +1,27 @@ +include ../tools.mk + +TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib + +ifdef IS_MSVC +LIBSTD := $(wildcard $(TARGET_SYSROOT)/libstd-*.dll.lib) +else +LIBSTD := $(wildcard $(TARGET_SYSROOT)/$(call DYLIB_GLOB,std)) +STD := $(basename $(patsubst lib%,%, $(notdir $(LIBSTD)))) +endif + +all: $(call RUN_BINFILE,foo) + $(call RUN,foo) + +ifdef IS_MSVC +CLIBS := $(TMPDIR)/foo.dll.lib $(TMPDIR)/bar.dll.lib $(LIBSTD) +$(call RUN_BINFILE,foo): $(call DYLIB,foo) + $(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo) +else +CLIBS := -lfoo -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT) +$(call RUN_BINFILE,foo): $(call DYLIB,foo) + $(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo) +endif + +$(call DYLIB,foo): + $(RUSTC) -C prefer-dynamic bar.rs + $(RUSTC) foo.rs diff --git a/src/test/run-make-fulldeps/cdylib-dylib-linkage/bar.rs b/src/test/run-make-fulldeps/cdylib-dylib-linkage/bar.rs new file mode 100644 index 0000000000000..b3a7539abaeff --- /dev/null +++ b/src/test/run-make-fulldeps/cdylib-dylib-linkage/bar.rs @@ -0,0 +1,5 @@ +#![crate_type = "dylib"] + +pub fn bar() { + println!("hello!"); +} diff --git a/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.c b/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.c new file mode 100644 index 0000000000000..154f9682ef8f1 --- /dev/null +++ b/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.c @@ -0,0 +1,10 @@ +#include + +extern void foo(); +extern unsigned bar(unsigned a, unsigned b); + +int main() { + foo(); + assert(bar(1, 2) == 3); + return 0; +} diff --git a/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.rs b/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.rs new file mode 100644 index 0000000000000..c2cc3afcc1322 --- /dev/null +++ b/src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.rs @@ -0,0 +1,13 @@ +#![crate_type = "cdylib"] + +extern crate bar; + +#[no_mangle] +pub extern fn foo() { + bar::bar(); +} + +#[no_mangle] +pub extern fn bar(a: u32, b: u32) -> u32 { + a + b +} diff --git a/src/test/ui/auxiliary/cdylib-dep.rs b/src/test/ui/auxiliary/cdylib-dep.rs deleted file mode 100644 index 8bd2b3353b8f3..0000000000000 --- a/src/test/ui/auxiliary/cdylib-dep.rs +++ /dev/null @@ -1 +0,0 @@ -#![crate_type = "dylib"] diff --git a/src/test/ui/cdylib-deps-must-be-static.rs b/src/test/ui/cdylib-deps-must-be-static.rs deleted file mode 100644 index abf954d8fb2c4..0000000000000 --- a/src/test/ui/cdylib-deps-must-be-static.rs +++ /dev/null @@ -1,10 +0,0 @@ -// build-fail -// error-pattern: crate `cdylib_dep` required to be available in rlib format, but was not found -// aux-build:cdylib-dep.rs -// ignore-musl -// ignore-cloudabi -// ignore-emscripten -// ignore-sgx no dynamic libraries -#![crate_type = "cdylib"] - -extern crate cdylib_dep; diff --git a/src/test/ui/cdylib-deps-must-be-static.stderr b/src/test/ui/cdylib-deps-must-be-static.stderr deleted file mode 100644 index a1dc8e985dad0..0000000000000 --- a/src/test/ui/cdylib-deps-must-be-static.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: crate `cdylib_dep` required to be available in rlib format, but was not found in this form - -error: aborting due to previous error - From f30a8186f7469d464e46e3451e2b2e41609225dd Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 23 Jan 2020 20:34:11 +0000 Subject: [PATCH 0596/1253] Make pointers to statics internal --- src/librustc_mir/transform/check_unsafety.rs | 46 ++++++++++--------- src/librustc_mir_build/build/expr/as_temp.rs | 1 + .../check/generator_interior.rs | 13 +----- .../issues/issue-67611-static-mut-refs.rs | 33 +++++++++++++ .../static-mut-reference-across-yield.rs | 29 ++++++++++++ 5 files changed, 89 insertions(+), 33 deletions(-) create mode 100644 src/test/ui/async-await/issues/issue-67611-static-mut-refs.rs create mode 100644 src/test/ui/generator/static-mut-reference-across-yield.rs diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 4e943547f07f5..59d370abc71c5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -233,28 +233,30 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let (local, []) = (&place.local, proj_base) { let decl = &self.body.local_decls[*local]; if decl.internal { - // Internal locals are used in the `move_val_init` desugaring. - // We want to check unsafety against the source info of the - // desugaring, rather than the source info of the RHS. - self.source_info = self.body.local_decls[*local].source_info; - } else if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { - if self.tcx.is_mutable_static(def_id) { - self.require_unsafe( - "use of mutable static", - "mutable statics can be mutated by multiple threads: aliasing \ - violations or data races will cause undefined behavior", - UnsafetyViolationKind::General, - ); - return; - } else if self.tcx.is_foreign_item(def_id) { - self.require_unsafe( - "use of extern static", - "extern statics are not controlled by the Rust type system: \ - invalid data, aliasing violations or data races will cause \ - undefined behavior", - UnsafetyViolationKind::General, - ); - return; + if let LocalInfo::StaticRef { def_id, .. } = decl.local_info { + if self.tcx.is_mutable_static(def_id) { + self.require_unsafe( + "use of mutable static", + "mutable statics can be mutated by multiple threads: aliasing \ + violations or data races will cause undefined behavior", + UnsafetyViolationKind::General, + ); + return; + } else if self.tcx.is_foreign_item(def_id) { + self.require_unsafe( + "use of extern static", + "extern statics are not controlled by the Rust type system: \ + invalid data, aliasing violations or data races will cause \ + undefined behavior", + UnsafetyViolationKind::General, + ); + return; + } + } else { + // Internal locals are used in the `move_val_init` desugaring. + // We want to check unsafety against the source info of the + // desugaring, rather than the source info of the RHS. + self.source_info = self.body.local_decls[*local].source_info; } } } diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs index f47987c56174c..34dd10cbc0fc8 100644 --- a/src/librustc_mir_build/build/expr/as_temp.rs +++ b/src/librustc_mir_build/build/expr/as_temp.rs @@ -61,6 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } if let ExprKind::StaticRef { def_id, .. } = expr.kind { let is_thread_local = this.hir.tcx().has_attr(def_id, sym::thread_local); + local_decl.internal = true; local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local }; } this.local_decls.push(local_decl) diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index fc02d17a50f37..75cc2c132f8a8 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -222,8 +222,6 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { - let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); - match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => { @@ -249,20 +247,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { } _ => intravisit::walk_expr(self, expr), }, - ExprKind::Path(qpath) => { - let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id); - if let Res::Def(DefKind::Static, def_id) = res { - // Statics are lowered to temporary references or - // pointers in MIR, so record that type. - let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id); - self.record(ptr_ty, scope, Some(expr), expr.span); - } - } _ => intravisit::walk_expr(self, expr), } self.expr_count += 1; + let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + // If there are adjustments, then record the final type -- // this is the actual value that is being produced. if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) { diff --git a/src/test/ui/async-await/issues/issue-67611-static-mut-refs.rs b/src/test/ui/async-await/issues/issue-67611-static-mut-refs.rs new file mode 100644 index 0000000000000..dda4a151dd2d6 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-67611-static-mut-refs.rs @@ -0,0 +1,33 @@ +// build-pass +// edition:2018 + +static mut A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn is_send_sync(_: T) {} + +async fn fun() { + let u = unsafe { A[async { 1 }.await] }; + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } +} + +fn main() { + let index_block = async { + let u = unsafe { A[async { 1 }.await] }; + }; + let match_block = async { + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } + }; + is_send_sync(index_block); + is_send_sync(match_block); + is_send_sync(fun()); +} diff --git a/src/test/ui/generator/static-mut-reference-across-yield.rs b/src/test/ui/generator/static-mut-reference-across-yield.rs new file mode 100644 index 0000000000000..2926bba997803 --- /dev/null +++ b/src/test/ui/generator/static-mut-reference-across-yield.rs @@ -0,0 +1,29 @@ +// build-pass +#![feature(generators)] + +static mut A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn is_send_sync(_: T) {} + +fn main() { + unsafe { + let gen_index = static || { + let u = A[{ + yield; + 1 + }]; + }; + let gen_match = static || match A { + i if { + yield; + true + } => + { + () + } + _ => (), + }; + is_send_sync(gen_index); + is_send_sync(gen_match); + } +} From aabf4e9253cd935d22877b950bba2c551c1dcf2f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 8 Jan 2020 07:33:57 -0800 Subject: [PATCH 0597/1253] Update some of Cargo's dependencies This is primarily updating the `curl` dependency, but also went ahead and applied a few updates for other packages that Cargo depends on. --- Cargo.lock | 186 +++++++++++++++++++++++++---------------------------- 1 file changed, 88 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 237b3dda670df..9c359b464ef1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ version = "0.0.0" dependencies = [ "compiler_builtins", "core", - "rand 0.7.0", + "rand 0.7.3", "rand_xorshift 0.2.0", ] @@ -32,7 +32,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e266e1f4be5ffa05309f650e2586fe1d3ae6034eb24025a7ae1dfecc330823a" dependencies = [ "html5ever", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "maplit", "matches", "tendril", @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] name = "backtrace" @@ -199,7 +199,7 @@ dependencies = [ "filetime", "getopts", "ignore", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "libc", "num_cpus", "pretty_assertions", @@ -272,11 +272,10 @@ checksum = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" [[package]] name = "c2-chacha" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "lazy_static 1.3.0", "ppv-lite86", ] @@ -311,7 +310,7 @@ dependencies = [ "ignore", "im-rc", "jobserver", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "lazycell", "libc", "libgit2-sys", @@ -364,7 +363,7 @@ dependencies = [ "flate2", "git2", "glob", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "remove_dir_all", "serde_json", "tar", @@ -402,19 +401,18 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" dependencies = [ "jobserver", - "num_cpus", ] [[package]] name = "cfg-if" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89431bba4e6b7092fb5fcd00a6f6ca596c55cc26b2f1e6dcdd08a1f4933f66b2" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -476,7 +474,7 @@ dependencies = [ "compiletest_rs", "derive-new", "git2", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", "rustc-workspace-hack", "rustc_tools_util 0.2.0", @@ -497,7 +495,7 @@ dependencies = [ "cargo_metadata 0.9.0", "if_chain", "itertools 0.8.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "matches", "pulldown-cmark 0.6.1", "quine-mc_cluskey", @@ -592,7 +590,7 @@ dependencies = [ "diff", "env_logger 0.7.1", "getopts", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "libc", "log", "miow 0.3.3", @@ -664,7 +662,7 @@ dependencies = [ name = "core" version = "0.0.0" dependencies = [ - "rand 0.7.0", + "rand 0.7.3", ] [[package]] @@ -750,7 +748,7 @@ dependencies = [ "arrayvec", "cfg-if", "crossbeam-utils 0.6.5", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "memoffset", "scopeguard", ] @@ -771,7 +769,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" dependencies = [ "cfg-if", - "lazy_static 1.3.0", + "lazy_static 1.4.0", ] [[package]] @@ -782,7 +780,7 @@ checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" dependencies = [ "autocfg", "cfg-if", - "lazy_static 1.3.0", + "lazy_static 1.4.0", ] [[package]] @@ -799,9 +797,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08ad3cb89d076a36b0ce5749eec2c9964f70c0c58480ab6b75a91ec4fc206d8" +checksum = "06aa71e9208a54def20792d877bc663d6aae0732b9852e612c4a933177c31283" dependencies = [ "curl-sys", "libc", @@ -814,9 +812,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9a9a4e417722876332136a00cacf92c2ceb331fab4b52b6a1ad16c6cd79255" +checksum = "0c38ca47d60b86d0cc9d42caa90a0885669c2abc9791f871c81f58cdf39e979b" dependencies = [ "cc", "libc", @@ -979,7 +977,7 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", "serde", "serde_derive", @@ -1245,13 +1243,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ "cfg-if", "libc", - "wasi 0.7.0", + "wasi", ] [[package]] @@ -1329,7 +1327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d" dependencies = [ "hashbrown 0.5.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "pest", "pest_derive", @@ -1545,7 +1543,7 @@ checksum = "0ec16832258409d571aaef8273f3c3cc5b060d784e159d1a0f3b0017308f84a7" dependencies = [ "crossbeam-channel", "globset", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "memchr", "regex", @@ -1582,7 +1580,7 @@ dependencies = [ "clap", "failure", "flate2", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "num_cpus", "rayon", "remove_dir_all", @@ -1644,13 +1642,11 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f74e73053eaf95399bf926e48fc7a2a3ce50bd0eaaa2357d391e95b2dcdd4f10" +checksum = "67b06c1b455f1cf4269a8cfc320ab930a810e2375a42af5075eb8a8b36405ce0" dependencies = [ "libc", - "log", - "rand 0.7.0", ] [[package]] @@ -1747,7 +1743,7 @@ dependencies = [ "bytes", "globset", "jsonrpc-core", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "num_cpus", "tokio", @@ -1773,9 +1769,9 @@ checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" [[package]] name = "lazy_static" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" @@ -1808,9 +1804,9 @@ dependencies = [ [[package]] name = "libnghttp2-sys" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4" +checksum = "02254d44f4435dd79e695f2c2b83cd06a47919adea30216ceaf0c57ca0a72463" dependencies = [ "cc", "libc", @@ -1870,7 +1866,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", ] [[package]] @@ -1963,7 +1959,7 @@ dependencies = [ "error-chain", "handlebars", "itertools 0.8.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "memchr", "open", @@ -2157,7 +2153,7 @@ dependencies = [ "hex 0.4.0", "log", "num-traits", - "rand 0.7.0", + "rand 0.7.3", "rustc-workspace-hack", "rustc_version", "serde", @@ -2171,7 +2167,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "libc", "log", "openssl", @@ -2260,7 +2256,7 @@ dependencies = [ "bitflags", "cfg-if", "foreign-types", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "libc", "openssl-sys", ] @@ -2273,18 +2269,18 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.6.0+1.1.1d" +version = "111.6.1+1.1.1d" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9c2da1de8a7a3f860919c01540b03a6db16de042405a8a07a5e9d0b4b825d9c" +checksum = "c91b04cb43c1a8a90e934e0cd612e2a5715d976d2d6cff4490278a0cddf35005" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.52" +version = "0.9.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c977d08e1312e2f7e4b86f9ebaa0ed3b19d1daff75fae88bbb88108afbd801fc" +checksum = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" dependencies = [ "autocfg", "cc", @@ -2341,7 +2337,7 @@ dependencies = [ "log", "mio-named-pipes", "miow 0.3.3", - "rand 0.7.0", + "rand 0.7.3", "tokio", "tokio-named-pipes", "tokio-uds", @@ -2469,9 +2465,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "polonius-engine" @@ -2486,9 +2482,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "precomputed-hash" @@ -2579,7 +2575,7 @@ checksum = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510" dependencies = [ "error-chain", "idna 0.2.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", "url 2.1.0", ] @@ -2654,7 +2650,7 @@ dependencies = [ "derive_more", "env_logger 0.6.2", "humantime 1.3.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "rls-span", "rustc-ap-syntax", @@ -2681,9 +2677,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", @@ -2831,7 +2827,7 @@ dependencies = [ "crossbeam-deque", "crossbeam-queue", "crossbeam-utils 0.6.5", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "num_cpus", ] @@ -2846,9 +2842,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.43" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "redox_termios" @@ -2960,14 +2956,14 @@ dependencies = [ "home", "itertools 0.8.0", "jsonrpc-core", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "lsp-codec", "lsp-types", "num_cpus", "ordslice", "racer", - "rand 0.7.0", + "rand 0.7.3", "rayon", "regex", "rls-analysis", @@ -3040,7 +3036,7 @@ dependencies = [ "failure", "futures", "log", - "rand 0.7.0", + "rand 0.7.3", "rls-data", "rls-ipc", "serde", @@ -3139,7 +3135,7 @@ dependencies = [ "ena", "indexmap", "jobserver", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "parking_lot", "rustc-ap-graphviz", @@ -3232,7 +3228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61fc1c901d2cbd24cae95d7bc5a58aa7661ec3dc5320c78c32830a52a685c33c" dependencies = [ "bitflags", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "rustc-ap-rustc_data_structures", "rustc-ap-rustc_errors", @@ -3309,7 +3305,7 @@ dependencies = [ "crossbeam-deque", "crossbeam-queue", "crossbeam-utils 0.6.5", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "num_cpus", ] @@ -3488,7 +3484,7 @@ dependencies = [ "graphviz", "indexmap", "jobserver", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "measureme", "parking_lot", @@ -3507,7 +3503,7 @@ name = "rustc_driver" version = "0.0.0" dependencies = [ "env_logger 0.7.1", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "rustc", "rustc_codegen_utils", @@ -3572,7 +3568,7 @@ dependencies = [ name = "rustc_feature" version = "0.0.0" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "rustc_data_structures", "rustc_span", ] @@ -3603,7 +3599,7 @@ version = "0.0.0" dependencies = [ "graphviz", "log", - "rand 0.7.0", + "rand 0.7.3", "rustc", "rustc_data_structures", "rustc_fs_util", @@ -4057,7 +4053,7 @@ dependencies = [ "getopts", "ignore", "itertools 0.8.0", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "regex", "rustc-ap-rustc_target", @@ -4092,11 +4088,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" +checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "winapi 0.3.8", ] @@ -4296,9 +4292,9 @@ checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" [[package]] name = "socket2" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" +checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" dependencies = [ "cfg-if", "libc", @@ -4329,9 +4325,9 @@ dependencies = [ "panic_abort", "panic_unwind", "profiler_builtins", - "rand 0.7.0", + "rand 0.7.3", "unwind", - "wasi 0.9.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -4349,7 +4345,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "new_debug_unreachable", "phf_shared", "precomputed-hash", @@ -4517,7 +4513,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if", "libc", - "rand 0.7.0", + "rand 0.7.3", "redox_syscall", "remove_dir_all", "winapi 0.3.8", @@ -4624,14 +4620,14 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", ] [[package]] name = "tidy" version = "0.1.0" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", "serde", "serde_json", @@ -4758,7 +4754,7 @@ checksum = "afbd6ef1b8cc2bd2c2b580d882774d443ebb1c6ceefe35ba9ea4ab586c89dbe8" dependencies = [ "crossbeam-queue", "futures", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "libc", "log", "mio", @@ -4777,7 +4773,7 @@ checksum = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" dependencies = [ "crossbeam-utils 0.6.5", "futures", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "mio", "num_cpus", @@ -4848,7 +4844,7 @@ dependencies = [ "crossbeam-queue", "crossbeam-utils 0.6.5", "futures", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "log", "num_cpus", "slab", @@ -4918,7 +4914,7 @@ dependencies = [ "failure", "failure_derive", "is-match", - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", "toml", "toml-query_derive", @@ -4962,7 +4958,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6b52bf4da6512f0f07785a04769222e50d29639e7ecd016b7806fd2de306b4" dependencies = [ - "lazy_static 1.3.0", + "lazy_static 1.4.0", "regex", ] @@ -5133,9 +5129,9 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] name = "vec_map" @@ -5197,12 +5193,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" From 2fd6c4a18a475a0474c035283e2c01480cbbc6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 24 Jan 2020 00:00:00 +0000 Subject: [PATCH 0598/1253] Remove unused ignore-license directives The tidy check was removed in rust-lang/rust#53617 --- src/libstd/sys/cloudabi/abi/bitflags.rs | 3 --- src/libstd/sys/cloudabi/abi/cloudabi.rs | 1 - src/test/pretty/top-level-doc-comments.rs | 5 ----- src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c | 1 - src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c | 2 -- src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c | 1 - src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c | 1 - src/test/run-make-fulldeps/c-static-dylib/cfoo.c | 1 - src/test/run-make-fulldeps/c-static-rlib/cfoo.c | 1 - .../run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp | 1 - src/test/run-make-fulldeps/extern-fn-generic/test.c | 1 - src/test/run-make-fulldeps/extern-fn-mangle/test.c | 1 - .../run-make-fulldeps/extern-fn-with-extern-types/ctest.c | 1 - .../run-make-fulldeps/extern-fn-with-packed-struct/test.c | 1 - src/test/run-make-fulldeps/extern-fn-with-union/ctest.c | 1 - src/test/run-make-fulldeps/glibc-staticlib-args/program.c | 1 - src/test/run-make-fulldeps/interdependent-c-libraries/bar.c | 1 - src/test/run-make-fulldeps/interdependent-c-libraries/foo.c | 1 - src/test/run-make-fulldeps/issue-25581/test.c | 1 - src/test/run-make-fulldeps/link-path-order/correct.c | 1 - src/test/run-make-fulldeps/link-path-order/wrong.c | 1 - src/test/run-make-fulldeps/linkage-attr-on-static/foo.c | 1 - src/test/run-make-fulldeps/lto-smoke-c/bar.c | 1 - src/test/run-make-fulldeps/manual-link/bar.c | 1 - src/test/run-make-fulldeps/manual-link/foo.c | 1 - .../run-make-fulldeps/sanitizer-staticlib-link/program.c | 1 - src/test/ui/attr-shebang.rs | 1 - .../ui/lexer-crlf-line-endings-string-literal-doc-comment.rs | 5 +---- 28 files changed, 1 insertion(+), 38 deletions(-) diff --git a/src/libstd/sys/cloudabi/abi/bitflags.rs b/src/libstd/sys/cloudabi/abi/bitflags.rs index 306936213ed11..2383277ad7284 100644 --- a/src/libstd/sys/cloudabi/abi/bitflags.rs +++ b/src/libstd/sys/cloudabi/abi/bitflags.rs @@ -21,9 +21,6 @@ // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. -// Appease Rust's tidy. -// ignore-license - #[cfg(feature = "bitflags")] use bitflags::bitflags; diff --git a/src/libstd/sys/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs index d113a7b3d60d4..b02faf1830c53 100644 --- a/src/libstd/sys/cloudabi/abi/cloudabi.rs +++ b/src/libstd/sys/cloudabi/abi/cloudabi.rs @@ -26,7 +26,6 @@ // Source: https://github.com/NuxiNL/cloudabi // Appease Rust's tidy. -// ignore-license // ignore-tidy-linelength //! **PLEASE NOTE: This entire crate including this diff --git a/src/test/pretty/top-level-doc-comments.rs b/src/test/pretty/top-level-doc-comments.rs index 16f95d334cbcf..b97927124c30f 100644 --- a/src/test/pretty/top-level-doc-comments.rs +++ b/src/test/pretty/top-level-doc-comments.rs @@ -1,11 +1,6 @@ /// Some doc comment. struct X; -// ignore-license - -// http://rust-lang.org/COPYRIGHT. -// - // pp-exact // Test that rust can properly pretty print a doc comment if it's the first line in a file. some diff --git a/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c index a975549354123..fea490cf9b45f 100644 --- a/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c +++ b/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c @@ -1,4 +1,3 @@ -// ignore-license #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c index b2849326a7588..fea490cf9b45f 100644 --- a/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c +++ b/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c @@ -1,5 +1,3 @@ -// ignore-license - #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c index 5729d411c5bcd..bb4036b06e13b 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c +++ b/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c @@ -1,4 +1,3 @@ -// ignore-license void foo(); int main() { diff --git a/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c index 5729d411c5bcd..bb4036b06e13b 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c +++ b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c @@ -1,4 +1,3 @@ -// ignore-license void foo(); int main() { diff --git a/src/test/run-make-fulldeps/c-static-dylib/cfoo.c b/src/test/run-make-fulldeps/c-static-dylib/cfoo.c index 113717a776a99..9fe07f82f9ed1 100644 --- a/src/test/run-make-fulldeps/c-static-dylib/cfoo.c +++ b/src/test/run-make-fulldeps/c-static-dylib/cfoo.c @@ -1,2 +1 @@ -// ignore-license int foo() { return 0; } diff --git a/src/test/run-make-fulldeps/c-static-rlib/cfoo.c b/src/test/run-make-fulldeps/c-static-rlib/cfoo.c index 113717a776a99..9fe07f82f9ed1 100644 --- a/src/test/run-make-fulldeps/c-static-rlib/cfoo.c +++ b/src/test/run-make-fulldeps/c-static-rlib/cfoo.c @@ -1,2 +1 @@ -// ignore-license int foo() { return 0; } diff --git a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp index aac3ba4220101..4c2fb9cdb8782 100644 --- a/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp +++ b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp @@ -1,4 +1,3 @@ -// ignore-license extern "C" void foo() { int *a = new int(3); delete a; diff --git a/src/test/run-make-fulldeps/extern-fn-generic/test.c b/src/test/run-make-fulldeps/extern-fn-generic/test.c index f9faef64afc41..a8504ff2afb06 100644 --- a/src/test/run-make-fulldeps/extern-fn-generic/test.c +++ b/src/test/run-make-fulldeps/extern-fn-generic/test.c @@ -1,4 +1,3 @@ -// ignore-license #include typedef struct TestStruct { diff --git a/src/test/run-make-fulldeps/extern-fn-mangle/test.c b/src/test/run-make-fulldeps/extern-fn-mangle/test.c index 1a9855dedec49..e94d75083b8ff 100644 --- a/src/test/run-make-fulldeps/extern-fn-mangle/test.c +++ b/src/test/run-make-fulldeps/extern-fn-mangle/test.c @@ -1,4 +1,3 @@ -// ignore-license #include uint32_t foo(); diff --git a/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c index c3d6166fb1284..3b6fb4cfce984 100644 --- a/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c +++ b/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c @@ -1,4 +1,3 @@ -// ignore-license #include #include diff --git a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c index 4124e202c1dd0..52af3dceb109c 100644 --- a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c +++ b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c @@ -1,4 +1,3 @@ -// ignore-license // Pragma needed cause of gcc bug on windows: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 #include diff --git a/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c index 8c87c230693d1..86cb64537236e 100644 --- a/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c +++ b/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c @@ -1,4 +1,3 @@ -// ignore-license #include #include diff --git a/src/test/run-make-fulldeps/glibc-staticlib-args/program.c b/src/test/run-make-fulldeps/glibc-staticlib-args/program.c index d704c39d5c42f..30f6974b75086 100644 --- a/src/test/run-make-fulldeps/glibc-staticlib-args/program.c +++ b/src/test/run-make-fulldeps/glibc-staticlib-args/program.c @@ -1,4 +1,3 @@ -// ignore-license void args_check(); int main() { diff --git a/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c index c761f029effbe..812c975352872 100644 --- a/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c +++ b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c @@ -1,4 +1,3 @@ -// ignore-license void foo(); void bar() { foo(); } diff --git a/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c index 2895ad473bf96..85e6cd8c3909a 100644 --- a/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c +++ b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c @@ -1,2 +1 @@ -// ignore-license void foo() {} diff --git a/src/test/run-make-fulldeps/issue-25581/test.c b/src/test/run-make-fulldeps/issue-25581/test.c index 5736b1730216d..52fbf78510a88 100644 --- a/src/test/run-make-fulldeps/issue-25581/test.c +++ b/src/test/run-make-fulldeps/issue-25581/test.c @@ -1,4 +1,3 @@ -// ignore-license #include #include diff --git a/src/test/run-make-fulldeps/link-path-order/correct.c b/src/test/run-make-fulldeps/link-path-order/correct.c index a595939f92e8c..3064af952f898 100644 --- a/src/test/run-make-fulldeps/link-path-order/correct.c +++ b/src/test/run-make-fulldeps/link-path-order/correct.c @@ -1,2 +1 @@ -// ignore-license int should_return_one() { return 1; } diff --git a/src/test/run-make-fulldeps/link-path-order/wrong.c b/src/test/run-make-fulldeps/link-path-order/wrong.c index c53e7e3c48c05..64275b3ad6bb0 100644 --- a/src/test/run-make-fulldeps/link-path-order/wrong.c +++ b/src/test/run-make-fulldeps/link-path-order/wrong.c @@ -1,2 +1 @@ -// ignore-license int should_return_one() { return 0; } diff --git a/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c b/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c index d7d33ea12e806..78a6934f57f76 100644 --- a/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c +++ b/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c @@ -1,4 +1,3 @@ -// ignore-license #include extern int32_t BAZ; diff --git a/src/test/run-make-fulldeps/lto-smoke-c/bar.c b/src/test/run-make-fulldeps/lto-smoke-c/bar.c index 5729d411c5bcd..bb4036b06e13b 100644 --- a/src/test/run-make-fulldeps/lto-smoke-c/bar.c +++ b/src/test/run-make-fulldeps/lto-smoke-c/bar.c @@ -1,4 +1,3 @@ -// ignore-license void foo(); int main() { diff --git a/src/test/run-make-fulldeps/manual-link/bar.c b/src/test/run-make-fulldeps/manual-link/bar.c index 3c167b45af98d..e42599986781f 100644 --- a/src/test/run-make-fulldeps/manual-link/bar.c +++ b/src/test/run-make-fulldeps/manual-link/bar.c @@ -1,2 +1 @@ -// ignore-license void bar() {} diff --git a/src/test/run-make-fulldeps/manual-link/foo.c b/src/test/run-make-fulldeps/manual-link/foo.c index 3c167b45af98d..e42599986781f 100644 --- a/src/test/run-make-fulldeps/manual-link/foo.c +++ b/src/test/run-make-fulldeps/manual-link/foo.c @@ -1,2 +1 @@ -// ignore-license void bar() {} diff --git a/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c index a6d3bcdc5ac9d..735e2b147fd9e 100644 --- a/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c +++ b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c @@ -1,4 +1,3 @@ -// ignore-license void overflow(); int main() { diff --git a/src/test/ui/attr-shebang.rs b/src/test/ui/attr-shebang.rs index cce31c9bb7b6b..3b0dc096f58fb 100644 --- a/src/test/ui/attr-shebang.rs +++ b/src/test/ui/attr-shebang.rs @@ -3,4 +3,3 @@ #![allow(stable_features)] #![feature(rust1)] pub fn main() { } -// ignore-license diff --git a/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs index ada253aacfb90..802be7f5afb57 100644 --- a/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs +++ b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs @@ -1,11 +1,8 @@ // run-pass -// ignore-tidy-cr ignore-license +// ignore-tidy-cr // ignore-tidy-cr (repeated again because of tidy bug) // license is ignored because tidy can't handle the CRLF here properly. -// http://rust-lang.org/COPYRIGHT. -// - // N.B., this file needs CRLF line endings. The .gitattributes file in // this directory should enforce it. From 55dce720b24fde5d8489498fb5f7abd8c52c28f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 23 Jan 2020 15:21:15 -0800 Subject: [PATCH 0599/1253] Account for `ty::Error` when suggesting `impl Trait` or `Box` --- .../traits/error_reporting/suggestions.rs | 14 +- .../dyn-trait-return-should-be-impl-trait.rs | 33 ++++ ...n-trait-return-should-be-impl-trait.stderr | 152 +++++++++++++++++- 3 files changed, 191 insertions(+), 8 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 4559007ea426a..12c8de17d10f9 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -606,11 +606,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); let mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); - let (last_ty, all_returns_have_same_type) = - ret_types.clone().fold((None, true), |(last_ty, mut same), returned_ty| { - same &= last_ty.map_or(true, |ty| ty == returned_ty); - (Some(returned_ty), same) - }); + let (last_ty, all_returns_have_same_type) = ret_types.clone().fold( + (None, true), + |(last_ty, mut same): (std::option::Option>, bool), ty| { + same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error; + (Some(ty), same) + }, + ); let all_returns_conform_to_trait = if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { match ty_ret_ty.kind { @@ -625,7 +627,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) }) } - _ => true, + _ => false, } } else { true diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index b70a51dc82511..93414379fd41a 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -22,6 +22,32 @@ fn bal() -> dyn Trait { //~ ERROR E0746 } 42 } +fn bam() -> Box { + if true { + return Struct; //~ ERROR mismatched types + } + 42 //~ ERROR mismatched types +} +fn baq() -> Box { + if true { + return 0; //~ ERROR mismatched types + } + 42 //~ ERROR mismatched types +} +fn baz() -> Box { + if true { + Struct //~ ERROR mismatched types + } else { + 42 //~ ERROR mismatched types + } +} +fn baw() -> Box { + if true { + 0 //~ ERROR mismatched types + } else { + 42 //~ ERROR mismatched types + } +} // Suggest using `impl Trait` fn bat() -> dyn Trait { //~ ERROR E0746 @@ -30,5 +56,12 @@ fn bat() -> dyn Trait { //~ ERROR E0746 } 42 } +fn bay() -> dyn Trait { //~ ERROR E0746 + if true { + 0u32 + } else { + 42u32 + } +} fn main() {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 977a7ef0e0244..0df6e8f8dc77c 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -95,8 +95,136 @@ LL | } LL | Box::new(42) | +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:16 + | +LL | fn bam() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +LL | if true { +LL | return Struct; + | ^^^^^^ + | | + | expected struct `std::boxed::Box`, found struct `Struct` + | help: store this in the heap by calling `Box::new`: `Box::new(Struct)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found struct `Struct` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:5 + | +LL | fn bam() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +... +LL | 42 + | ^^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:16 + | +LL | fn baq() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +LL | if true { +LL | return 0; + | ^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(0)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:35:5 + | +LL | fn baq() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +... +LL | 42 + | ^^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:39:9 + | +LL | fn baz() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +LL | if true { +LL | Struct + | ^^^^^^ + | | + | expected struct `std::boxed::Box`, found struct `Struct` + | help: store this in the heap by calling `Box::new`: `Box::new(Struct)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found struct `Struct` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:41:9 + | +LL | fn baz() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +... +LL | 42 + | ^^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9 + | +LL | fn baw() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +LL | if true { +LL | 0 + | ^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(0)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9 + | +LL | fn baw() -> Box { + | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type +... +LL | 42 + | ^^ + | | + | expected struct `std::boxed::Box`, found integer + | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | + = note: expected struct `std::boxed::Box<(dyn Trait + 'static)>` + found type `{integer}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html + error[E0746]: return type cannot have an unboxed trait object - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time @@ -107,7 +235,27 @@ help: return `impl Trait` instead, as all return paths are of type `{integer}`, LL | fn bat() -> impl Trait { | ^^^^^^^^^^ -error: aborting due to 9 previous errors +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:59:13 + | +LL | fn bay() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on trait objects, see + = note: if all the returned values were of the same type you could use `impl Trait` as the return type + = note: for information on `impl Trait`, see + = note: you can create a new `enum` with a variant for each returned type +help: return a boxed trait object instead + | +LL | fn bay() -> Box { +LL | Box::new(if true { +LL | 0u32 +LL | } else { +LL | 42u32 +LL | }) + | + +error: aborting due to 18 previous errors Some errors have detailed explanations: E0277, E0308, E0746. For more information about an error, try `rustc --explain E0277`. From 1cbb5d849071970f7a4d19ce8f75becaac4ee0c2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 23 Jan 2020 20:29:42 -0500 Subject: [PATCH 0600/1253] Clear out std, not std tools This was a typo that slipped in, and meant that we were still not properly clearing out std. --- src/bootstrap/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 00c8e72a8f685..d9c894aa9c6b1 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -874,7 +874,7 @@ impl<'a> Builder<'a> { // // Only clear out the directory if we're compiling std; otherwise, we // should let Cargo take care of things for us (via depdep info) - if !self.config.dry_run && mode == Mode::ToolStd && cmd == "build" { + if !self.config.dry_run && mode == Mode::Std && cmd == "build" { self.clear_if_dirty(&out_dir, &self.rustc(compiler)); } From 768f6f934028d3ac261cc6ad91219f6f90de1d72 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2020 12:56:32 +0100 Subject: [PATCH 0601/1253] Clean up error codes E0223 and E0225 explanations --- src/librustc_error_codes/error_codes/E0223.md | 3 ++- src/librustc_error_codes/error_codes/E0225.md | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0223.md b/src/librustc_error_codes/error_codes/E0223.md index 9fe0360425587..0d49f514ccf4d 100644 --- a/src/librustc_error_codes/error_codes/E0223.md +++ b/src/librustc_error_codes/error_codes/E0223.md @@ -1,5 +1,6 @@ An attempt was made to retrieve an associated type, but the type was ambiguous. -For example: + +Erroneous code example: ```compile_fail,E0223 trait MyTrait {type X; } diff --git a/src/librustc_error_codes/error_codes/E0225.md b/src/librustc_error_codes/error_codes/E0225.md index b9820dc68eeeb..c306e71009715 100644 --- a/src/librustc_error_codes/error_codes/E0225.md +++ b/src/librustc_error_codes/error_codes/E0225.md @@ -1,5 +1,6 @@ -You attempted to use multiple types as bounds for a closure or trait object. -Rust does not currently support this. A simple example that causes this error: +Multiple types were used as bounds for a closure or trait object. + +Erroneous code example: ```compile_fail,E0225 fn main() { @@ -7,6 +8,8 @@ fn main() { } ``` +Rust does not currently support this. + Auto traits such as Send and Sync are an exception to this rule: It's possible to have bounds of one non-builtin trait, plus any number of auto traits. For example, the following compiles correctly: From 9a2d5e87d69cf2583db5c6dffaf82d43004a35e0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 23 Dec 2019 17:41:06 +0100 Subject: [PATCH 0602/1253] Render const pointers in MIR more compactly --- src/librustc/mir/interpret/mod.rs | 8 +++++++- src/librustc/mir/interpret/pointer.rs | 4 ++-- src/test/mir-opt/const-promotion-extern-static.rs | 4 ++-- src/test/mir-opt/const_prop/read_immutable_static.rs | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index e554b280ef78c..54e196f4b3341 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -166,9 +166,15 @@ pub enum LitToConstError { Reported, } -#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] +#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct AllocId(pub u64); +impl fmt::Debug for AllocId { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "alloc{}", self.0) + } +} + impl rustc_serialize::UseSpecializedEncodable for AllocId {} impl rustc_serialize::UseSpecializedDecodable for AllocId {} diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 9b0399e22c59c..a4974fb541b6b 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -133,13 +133,13 @@ static_assert_size!(Pointer, 16); impl fmt::Debug for Pointer { default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}.{:#x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag) + write!(f, "{:?}+{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag) } } // Specialization for no tag impl fmt::Debug for Pointer<(), Id> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}.{:#x}", self.alloc_id, self.offset.bytes()) + write!(f, "{:?}+{:x}", self.alloc_id, self.offset.bytes()) } } diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs index 3abc90e42e8ca..f6f7d0910911c 100644 --- a/src/test/mir-opt/const-promotion-extern-static.rs +++ b/src/test/mir-opt/const-promotion-extern-static.rs @@ -14,7 +14,7 @@ fn main() {} // START rustc.FOO.PromoteTemps.before.mir // bb0: { // ... -// _5 = const Scalar(AllocId(1).0x0) : &i32; +// _5 = const Scalar(alloc1+0) : &i32; // _4 = &(*_5); // _3 = [move _4]; // _2 = &_3; @@ -31,7 +31,7 @@ fn main() {} // START rustc.BAR.PromoteTemps.before.mir // bb0: { // ... -// _5 = const Scalar(AllocId(0).0x0) : &i32; +// _5 = const Scalar(alloc0+0) : &i32; // _4 = &(*_5); // _3 = [move _4]; // _2 = &_3; diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs index d9e0eb623afe1..693ef78398558 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static.rs +++ b/src/test/mir-opt/const_prop/read_immutable_static.rs @@ -10,10 +10,10 @@ fn main() { // START rustc.main.ConstProp.before.mir // bb0: { // ... -// _3 = const Scalar(AllocId(0).0x0) : &u8; +// _3 = const Scalar(alloc0+0) : &u8; // _2 = (*_3); // ... -// _5 = const Scalar(AllocId(0).0x0) : &u8; +// _5 = const Scalar(alloc0+0) : &u8; // _4 = (*_5); // _1 = Add(move _2, move _4); // ... From 50dd8eaeb9ebbccb8b79ff30d3068d0ee337cd2f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 24 Jan 2020 16:22:24 +0000 Subject: [PATCH 0603/1253] Print constants in `type_name` for const generics --- src/librustc/ty/print/pretty.rs | 38 +++++++++++++++---- .../symbol_names/legacy.rs | 2 +- .../interpret/intrinsics/type_name.rs | 5 +-- .../const-generics/const-generic-type_name.rs | 11 ++++++ .../const-generic-type_name.stderr | 8 ++++ 5 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/const-generics/const-generic-type_name.rs create mode 100644 src/test/ui/const-generics/const-generic-type_name.stderr diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 9091de55b7d8e..7dd3c8f4a7295 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -831,7 +831,11 @@ pub trait PrettyPrinter<'tcx>: Ok(self) } - fn pretty_print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { + fn pretty_print_const( + mut self, + ct: &'tcx ty::Const<'tcx>, + print_ty: bool, + ) -> Result { define_scoped_cx!(self); if self.tcx().sess.verbose() { @@ -839,6 +843,15 @@ pub trait PrettyPrinter<'tcx>: return Ok(self); } + macro_rules! print_underscore { + () => {{ + p!(write("_")); + if print_ty { + p!(write(": "), print(ct.ty)); + } + }}; + } + match (ct.val, &ct.ty.kind) { (_, ty::FnDef(did, substs)) => p!(print_value_path(*did, substs)), (ty::ConstKind::Unevaluated(did, substs, promoted), _) => { @@ -857,22 +870,27 @@ pub trait PrettyPrinter<'tcx>: { p!(write("{}", snip)) } else { - p!(write("_: "), print(ct.ty)) + print_underscore!() } } else { - p!(write("_: "), print(ct.ty)) + print_underscore!() } } } } } - (ty::ConstKind::Infer(..), _) => p!(write("_: "), print(ct.ty)), + (ty::ConstKind::Infer(..), _) => print_underscore!(), (ty::ConstKind::Param(ParamConst { name, .. }), _) => p!(write("{}", name)), - (ty::ConstKind::Value(value), _) => return self.pretty_print_const_value(value, ct.ty), + (ty::ConstKind::Value(value), _) => { + return self.pretty_print_const_value(value, ct.ty, print_ty); + } _ => { // fallback - p!(write("{:?} : ", ct.val), print(ct.ty)) + p!(write("{:?}", ct.val)); + if print_ty { + p!(write(" : "), print(ct.ty)); + } } }; Ok(self) @@ -882,6 +900,7 @@ pub trait PrettyPrinter<'tcx>: mut self, ct: ConstValue<'tcx>, ty: Ty<'tcx>, + print_ty: bool, ) -> Result { define_scoped_cx!(self); @@ -988,7 +1007,10 @@ pub trait PrettyPrinter<'tcx>: }; if !printed { // fallback - p!(write("{:?} : ", ct), print(ty)) + p!(write("{:?}", ct)); + if print_ty { + p!(write(" : "), print(ty)); + } } } }; @@ -1162,7 +1184,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { } fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result { - self.pretty_print_const(ct) + self.pretty_print_const(ct, true) } fn path_crate(mut self, cnum: CrateNum) -> Result { diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index 4f5b9ce03fc3f..0dedda9bb6b73 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -237,7 +237,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { // only print integers if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { .. })) = ct.val { if ct.ty.is_integral() { - return self.pretty_print_const(ct); + return self.pretty_print_const(ct, true); } } self.write_str("_")?; diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index eed47c147c60d..cd8bf7085d1b1 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -69,9 +69,8 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { } } - fn print_const(self, _: &'tcx ty::Const<'tcx>) -> Result { - // don't print constants to the user - Ok(self) + fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result { + self.pretty_print_const(ct, false) } fn print_dyn_existential( diff --git a/src/test/ui/const-generics/const-generic-type_name.rs b/src/test/ui/const-generics/const-generic-type_name.rs new file mode 100644 index 0000000000000..28586426b44e9 --- /dev/null +++ b/src/test/ui/const-generics/const-generic-type_name.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +#[derive(Debug)] +struct S; + +fn main() { + assert_eq!(std::any::type_name::>(), "const_generic_type_name::S<3usize>"); +} diff --git a/src/test/ui/const-generics/const-generic-type_name.stderr b/src/test/ui/const-generics/const-generic-type_name.stderr new file mode 100644 index 0000000000000..6b60a77effea5 --- /dev/null +++ b/src/test/ui/const-generics/const-generic-type_name.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-generic-type_name.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From f4f96e294335de13bc7341c626837affdb2e4a45 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 22 Jan 2020 01:41:44 +0000 Subject: [PATCH 0604/1253] Normalise diagnostics with respect to "the X is declared/defined here" --- src/librustc_metadata/creader.rs | 2 +- src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs | 2 +- src/librustc_mir/borrow_check/diagnostics/region_errors.rs | 2 +- src/test/ui/allocator/two-allocators.stderr | 2 +- src/test/ui/borrowck/issue-45983.nll.stderr | 2 +- src/test/ui/generator/ref-escapes-but-not-over-yield.stderr | 2 +- ...approximated-shorter-to-static-comparing-against-free.stderr | 2 +- src/test/ui/nll/outlives-suggestion-simple.stderr | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 351e72d4678f2..4c4383aa603cb 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -694,7 +694,7 @@ impl<'a> CrateLoader<'a> { self.sess .struct_span_err(*span2, "cannot define multiple global allocators") .span_label(*span2, "cannot define a new global allocator") - .span_label(*span1, "previous global allocator is defined here") + .span_label(*span1, "previous global allocator defined here") .emit(); true } diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 08333ae423da7..89fe1883e629b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1259,7 +1259,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label( upvar_span, - format!("`{}` is declared here, outside of the {} body", upvar_name, escapes_from), + format!("`{}` declared here, outside of the {} body", upvar_name, escapes_from), ); err.span_label(borrow_span, format!("borrow is only valid in the {} body", escapes_from)); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index b999dfa303103..0e040ec7827e1 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -457,7 +457,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { diag.span_label( outlived_fr_span, format!( - "`{}` is declared here, outside of the {} body", + "`{}` declared here, outside of the {} body", outlived_fr_name, escapes_from ), ); diff --git a/src/test/ui/allocator/two-allocators.stderr b/src/test/ui/allocator/two-allocators.stderr index 35d9f0f42f001..da636a5a567f3 100644 --- a/src/test/ui/allocator/two-allocators.stderr +++ b/src/test/ui/allocator/two-allocators.stderr @@ -2,7 +2,7 @@ error: cannot define multiple global allocators --> $DIR/two-allocators.rs:6:1 | LL | static A: System = System; - | -------------------------- previous global allocator is defined here + | -------------------------- previous global allocator defined here LL | #[global_allocator] LL | static B: System = System; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr index 49d6c2473f6a3..51bb4dee6762a 100644 --- a/src/test/ui/borrowck/issue-45983.nll.stderr +++ b/src/test/ui/borrowck/issue-45983.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/issue-45983.rs:20:18 | LL | let x = None; - | - `x` is declared here, outside of the closure body + | - `x` declared here, outside of the closure body LL | give_any(|y| x = Some(y)); | - ^^^^^^^^^^^ `y` escapes the closure body here | | diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr index de533e4d5ff7b..9986220218e28 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of generator --> $DIR/ref-escapes-but-not-over-yield.rs:11:9 | LL | let mut a = &3; - | ----- `a` is declared here, outside of the generator body + | ----- `a` declared here, outside of the generator body ... LL | a = &b; | ^^^^-- diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 708e50de570db..f5723ba5da5ba 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -19,7 +19,7 @@ error[E0521]: borrowed data escapes outside of closure LL | foo(cell, |cell_a, cell_x| { | ------ ------ `cell_x` is a reference that is only valid in the closure body | | - | `cell_a` is declared here, outside of the closure body + | `cell_a` declared here, outside of the closure body LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure | ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here diff --git a/src/test/ui/nll/outlives-suggestion-simple.stderr b/src/test/ui/nll/outlives-suggestion-simple.stderr index f7603e29d488c..db7f57ceccf13 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.stderr +++ b/src/test/ui/nll/outlives-suggestion-simple.stderr @@ -99,7 +99,7 @@ error[E0521]: borrowed data escapes outside of function LL | fn get_bar(&self) -> Bar2 { | ----- | | - | `self` is declared here, outside of the function body + | `self` declared here, outside of the function body | `self` is a reference that is only valid in the function body LL | Bar2::new(&self) | ^^^^^^^^^^^^^^^^ `self` escapes the function body here From 24a2929ed1d3e1760bf89c878352448fb5ee2087 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 22 Jan 2020 23:57:38 +0000 Subject: [PATCH 0605/1253] Normalise notes with the/is --- src/librustc/lint.rs | 2 +- src/librustc/middle/lang_items.rs | 6 +++--- src/librustc_lint/types.rs | 2 +- .../transform/check_consts/validation.rs | 2 +- src/librustc_passes/diagnostic_items.rs | 4 ++-- src/librustc_typeck/astconv.rs | 2 +- .../deny-intra-link-resolution-failure.stderr | 2 +- src/test/rustdoc-ui/deny-missing-docs-crate.stderr | 2 +- src/test/rustdoc-ui/deny-missing-docs-macro.stderr | 2 +- src/test/rustdoc-ui/doc-without-codeblock.stderr | 2 +- src/test/rustdoc-ui/intra-doc-alias-ice.stderr | 2 +- src/test/rustdoc-ui/intra-link-span-ice-55723.stderr | 2 +- src/test/rustdoc-ui/intra-links-ambiguity.stderr | 2 +- src/test/rustdoc-ui/intra-links-anchors.stderr | 2 +- src/test/rustdoc-ui/lint-group.stderr | 6 +++--- .../rustdoc-ui/lint-missing-doc-code-example.stderr | 2 +- src/test/rustdoc-ui/private-item-doc-test.stderr | 2 +- .../internal-lints/default_hash_types.stderr | 2 +- .../lint_pass_impl_without_macro.stderr | 2 +- .../ui-fulldeps/internal-lints/pass_ty_by_ref.stderr | 2 +- .../internal-lints/qualified_ty_ty_ctxt.stderr | 2 +- .../internal-lints/ty_tykind_usage.stderr | 2 +- src/test/ui-fulldeps/lint-plugin-deny-attr.stderr | 2 +- src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr | 2 +- src/test/ui-fulldeps/lint-tool-test.stderr | 4 ++-- src/test/ui/anon-params-deprecated.stderr | 2 +- .../associated-const-dead-code.stderr | 2 +- .../2015-edition-error-various-positions.stderr | 2 +- .../await-keyword/2015-edition-warning.stderr | 2 +- src/test/ui/async-await/unreachable-lint-1.stderr | 2 +- src/test/ui/async-await/unused-lifetime.stderr | 2 +- .../ui/attributes/register-attr-tool-unused.stderr | 2 +- src/test/ui/bad/bad-lint-cap2.stderr | 2 +- src/test/ui/bad/bad-lint-cap3.stderr | 2 +- ...on-sharing-interference-future-compat-lint.stderr | 4 ++-- src/test/ui/cast-char.stderr | 2 +- .../cfg-attr-empty-is-unused.stderr | 2 +- .../cfg-attr-multi-true.stderr | 2 +- .../const-parameter-uppercase-lint.stderr | 2 +- src/test/ui/consts/array-literal-index-oob.stderr | 2 +- src/test/ui/consts/assoc_const_generic_impl.stderr | 2 +- src/test/ui/consts/const-err-early.stderr | 2 +- src/test/ui/consts/const-err-multi.stderr | 2 +- src/test/ui/consts/const-err.stderr | 2 +- src/test/ui/consts/const-err2.stderr | 2 +- src/test/ui/consts/const-err3.stderr | 2 +- .../const-eval/conditional_array_execution.stderr | 2 +- .../ui/consts/const-eval/const-eval-overflow2.stderr | 2 +- .../consts/const-eval/const-eval-overflow2b.stderr | 2 +- .../consts/const-eval/const-eval-overflow2c.stderr | 2 +- .../const-eval/index-out-of-bounds-never-type.stderr | 2 +- src/test/ui/consts/const-eval/issue-43197.stderr | 2 +- .../consts/const-eval/panic-assoc-never-type.stderr | 2 +- .../ui/consts/const-eval/panic-never-type.stderr | 2 +- src/test/ui/consts/const-eval/promoted_errors.stderr | 2 +- .../ui/consts/const-eval/promoted_errors2.stderr | 2 +- src/test/ui/consts/const-eval/pub_const_err.stderr | 2 +- .../ui/consts/const-eval/pub_const_err_bin.stderr | 2 +- src/test/ui/consts/const-eval/ub-nonnull.stderr | 2 +- .../const-eval/validate_uninhabited_zsts.stderr | 2 +- .../miri_unleashed/const_refers_to_static.stderr | 2 +- .../ui/consts/miri_unleashed/mutable_const.stderr | 2 +- .../ui/consts/miri_unleashed/non_const_fn.stderr | 2 +- src/test/ui/deprecation/deprecation-lint-2.stderr | 2 +- src/test/ui/deprecation/deprecation-lint-3.stderr | 2 +- .../ui/deprecation/deprecation-lint-nested.stderr | 2 +- src/test/ui/deprecation/deprecation-lint.stderr | 2 +- .../deprecation/rustc_deprecation-in-future.stderr | 2 +- src/test/ui/deprecation/suggestion.stderr | 2 +- .../ui/derives/deriving-meta-empty-trait-list.stderr | 2 +- src/test/ui/derives/deriving-with-repr-packed.stderr | 2 +- src/test/ui/duplicate_entry_error.stderr | 2 +- .../dyn-2015-edition-keyword-ident-lint.stderr | 2 +- .../ui/editions/edition-extern-crate-allowed.stderr | 2 +- .../editions/edition-raw-pointer-method-2015.stderr | 2 +- src/test/ui/enable-unstable-lib-feature.stderr | 2 +- src/test/ui/enum/enum-discrim-too-small2.stderr | 2 +- src/test/ui/enum/enum-size-variance.stderr | 2 +- src/test/ui/error-codes/E0001.stderr | 2 +- src/test/ui/error-codes/E0152.stderr | 2 +- src/test/ui/expr_attr_paren_order.stderr | 2 +- src/test/ui/extern-flag/public-and-private.stderr | 2 +- .../issue-43106-gating-of-builtin-attrs.stderr | 4 ++-- .../feature-gates/feature-gate-feature-gate.stderr | 2 +- .../ui/feature-gates/feature-gate-no-debug-2.stderr | 2 +- src/test/ui/fn_must_use.stderr | 2 +- src/test/ui/future-incompatible-lint-group.stderr | 2 +- src/test/ui/generic/generic-no-mangle.stderr | 2 +- src/test/ui/imports/extern-crate-used.stderr | 2 +- src/test/ui/imports/reexports.stderr | 2 +- src/test/ui/imports/unresolved-imports-used.stderr | 2 +- src/test/ui/imports/unused-macro-use.stderr | 2 +- src/test/ui/imports/unused.stderr | 2 +- src/test/ui/in-band-lifetimes/elided-lifetimes.fixed | 2 +- src/test/ui/in-band-lifetimes/elided-lifetimes.rs | 2 +- .../ui/in-band-lifetimes/elided-lifetimes.stderr | 2 +- src/test/ui/invalid/invalid-plugin-attr.stderr | 2 +- src/test/ui/issues/issue-10656.stderr | 2 +- src/test/ui/issues/issue-12116.stderr | 2 +- src/test/ui/issues/issue-12369.stderr | 2 +- src/test/ui/issues/issue-13727.stderr | 2 +- src/test/ui/issues/issue-14221.stderr | 2 +- src/test/ui/issues/issue-14309.stderr | 12 ++++++------ src/test/ui/issues/issue-16250.stderr | 4 ++-- src/test/ui/issues/issue-17337.stderr | 2 +- src/test/ui/issues/issue-17718-const-naming.stderr | 4 ++-- src/test/ui/issues/issue-17999.stderr | 2 +- src/test/ui/issues/issue-2150.stderr | 2 +- src/test/ui/issues/issue-22599.stderr | 2 +- src/test/ui/issues/issue-27060.stderr | 2 +- src/test/ui/issues/issue-30240-b.stderr | 2 +- src/test/ui/issues/issue-30302.stderr | 2 +- src/test/ui/issues/issue-30730.stderr | 2 +- src/test/ui/issues/issue-31221.stderr | 2 +- .../ui/issues/issue-33140-traitobject-crate.stderr | 2 +- src/test/ui/issues/issue-37515.stderr | 2 +- src/test/ui/issues/issue-41255.stderr | 2 +- .../issue-45107-unnecessary-unsafe-in-closure.stderr | 2 +- src/test/ui/issues/issue-46576.stderr | 2 +- src/test/ui/issues/issue-48131.stderr | 2 +- src/test/ui/issues/issue-49934.rs | 2 +- src/test/ui/issues/issue-49934.stderr | 2 +- src/test/ui/issues/issue-50781.stderr | 2 +- src/test/ui/issues/issue-55511.stderr | 2 +- src/test/ui/issues/issue-56685.stderr | 2 +- src/test/ui/issues/issue-57472.stderr | 2 +- src/test/ui/issues/issue-59896.stderr | 2 +- src/test/ui/issues/issue-60622.stderr | 2 +- src/test/ui/issues/issue-6804.stderr | 2 +- src/test/ui/issues/issue-7246.stderr | 2 +- src/test/ui/issues/issue-8460-const.stderr | 2 +- src/test/ui/issues/issue-8460-const2.stderr | 2 +- src/test/ui/lint/dead-code/basic.stderr | 2 +- src/test/ui/lint/dead-code/empty-unused-enum.stderr | 2 +- src/test/ui/lint/dead-code/impl-trait.stderr | 2 +- src/test/ui/lint/dead-code/lint-dead-code-1.stderr | 2 +- src/test/ui/lint/dead-code/lint-dead-code-2.stderr | 2 +- src/test/ui/lint/dead-code/lint-dead-code-3.stderr | 2 +- src/test/ui/lint/dead-code/lint-dead-code-4.stderr | 2 +- src/test/ui/lint/dead-code/lint-dead-code-5.stderr | 2 +- src/test/ui/lint/dead-code/newline-span.stderr | 2 +- src/test/ui/lint/dead-code/type-alias.stderr | 2 +- src/test/ui/lint/dead-code/unused-enum.stderr | 2 +- .../ui/lint/dead-code/unused-struct-variant.stderr | 2 +- src/test/ui/lint/dead-code/unused-variant.stderr | 2 +- src/test/ui/lint/dead-code/with-core-crate.stderr | 2 +- .../ui/lint/inclusive-range-pattern-syntax.stderr | 2 +- .../ui/lint/inline-trait-and-foreign-items.stderr | 2 +- ...ue-47390-unused-variable-in-struct-pattern.stderr | 6 +++--- src/test/ui/lint/issue-54180-unused-ref-field.stderr | 2 +- .../ui/lint/issue-54538-unused-parens-lint.stderr | 2 +- ...66362-no-snake-case-warning-for-field-puns.stderr | 2 +- src/test/ui/lint/lint-attr-non-item-node.stderr | 2 +- src/test/ui/lint/lint-change-warnings.stderr | 4 ++-- src/test/ui/lint/lint-ctypes-enum.stderr | 8 ++++---- src/test/ui/lint/lint-ctypes.stderr | 10 +++++----- .../lint-directives-on-use-items-issue-10534.stderr | 4 ++-- src/test/ui/lint/lint-exceeding-bitshifts.stderr | 2 +- src/test/ui/lint/lint-exceeding-bitshifts2.stderr | 2 +- src/test/ui/lint/lint-forbid-internal-unsafe.stderr | 2 +- src/test/ui/lint/lint-group-nonstandard-style.stderr | 10 +++++----- src/test/ui/lint/lint-impl-fn.stderr | 6 +++--- .../lint/lint-lowercase-static-const-pattern.stderr | 2 +- src/test/ui/lint/lint-match-arms.rs | 2 +- src/test/ui/lint/lint-match-arms.stderr | 2 +- src/test/ui/lint/lint-misplaced-attr.stderr | 2 +- .../ui/lint/lint-missing-copy-implementations.stderr | 2 +- src/test/ui/lint/lint-missing-doc.stderr | 2 +- src/test/ui/lint/lint-non-camel-case-types.stderr | 2 +- src/test/ui/lint/lint-non-snake-case-crate-2.stderr | 2 +- src/test/ui/lint/lint-non-snake-case-crate.stderr | 2 +- .../ui/lint/lint-non-snake-case-functions.stderr | 2 +- .../ui/lint/lint-non-snake-case-lifetimes.stderr | 2 +- src/test/ui/lint/lint-non-snake-case-modules.stderr | 2 +- .../lint/lint-non-uppercase-associated-const.stderr | 2 +- src/test/ui/lint/lint-non-uppercase-statics.stderr | 2 +- src/test/ui/lint/lint-owned-heap-memory.stderr | 2 +- src/test/ui/lint/lint-qualification.stderr | 2 +- src/test/ui/lint/lint-range-endpoint-overflow.stderr | 2 +- src/test/ui/lint/lint-removed-allow.stderr | 2 +- src/test/ui/lint/lint-removed-cmdline.stderr | 2 +- src/test/ui/lint/lint-removed.stderr | 2 +- src/test/ui/lint/lint-renamed-allow.stderr | 2 +- src/test/ui/lint/lint-renamed-cmdline.stderr | 2 +- src/test/ui/lint/lint-renamed.stderr | 2 +- src/test/ui/lint/lint-shorthand-field.stderr | 2 +- src/test/ui/lint/lint-stability-deprecated.stderr | 2 +- .../ui/lint/lint-stability-fields-deprecated.stderr | 2 +- src/test/ui/lint/lint-stability2.stderr | 2 +- src/test/ui/lint/lint-stability3.stderr | 2 +- src/test/ui/lint/lint-type-limits2.stderr | 2 +- src/test/ui/lint/lint-type-limits3.stderr | 2 +- src/test/ui/lint/lint-type-overflow.stderr | 2 +- src/test/ui/lint/lint-type-overflow2.stderr | 2 +- src/test/ui/lint/lint-unconditional-recursion.stderr | 2 +- src/test/ui/lint/lint-unknown-lint.stderr | 2 +- .../ui/lint/lint-unnecessary-import-braces.stderr | 2 +- src/test/ui/lint/lint-unnecessary-parens.stderr | 2 +- src/test/ui/lint/lint-unsafe-code.stderr | 2 +- src/test/ui/lint/lint-unused-extern-crate.stderr | 2 +- src/test/ui/lint/lint-unused-imports.stderr | 2 +- src/test/ui/lint/lint-unused-mut-self.stderr | 2 +- src/test/ui/lint/lint-unused-mut-variables.stderr | 4 ++-- src/test/ui/lint/lint-unused-variables.stderr | 2 +- src/test/ui/lint/lint-uppercase-variables.stderr | 4 ++-- src/test/ui/lint/lints-in-foreign-macros.stderr | 4 ++-- src/test/ui/lint/must-use-ops.stderr | 2 +- src/test/ui/lint/must_use-array.stderr | 2 +- src/test/ui/lint/must_use-trait.stderr | 2 +- src/test/ui/lint/must_use-tuple.stderr | 2 +- src/test/ui/lint/must_use-unit.stderr | 2 +- src/test/ui/lint/opaque-ty-ffi-unsafe.stderr | 2 +- src/test/ui/lint/reasons.rs | 4 ++-- src/test/ui/lint/reasons.stderr | 4 ++-- .../redundant-semi-proc-macro.stderr | 2 +- .../lint-non-ascii-idents.stderr | 2 +- .../lint-uncommon-codepoints.stderr | 2 +- src/test/ui/lint/suggestions.stderr | 4 ++-- .../trivial-casts-featuring-type-ascription.stderr | 4 ++-- src/test/ui/lint/trivial-casts.stderr | 4 ++-- src/test/ui/lint/type-overflow.stderr | 2 +- src/test/ui/lint/uninitialized-zeroed.stderr | 2 +- src/test/ui/lint/unreachable_pub-pub_crate.stderr | 2 +- src/test/ui/lint/unreachable_pub.stderr | 2 +- .../ui/lint/unused_import_warning_issue_45268.stderr | 2 +- src/test/ui/lint/unused_labels.stderr | 2 +- .../ui/lint/unused_parens_json_suggestion.stderr | 2 +- .../lint/unused_parens_remove_json_suggestion.stderr | 2 +- src/test/ui/lint/use-redundant.stderr | 2 +- .../lint/warn-unused-inline-on-fn-prototypes.stderr | 2 +- src/test/ui/liveness/liveness-dead.stderr | 2 +- src/test/ui/liveness/liveness-unused.stderr | 6 +++--- .../ui/macros/issue-61053-different-kleene.stderr | 2 +- .../ui/macros/issue-61053-duplicate-binder.stderr | 2 +- .../ui/macros/issue-61053-missing-repetition.stderr | 2 +- src/test/ui/macros/issue-61053-unbound.stderr | 2 +- src/test/ui/macros/macro-use-all-and-none.stderr | 2 +- .../ui/match/match-no-arms-unreachable-after.stderr | 2 +- .../method-call-lifetime-args-lint-fail.stderr | 2 +- .../ui/methods/method-call-lifetime-args-lint.stderr | 2 +- src/test/ui/missing_debug_impls.stderr | 2 +- src/test/ui/never_type/never-assign-dead-code.stderr | 4 ++-- src/test/ui/nll/capture-mut-ref.stderr | 2 +- src/test/ui/nll/issue-61424.stderr | 2 +- src/test/ui/nll/unused-mut-issue-50343.stderr | 2 +- src/test/ui/no-patterns-in-args-2.stderr | 2 +- .../exhaustiveness-unreachable-pattern.stderr | 2 +- .../ui/panic-handler/panic-handler-duplicate.stderr | 2 +- src/test/ui/panic-handler/panic-handler-std.stderr | 2 +- src/test/ui/parser/recover-range-pats.stderr | 2 +- src/test/ui/path-lookahead.stderr | 2 +- .../ui/pattern/deny-irrefutable-let-patterns.stderr | 2 +- .../usefulness/exhaustive_integer_patterns.stderr | 4 ++-- src/test/ui/pattern/usefulness/issue-43253.stderr | 4 ++-- .../ui/pattern/usefulness/match-arm-statics.stderr | 2 +- .../usefulness/match-byte-array-patterns.stderr | 2 +- .../match-empty-exhaustive_patterns.stderr | 2 +- .../usefulness/match-range-fail-dominate.stderr | 2 +- src/test/ui/pattern/usefulness/match-ref-ice.stderr | 2 +- .../ui/pattern/usefulness/match-vec-fixed.stderr | 2 +- .../pattern/usefulness/match-vec-unreachable.stderr | 2 +- .../pattern/usefulness/slice-pattern-const-2.stderr | 2 +- .../pattern/usefulness/slice-pattern-const-3.stderr | 2 +- .../ui/pattern/usefulness/slice-pattern-const.stderr | 2 +- .../usefulness/slice-patterns-reachability.stderr | 2 +- .../usefulness/struct-pattern-match-useless.stderr | 2 +- .../pattern/usefulness/top-level-alternation.stderr | 2 +- .../privacy/private-in-public-non-principal.stderr | 2 +- src/test/ui/privacy/private-in-public-warn.stderr | 2 +- src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr | 2 +- src/test/ui/proc-macro/attributes-included.stderr | 2 +- src/test/ui/proc-macro/no-macro-use-attr.stderr | 2 +- .../range/range-inclusive-pattern-precedence.stderr | 2 +- src/test/ui/reachable/expr_add.stderr | 2 +- src/test/ui/reachable/expr_again.stderr | 2 +- src/test/ui/reachable/expr_array.stderr | 2 +- src/test/ui/reachable/expr_assign.stderr | 2 +- src/test/ui/reachable/expr_block.stderr | 2 +- src/test/ui/reachable/expr_box.stderr | 2 +- src/test/ui/reachable/expr_call.stderr | 2 +- src/test/ui/reachable/expr_cast.stderr | 2 +- src/test/ui/reachable/expr_if.stderr | 2 +- src/test/ui/reachable/expr_loop.stderr | 2 +- src/test/ui/reachable/expr_match.stderr | 2 +- src/test/ui/reachable/expr_method.stderr | 2 +- src/test/ui/reachable/expr_repeat.stderr | 2 +- src/test/ui/reachable/expr_return.stderr | 2 +- src/test/ui/reachable/expr_return_in_macro.stderr | 2 +- src/test/ui/reachable/expr_struct.stderr | 2 +- src/test/ui/reachable/expr_tup.stderr | 2 +- src/test/ui/reachable/expr_type.stderr | 2 +- src/test/ui/reachable/expr_unary.stderr | 2 +- src/test/ui/reachable/expr_while.stderr | 2 +- src/test/ui/reachable/unreachable-arm.stderr | 2 +- src/test/ui/reachable/unreachable-code.stderr | 2 +- src/test/ui/reachable/unreachable-in-call.stderr | 2 +- .../ui/reachable/unreachable-loop-patterns.stderr | 2 +- src/test/ui/reachable/unreachable-try-pattern.stderr | 4 ++-- src/test/ui/reachable/unwarned-match-on-never.stderr | 2 +- src/test/ui/removing-extern-crate.stderr | 2 +- .../improper_ctypes/extern_crate_improper.stderr | 2 +- .../issue-65157-repeated-match-arm.stderr | 2 +- .../uninhabited/patterns_same_crate.stderr | 2 +- .../ui/rfc-2565-param-attrs/param-attrs-cfg.stderr | 2 +- .../cant-hide-behind-doubly-indirect-embedded.stderr | 2 +- .../cant-hide-behind-doubly-indirect-param.stderr | 2 +- .../cant-hide-behind-indirect-struct-embedded.stderr | 2 +- .../cant-hide-behind-indirect-struct-param.stderr | 2 +- ...e-62307-match-ref-ref-forbidden-without-eq.stderr | 2 +- src/test/ui/rust-2018/async-ident-allowed.stderr | 2 +- src/test/ui/rust-2018/async-ident.stderr | 2 +- src/test/ui/rust-2018/dyn-keyword.stderr | 2 +- .../edition-lint-fully-qualified-paths.stderr | 2 +- .../edition-lint-infer-outlives-multispan.stderr | 2 +- .../ui/rust-2018/edition-lint-infer-outlives.stderr | 2 +- .../rust-2018/edition-lint-nested-empty-paths.stderr | 2 +- .../ui/rust-2018/edition-lint-nested-paths.stderr | 2 +- src/test/ui/rust-2018/edition-lint-paths.stderr | 2 +- .../rust-2018/extern-crate-idiomatic-in-2018.stderr | 2 +- src/test/ui/rust-2018/extern-crate-rename.stderr | 2 +- src/test/ui/rust-2018/extern-crate-submod.stderr | 2 +- .../issue-54400-unused-extern-crate-attr-span.stderr | 2 +- .../ui/rust-2018/macro-use-warned-against.stderr | 4 ++-- src/test/ui/rust-2018/remove-extern-crate.stderr | 2 +- .../suggestions-not-always-applicable.stderr | 2 +- src/test/ui/rust-2018/try-ident.stderr | 2 +- src/test/ui/rust-2018/try-macro.stderr | 2 +- src/test/ui/single-use-lifetime/fn-types.stderr | 2 +- .../one-use-in-fn-argument-in-band.stderr | 2 +- .../one-use-in-fn-argument.stderr | 2 +- .../one-use-in-inherent-impl-header.stderr | 2 +- .../one-use-in-inherent-method-argument.stderr | 2 +- .../one-use-in-inherent-method-return.stderr | 2 +- .../one-use-in-trait-method-argument.stderr | 2 +- ...ses-in-inherent-method-argument-and-return.stderr | 2 +- .../ui/single-use-lifetime/zero-uses-in-fn.stderr | 2 +- .../ui/single-use-lifetime/zero-uses-in-impl.stderr | 2 +- src/test/ui/span/issue-24690.stderr | 2 +- src/test/ui/span/lint-unused-unsafe.stderr | 2 +- src/test/ui/span/macro-span-replacement.stderr | 2 +- src/test/ui/span/multispan-import-lint.stderr | 2 +- .../span/unused-warning-point-at-identifier.stderr | 2 +- src/test/ui/stable-features.stderr | 2 +- src/test/ui/suggestions/issue-61963.stderr | 2 +- .../ui/suggestions/unused-closure-argument.stderr | 2 +- src/test/ui/test-attrs/test-warns-dead-code.stderr | 2 +- src/test/ui/tool_lints-fail.stderr | 2 +- .../ui/trivial-bounds/trivial-bounds-lint.stderr | 2 +- src/test/ui/trivial_casts.stderr | 4 ++-- .../try-block/try-block-unreachable-code-lint.stderr | 2 +- ...t-priority-lint-ambiguous_associated_items.stderr | 4 ++-- src/test/ui/underscore-imports/basic.stderr | 2 +- src/test/ui/underscore-imports/unused-2018.stderr | 2 +- src/test/ui/uninhabited/uninhabited-patterns.stderr | 2 +- src/test/ui/union/union-fields-1.stderr | 2 +- src/test/ui/union/union-lint-dead-code.stderr | 2 +- src/test/ui/union/union-repr-c.stderr | 4 ++-- src/test/ui/unnecessary-extern-crate.stderr | 2 +- src/test/ui/unreachable-code-ret.stderr | 2 +- .../unsafe-around-compiler-generated-unsafe.stderr | 2 +- src/test/ui/unused/unused-attr.stderr | 2 +- src/test/ui/unused/unused-macro-rules.stderr | 4 ++-- src/test/ui/unused/unused-macro.stderr | 4 ++-- .../ui/unused/unused-mut-warning-captured-var.stderr | 2 +- src/test/ui/unused/unused-result.rs | 4 ++-- src/test/ui/unused/unused-result.stderr | 4 ++-- .../ui/use/use-nested-groups-unused-imports.stderr | 2 +- src/test/ui/useless-comment.stderr | 2 +- src/test/ui/variants/variant-size-differences.stderr | 2 +- 369 files changed, 423 insertions(+), 423 deletions(-) diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs index 2ed6cd5283b10..8c18b1368a9d8 100644 --- a/src/librustc/lint.rs +++ b/src/librustc/lint.rs @@ -259,7 +259,7 @@ pub fn struct_lint_level<'a>( &mut err, DiagnosticMessageId::from(lint), src, - "lint level defined here", + "the lint level is defined here", ); if lint_attr_name.as_str() != name { let level_str = level.as_str(); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 27b769742a9fc..9e33ee8da2152 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -204,17 +204,17 @@ impl LanguageItemCollector<'tcx> { }, }; if let Some(span) = self.tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here"); + err.span_note(span, "the lang item is first defined here"); } else { match self.tcx.extern_crate(original_def_id) { Some(ExternCrate {dependency_of, ..}) => { err.note(&format!( - "first defined in crate `{}` (which `{}` depends on)", + "the lang item is first defined in crate `{}` (which `{}` depends on)", self.tcx.crate_name(original_def_id.krate), self.tcx.crate_name(*dependency_of))); }, _ => { - err.note(&format!("first defined in crate `{}`.", + err.note(&format!("the lang item is first defined in crate `{}`.", self.tcx.crate_name(original_def_id.krate))); } } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 674a82b61961c..d96ba59d9a353 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -894,7 +894,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { diag.note(note); if let ty::Adt(def, _) = ty.kind { if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) { - diag.span_note(sp, "type defined here"); + diag.span_note(sp, "the type is defined here"); } } diag.emit(); diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 44b2a90053a38..f23b180eb8c81 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -625,7 +625,7 @@ fn check_short_circuiting_in_const_local(item: &Item<'_, 'tcx>) { } for local in locals { let span = body.local_decls[local].source_info.span; - error.span_note(span, "more locals defined here"); + error.span_note(span, "more locals are defined here"); } error.emit(); } diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs index 8d220a3f695f2..5e831b558a350 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/src/librustc_passes/diagnostic_items.rs @@ -73,10 +73,10 @@ fn collect_item( )), }; if let Some(span) = tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here"); + err.span_note(span, "the diagnostic item is first defined here"); } else { err.note(&format!( - "first defined in crate `{}`.", + "the diagnostic item is first defined in crate `{}`.", tcx.crate_name(original_def_id.krate) )); } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 89eeed8d11ebc..c2123876b679b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2220,7 +2220,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut could_refer_to = |kind: DefKind, def_id, also| { let note_msg = format!( - "`{}` could{} refer to {} defined here", + "`{}` could{} refer to the {} defined here", assoc_ident, also, kind.descr(def_id) diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index b432bfbf20f5d..bc21cfd47c5d1 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -4,7 +4,7 @@ error: `[v2]` cannot be resolved, ignoring it. LL | /// [v2] | ^^ cannot be resolved, ignoring | -note: lint level defined here +note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 | LL | #![deny(intra_doc_link_resolution_failure)] diff --git a/src/test/rustdoc-ui/deny-missing-docs-crate.stderr b/src/test/rustdoc-ui/deny-missing-docs-crate.stderr index 9cd50d26766ea..f0a13b70b977f 100644 --- a/src/test/rustdoc-ui/deny-missing-docs-crate.stderr +++ b/src/test/rustdoc-ui/deny-missing-docs-crate.stderr @@ -6,7 +6,7 @@ LL | | LL | | pub struct Foo; | |_______________^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deny-missing-docs-crate.rs:1:9 | LL | #![deny(missing_docs)] diff --git a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr index ef15bf05d54ef..a564006e74f48 100644 --- a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr +++ b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr @@ -4,7 +4,7 @@ error: missing documentation for macro LL | macro_rules! foo { | ^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deny-missing-docs-macro.rs:3:9 | LL | #![deny(missing_docs)] diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr index bf65fcf19a0d6..f2b2328322a7b 100644 --- a/src/test/rustdoc-ui/doc-without-codeblock.stderr +++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr @@ -10,7 +10,7 @@ LL | | pub fn bar() {} LL | | } | |_^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/doc-without-codeblock.rs:1:9 | LL | #![deny(missing_doc_code_examples)] diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr index d4d3e5fea3e1a..cf26675163054 100644 --- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr @@ -4,7 +4,7 @@ error: `[TypeAlias::hoge]` cannot be resolved, ignoring it. LL | /// [broken cross-reference](TypeAlias::hoge) | ^^^^^^^^^^^^^^^ cannot be resolved, ignoring | -note: lint level defined here +note: the lint level is defined here --> $DIR/intra-doc-alias-ice.rs:1:9 | LL | #![deny(intra_doc_link_resolution_failure)] diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index edd5b8b92f230..ce31eb3a8a378 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -4,7 +4,7 @@ error: `[i]` cannot be resolved, ignoring it. LL | /// (arr[i]) | ^ cannot be resolved, ignoring | -note: lint level defined here +note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 | LL | #![deny(intra_doc_link_resolution_failure)] diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.stderr b/src/test/rustdoc-ui/intra-links-ambiguity.stderr index 9ee3ff57fb5f0..7b9821b3d047a 100644 --- a/src/test/rustdoc-ui/intra-links-ambiguity.stderr +++ b/src/test/rustdoc-ui/intra-links-ambiguity.stderr @@ -4,7 +4,7 @@ error: `ambiguous` is both a struct and a function LL | /// [`ambiguous`] is ambiguous. | ^^^^^^^^^^^ ambiguous link | -note: lint level defined here +note: the lint level is defined here --> $DIR/intra-links-ambiguity.rs:1:9 | LL | #![deny(intra_doc_link_resolution_failure)] diff --git a/src/test/rustdoc-ui/intra-links-anchors.stderr b/src/test/rustdoc-ui/intra-links-anchors.stderr index 5fead8e4c358e..11dee5547db4f 100644 --- a/src/test/rustdoc-ui/intra-links-anchors.stderr +++ b/src/test/rustdoc-ui/intra-links-anchors.stderr @@ -4,7 +4,7 @@ error: `[Foo::f#hola]` has an issue with the link anchor. LL | /// Or maybe [Foo::f#hola]. | ^^^^^^^^^^^ struct fields cannot be followed by anchors | -note: lint level defined here +note: the lint level is defined here --> $DIR/intra-links-anchors.rs:1:9 | LL | #![deny(intra_doc_link_resolution_failure)] diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index dca98cf58df31..852c9120e0bf9 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -8,7 +8,7 @@ LL | | /// println!("sup"); LL | | /// ``` | |_______^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group.rs:7:9 | LL | #![deny(rustdoc)] @@ -21,7 +21,7 @@ error: `[error]` cannot be resolved, ignoring it. LL | /// what up, let's make an [error] | ^^^^^ cannot be resolved, ignoring | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group.rs:7:9 | LL | #![deny(rustdoc)] @@ -35,7 +35,7 @@ error: missing code example in this documentation LL | /// wait, this doesn't have a doctest? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group.rs:7:9 | LL | #![deny(rustdoc)] diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr index 179dba17c6d81..3fcfc1808e079 100644 --- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr @@ -5,7 +5,7 @@ LL | / mod module1 { LL | | } | |_^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-missing-doc-code-example.rs:2:9 | LL | #![deny(missing_doc_code_examples)] diff --git a/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr index 8abbdb31ec91a..70b6638b23711 100644 --- a/src/test/rustdoc-ui/private-item-doc-test.stderr +++ b/src/test/rustdoc-ui/private-item-doc-test.stderr @@ -8,7 +8,7 @@ LL | | /// assert!(false); LL | | /// ``` | |___________^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/private-item-doc-test.rs:1:9 | LL | #![deny(private_doc_tests)] diff --git a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr index c1762d31323cf..4f78f51b676f4 100644 --- a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr +++ b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr @@ -4,7 +4,7 @@ error: Prefer FxHashMap over HashMap, it has better performance LL | let _map: HashMap = HashMap::default(); | ^^^^^^^ help: use: `FxHashMap` | -note: lint level defined here +note: the lint level is defined here --> $DIR/default_hash_types.rs:10:8 | LL | #[deny(rustc::default_hash_types)] diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index 39ac0019aac23..966a747a1c9f4 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -4,7 +4,7 @@ error: implementing `LintPass` by hand LL | impl LintPass for Foo { | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint_pass_impl_without_macro.rs:4:9 | LL | #![deny(rustc::lint_pass_impl_without_macro)] diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.stderr b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.stderr index d2ed6b6a19c31..2751a37f7419d 100644 --- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.stderr +++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.stderr @@ -4,7 +4,7 @@ error: passing `Ty<'_>` by reference LL | ty_ref: &Ty<'_>, | ^^^^^^^ help: try passing by value: `Ty<'_>` | -note: lint level defined here +note: the lint level is defined here --> $DIR/pass_ty_by_ref.rs:4:9 | LL | #![deny(rustc::ty_pass_by_reference)] diff --git a/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr b/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr index 72c23f8cd3cac..59732cd84e520 100644 --- a/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr +++ b/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr @@ -4,7 +4,7 @@ error: usage of qualified `ty::Ty<'_>` LL | ty_q: ty::Ty<'_>, | ^^^^^^^^^^ help: try using it unqualified: `Ty<'_>` | -note: lint level defined here +note: the lint level is defined here --> $DIR/qualified_ty_ty_ctxt.rs:4:9 | LL | #![deny(rustc::usage_of_qualified_ty)] diff --git a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr index 28c837adac3a1..ee9f1ff10f88e 100644 --- a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr +++ b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr @@ -4,7 +4,7 @@ error: usage of `ty::TyKind::` LL | let kind = TyKind::Bool; | ^^^^^^ help: try using ty:: directly: `ty` | -note: lint level defined here +note: the lint level is defined here --> $DIR/ty_tykind_usage.rs:9:8 | LL | #[deny(rustc::usage_of_ty_tykind)] diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr index c611023e5490c..a0081b15f53c5 100644 --- a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr +++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr @@ -12,7 +12,7 @@ error: item is named 'lintme' LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-plugin-deny-attr.rs:7:9 | LL | #![deny(test_lint)] diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr index f93a0a0de5377..df92bc70a7971 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr @@ -30,7 +30,7 @@ error: item is named 'lintme' LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-plugin-forbid-attrs.rs:7:11 | LL | #![forbid(test_lint)] diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr index 809b9ac16205d..31d25652d5d39 100644 --- a/src/test/ui-fulldeps/lint-tool-test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr @@ -70,7 +70,7 @@ error: item is named 'lintme' LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] @@ -83,7 +83,7 @@ error: item is named 'lintmetoo' LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] diff --git a/src/test/ui/anon-params-deprecated.stderr b/src/test/ui/anon-params-deprecated.stderr index 8e4fa70d342f2..4520559845f47 100644 --- a/src/test/ui/anon-params-deprecated.stderr +++ b/src/test/ui/anon-params-deprecated.stderr @@ -4,7 +4,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi LL | fn foo(i32); | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | -note: lint level defined here +note: the lint level is defined here --> $DIR/anon-params-deprecated.rs:1:9 | LL | #![warn(anonymous_parameters)] diff --git a/src/test/ui/associated-const/associated-const-dead-code.stderr b/src/test/ui/associated-const/associated-const-dead-code.stderr index 8c6d76bbdf68c..172aed733fca9 100644 --- a/src/test/ui/associated-const/associated-const-dead-code.stderr +++ b/src/test/ui/associated-const/associated-const-dead-code.stderr @@ -4,7 +4,7 @@ error: associated const is never used: `BAR` LL | const BAR: u32 = 1; | ^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/associated-const-dead-code.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index f1a22cda51b21..474c09d79dfbb 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -4,7 +4,7 @@ error: `await` is a keyword in the 2018 edition LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | -note: lint level defined here +note: the lint level is defined here --> $DIR/2015-edition-error-various-positions.rs:2:9 | LL | #![deny(keyword_idents)] diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr index d9ae1b9a167a6..0c558eb12f089 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr @@ -4,7 +4,7 @@ error: `await` is a keyword in the 2018 edition LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | -note: lint level defined here +note: the lint level is defined here --> $DIR/2015-edition-warning.rs:4:9 | LL | #![deny(keyword_idents)] diff --git a/src/test/ui/async-await/unreachable-lint-1.stderr b/src/test/ui/async-await/unreachable-lint-1.stderr index 382581bf94554..e9325788961b2 100644 --- a/src/test/ui/async-await/unreachable-lint-1.stderr +++ b/src/test/ui/async-await/unreachable-lint-1.stderr @@ -6,7 +6,7 @@ LL | return; bar().await; | | | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-lint-1.rs:2:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr index 885cdc04cfa4c..2a7a12a364346 100644 --- a/src/test/ui/async-await/unused-lifetime.stderr +++ b/src/test/ui/async-await/unused-lifetime.stderr @@ -4,7 +4,7 @@ error: lifetime parameter `'a` never used LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) { | ^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-lifetime.rs:7:9 | LL | #![deny(unused_lifetimes)] diff --git a/src/test/ui/attributes/register-attr-tool-unused.stderr b/src/test/ui/attributes/register-attr-tool-unused.stderr index 0756c572c35fe..85a4fa4a74813 100644 --- a/src/test/ui/attributes/register-attr-tool-unused.stderr +++ b/src/test/ui/attributes/register-attr-tool-unused.stderr @@ -4,7 +4,7 @@ error: unused attribute LL | #[register_attr(attr)] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/register-attr-tool-unused.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/bad/bad-lint-cap2.stderr b/src/test/ui/bad/bad-lint-cap2.stderr index 75e257893fa80..3f3affe5a9811 100644 --- a/src/test/ui/bad/bad-lint-cap2.stderr +++ b/src/test/ui/bad/bad-lint-cap2.stderr @@ -4,7 +4,7 @@ error: unused import: `std::option` LL | use std::option; | ^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/bad-lint-cap2.rs:4:9 | LL | #![deny(warnings)] diff --git a/src/test/ui/bad/bad-lint-cap3.stderr b/src/test/ui/bad/bad-lint-cap3.stderr index 96b40c98c0ed8..a4e399b1fac39 100644 --- a/src/test/ui/bad/bad-lint-cap3.stderr +++ b/src/test/ui/bad/bad-lint-cap3.stderr @@ -4,7 +4,7 @@ warning: unused import: `std::option` LL | use std::option; | ^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/bad-lint-cap3.rs:5:9 | LL | #![deny(warnings)] diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.stderr index 77fbfb37addd0..85779e53437c7 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.stderr @@ -9,7 +9,7 @@ LL | v.push(shared.len()); | | | mutable borrow occurs here | -note: lint level defined here +note: the lint level is defined here --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:18:13 | LL | #![warn(mutable_borrow_reservation_conflict)] @@ -28,7 +28,7 @@ LL | v.push(shared.len()); | | | mutable borrow occurs here | -note: lint level defined here +note: the lint level is defined here --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:31:13 | LL | #![deny(mutable_borrow_reservation_conflict)] diff --git a/src/test/ui/cast-char.stderr b/src/test/ui/cast-char.stderr index 1729e5cbf0931..211937c9d6faf 100644 --- a/src/test/ui/cast-char.stderr +++ b/src/test/ui/cast-char.stderr @@ -4,7 +4,7 @@ error: only `u8` can be cast into `char` LL | const XYZ: char = 0x1F888 as char; | ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'` | -note: lint level defined here +note: the lint level is defined here --> $DIR/cast-char.rs:1:9 | LL | #![deny(overflowing_literals)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr index 046defd5561ae..67cb6530e3831 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr @@ -4,7 +4,7 @@ error: unused attribute LL | #[cfg_attr(FALSE,)] | ^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cfg-attr-empty-is-unused.rs:5:9 | LL | #![deny(unused)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index f55671f6bba81..d2c613845a0ff 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -30,7 +30,7 @@ warning: unused `MustUseDeprecated` that must be used LL | MustUseDeprecated::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cfg-attr-multi-true.rs:7:9 | LL | #![warn(unused_must_use)] diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr index 32cf8d8a01a78..3fb7c8c48b90d 100644 --- a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr +++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr @@ -12,7 +12,7 @@ error: const parameter `x` should have an upper case name LL | fn noop() { | ^ help: convert the identifier to upper case (notice the capitalization): `X` | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-parameter-uppercase-lint.rs:4:9 | LL | #![deny(non_upper_case_globals)] diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr index e93aa324784c3..59e116970150a 100644 --- a/src/test/ui/consts/array-literal-index-oob.stderr +++ b/src/test/ui/consts/array-literal-index-oob.stderr @@ -4,7 +4,7 @@ warning: index out of bounds: the len is 3 but the index is 4 LL | &{ [1, 2, 3][4] }; | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/array-literal-index-oob.rs:4:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr index 4b13f52e76291..104197fa17fc6 100644 --- a/src/test/ui/consts/assoc_const_generic_impl.stderr +++ b/src/test/ui/consts/assoc_const_generic_impl.stderr @@ -6,7 +6,7 @@ LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::()]; | | | index out of bounds: the len is 1 but the index is 4 | -note: lint level defined here +note: the lint level is defined here --> $DIR/assoc_const_generic_impl.rs:3:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-err-early.stderr b/src/test/ui/consts/const-err-early.stderr index 9b0ef94a5b8c3..b78ac38d7e7e2 100644 --- a/src/test/ui/consts/const-err-early.stderr +++ b/src/test/ui/consts/const-err-early.stderr @@ -6,7 +6,7 @@ LL | pub const A: i8 = -std::i8::MIN; | | | attempt to negate with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr index c647f13fc7520..65427b8a1b289 100644 --- a/src/test/ui/consts/const-err-multi.stderr +++ b/src/test/ui/consts/const-err-multi.stderr @@ -6,7 +6,7 @@ LL | pub const A: i8 = -std::i8::MIN; | | | attempt to negate with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr index 495b221d7d724..069521e6e4541 100644 --- a/src/test/ui/consts/const-err.stderr +++ b/src/test/ui/consts/const-err.stderr @@ -6,7 +6,7 @@ LL | const FOO: u8 = [5u8][1]; | | | index out of bounds: the len is 1 but the index is 1 | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-err.rs:5:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index 2ca1019d4947b..a76b6d1775f04 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -4,7 +4,7 @@ error: this expression will panic at runtime LL | let a = -std::i8::MIN; | ^^^^^^^^^^^^^ attempt to negate with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-err2.rs:11:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr index c374637bec267..02b912e928c80 100644 --- a/src/test/ui/consts/const-err3.stderr +++ b/src/test/ui/consts/const-err3.stderr @@ -4,7 +4,7 @@ error: attempt to negate with overflow LL | let a = -std::i8::MIN; | ^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-err3.rs:11:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index b5f5f84cf3894..c72a1ed40c5d4 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -6,7 +6,7 @@ LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | | | attempt to subtract with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/conditional_array_execution.rs:3:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr index 419b3d52dbff1..6f823005572b5 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr @@ -8,7 +8,7 @@ LL | | i8::MIN - 1, LL | | ); | |_______- | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr index 2cfd34c9fc3c7..f9a4e5aa96801 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr @@ -8,7 +8,7 @@ LL | | i8::MAX + 1, LL | | ); | |_______- | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr index 5e63286c594d9..6b90617802629 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr @@ -8,7 +8,7 @@ LL | | i8::MIN * 2, LL | | ); | |_______- | -note: lint level defined here +note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr index e664a4aab3ca5..8fadfabe41c93 100644 --- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr +++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr @@ -6,7 +6,7 @@ LL | const VOID: ! = { let x = 0 * std::mem::size_of::(); [][x] }; | | | index out of bounds: the len is 0 but the index is 0 | -note: lint level defined here +note: the lint level is defined here --> $DIR/index-out-of-bounds-never-type.rs:4:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 23b54d954c658..668d061b799d0 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -6,7 +6,7 @@ LL | const X: u32 = 0 - 1; | | | attempt to subtract with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr index 575c3648b70db..d09a295264c62 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -6,7 +6,7 @@ LL | const VOID: ! = panic!(); | | | the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:11:21 | -note: lint level defined here +note: the lint level is defined here --> $DIR/panic-assoc-never-type.rs:4:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/panic-never-type.stderr b/src/test/ui/consts/const-eval/panic-never-type.stderr index 4d1686a8d8f04..3daad0a2fdd8c 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-never-type.stderr @@ -6,7 +6,7 @@ LL | const VOID: ! = panic!(); | | | the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:8:17 | -note: lint level defined here +note: the lint level is defined here --> $DIR/panic-never-type.rs:4:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index b4330deb3ef10..08ae5c7a32b65 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -4,7 +4,7 @@ warning: this expression will panic at runtime LL | let _x = 0u32 - 1; | ^^^^^^^^ attempt to subtract with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/promoted_errors.rs:5:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr index a4dad295edd79..d1a9cb958e155 100644 --- a/src/test/ui/consts/const-eval/promoted_errors2.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr @@ -4,7 +4,7 @@ warning: attempt to subtract with overflow LL | println!("{}", 0u32 - 1); | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/promoted_errors2.rs:5:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/pub_const_err.stderr b/src/test/ui/consts/const-eval/pub_const_err.stderr index bd262b69da81a..ded2df4e013a3 100644 --- a/src/test/ui/consts/const-eval/pub_const_err.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err.stderr @@ -6,7 +6,7 @@ LL | pub const Z: u32 = 0 - 1; | | | attempt to subtract with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/pub_const_err.rs:2:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr index 866d1753edb95..570a8e49319a2 100644 --- a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr @@ -6,7 +6,7 @@ LL | pub const Z: u32 = 0 - 1; | | | attempt to subtract with overflow | -note: lint level defined here +note: the lint level is defined here --> $DIR/pub_const_err_bin.rs:2:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index c2446d1404019..4d9d258f80890 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -18,7 +18,7 @@ LL | | mem::transmute(out_of_bounds_ptr) LL | | } }; | |____- | -note: lint level defined here +note: the lint level is defined here --> $DIR/ub-nonnull.rs:14:8 | LL | #[deny(const_err)] // this triggers a `const_err` so validation does not even happen diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 51e80bb8b118b..c98e206e88c24 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -10,7 +10,7 @@ LL | unsafe { std::mem::transmute(()) } LL | const FOO: [Empty; 3] = [foo(); 3]; | ----------------------------------- | -note: lint level defined here +note: the lint level is defined here --> $DIR/validate_uninhabited_zsts.rs:13:8 | LL | #[warn(const_err)] diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index 243efbbaa76af..15e13942481c9 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -64,7 +64,7 @@ LL | | LL | | }; | |__- | -note: lint level defined here +note: the lint level is defined here --> $DIR/const_refers_to_static.rs:2:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/consts/miri_unleashed/mutable_const.stderr b/src/test/ui/consts/miri_unleashed/mutable_const.stderr index 9daca765c7cd0..86f27784701c6 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const.stderr @@ -16,7 +16,7 @@ LL | | } LL | | }; | |__- | -note: lint level defined here +note: the lint level is defined here --> $DIR/mutable_const.rs:5:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr index 6a7df858febcf..dcd37345fdd58 100644 --- a/src/test/ui/consts/miri_unleashed/non_const_fn.stderr +++ b/src/test/ui/consts/miri_unleashed/non_const_fn.stderr @@ -12,7 +12,7 @@ LL | const C: () = foo(); | | | calling non-const function `foo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/non_const_fn.rs:4:9 | LL | #![warn(const_err)] diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr index f90ca7986015e..e8c2156742f0d 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.stderr +++ b/src/test/ui/deprecation/deprecation-lint-2.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'deprecation_lint::deprecated': text LL | macro_test!(); | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deprecation-lint-2.rs:4:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr index fb90a63b0fb5c..7cc06a23b0fe3 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.stderr +++ b/src/test/ui/deprecation/deprecation-lint-3.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'deprecation_lint::deprecated_text': text LL | macro_test_arg_nested!(deprecated_text); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deprecation-lint-3.rs:4:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/deprecation/deprecation-lint-nested.stderr b/src/test/ui/deprecation/deprecation-lint-nested.stderr index 206e12cfb3ecf..b71f90014fe6e 100644 --- a/src/test/ui/deprecation/deprecation-lint-nested.stderr +++ b/src/test/ui/deprecation/deprecation-lint-nested.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'loud::DeprecatedType' LL | struct Foo(DeprecatedType); | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deprecation-lint-nested.rs:1:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index ffbcb259754e7..362a901d77d44 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'deprecation_lint::deprecated': text LL | deprecated(); | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deprecation-lint.rs:4:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr index 4bbe79b55b323..4aff11ad66f18 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr @@ -4,7 +4,7 @@ error: use of item 'S' that will be deprecated in future version 99.99.99: effec LL | let _ = S; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/rustc_deprecation-in-future.rs:3:9 | LL | #![deny(deprecated_in_future)] diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr index 6aaabfe957517..b60d420b54689 100644 --- a/src/test/ui/deprecation/suggestion.stderr +++ b/src/test/ui/deprecation/suggestion.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'Foo::deprecated': replaced by `replacement` LL | foo.deprecated(); | ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement` | -note: lint level defined here +note: the lint level is defined here --> $DIR/suggestion.rs:7:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr index b5d3670b5f39e..1fd7d58c86a37 100644 --- a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr +++ b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr @@ -4,7 +4,7 @@ error: unused attribute LL | #[derive()] | ^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deriving-meta-empty-trait-list.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 8093c58a67e42..8ab2e4cba7493 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -4,7 +4,7 @@ error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or cons LL | #[derive(Copy, Clone, PartialEq, Eq)] | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(safe_packed_borrows)] diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr index 46b137b2cf9c0..2d52ea3f6c20e 100644 --- a/src/test/ui/duplicate_entry_error.stderr +++ b/src/test/ui/duplicate_entry_error.stderr @@ -7,7 +7,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `duplicate_entry_error` depends on) + = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) error: aborting due to previous error diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr index 361727733bc57..32f06b62bb41a 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -4,7 +4,7 @@ error: `dyn` is a keyword in the 2018 edition LL | pub mod dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | -note: lint level defined here +note: the lint level is defined here --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:10:9 | LL | #![deny(keyword_idents)] diff --git a/src/test/ui/editions/edition-extern-crate-allowed.stderr b/src/test/ui/editions/edition-extern-crate-allowed.stderr index 45b46794be204..dd39847d49afa 100644 --- a/src/test/ui/editions/edition-extern-crate-allowed.stderr +++ b/src/test/ui/editions/edition-extern-crate-allowed.stderr @@ -4,7 +4,7 @@ warning: unused extern crate LL | extern crate edition_extern_crate_allowed; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-extern-crate-allowed.rs:5:9 | LL | #![warn(rust_2018_idioms)] diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr index 6a8861ba67bb9..1df582ee06c42 100644 --- a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr @@ -4,7 +4,7 @@ error: type annotations needed LL | let _ = y.is_null(); | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-raw-pointer-method-2015.rs:5:8 | LL | #[deny(warnings)] diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr index d5b8c0efaad37..bb4e928ad1583 100644 --- a/src/test/ui/enable-unstable-lib-feature.stderr +++ b/src/test/ui/enable-unstable-lib-feature.stderr @@ -4,7 +4,7 @@ error: function `BOGUS` should have a snake case name LL | pub fn BOGUS() { } | ^^^^^ help: convert the identifier to snake case: `bogus` | -note: lint level defined here +note: the lint level is defined here --> $DIR/enable-unstable-lib-feature.rs:6:9 | LL | #![deny(non_snake_case)] // To trigger a hard error diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr index f7220044ba42d..3aa88df29f11b 100644 --- a/src/test/ui/enum/enum-discrim-too-small2.stderr +++ b/src/test/ui/enum/enum-discrim-too-small2.stderr @@ -4,7 +4,7 @@ error: literal out of range for `i8` LL | Ci8 = 223, | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/enum-discrim-too-small2.rs:1:9 | LL | #![deny(overflowing_literals)] diff --git a/src/test/ui/enum/enum-size-variance.stderr b/src/test/ui/enum/enum-size-variance.stderr index 1ebd9b6806f89..cf8321d5f3a44 100644 --- a/src/test/ui/enum/enum-size-variance.stderr +++ b/src/test/ui/enum/enum-size-variance.stderr @@ -4,7 +4,7 @@ warning: enum variant is more than three times larger (32 bytes) than the next l LL | L(i64, i64, i64, i64), | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/enum-size-variance.rs:3:9 | LL | #![warn(variant_size_differences)] diff --git a/src/test/ui/error-codes/E0001.stderr b/src/test/ui/error-codes/E0001.stderr index 992345151827f..577c49032d799 100644 --- a/src/test/ui/error-codes/E0001.stderr +++ b/src/test/ui/error-codes/E0001.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | _ => {/* ... */} | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/E0001.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index c41a0430150a4..29981991ee02b 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -4,7 +4,7 @@ error[E0152]: found duplicate lang item `arc` LL | struct Foo; | ^^^^^^^^^^^ | - = note: first defined in crate `alloc` (which `std` depends on) + = note: the lang item is first defined in crate `alloc` (which `std` depends on) error: aborting due to previous error diff --git a/src/test/ui/expr_attr_paren_order.stderr b/src/test/ui/expr_attr_paren_order.stderr index 57a9350c089a8..c6b373e3f13c4 100644 --- a/src/test/ui/expr_attr_paren_order.stderr +++ b/src/test/ui/expr_attr_paren_order.stderr @@ -4,7 +4,7 @@ error: variable `X` should have a snake case name LL | let X = 0; | ^ help: convert the identifier to snake case (notice the capitalization): `x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_attr_paren_order.rs:17:17 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/extern-flag/public-and-private.stderr b/src/test/ui/extern-flag/public-and-private.stderr index 72f1bb2d26f1a..94c7deaa80de8 100644 --- a/src/test/ui/extern-flag/public-and-private.stderr +++ b/src/test/ui/extern-flag/public-and-private.stderr @@ -4,7 +4,7 @@ error: type `somedep::S` from private dependency 'somedep' in public interface LL | pub field: somedep::S, | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/public-and-private.rs:5:9 | LL | #![deny(exported_private_dependencies)] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index da7d8f9bee5c5..96c87a675a9fa 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -4,7 +4,7 @@ warning: unknown lint: `x5400` LL | #![warn(x5400)] | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:28 | LL | #![warn(unused_attributes, unknown_lints)] @@ -250,7 +250,7 @@ warning: unused attribute LL | #[macro_use] fn f() { } | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 | LL | #![warn(unused_attributes, unknown_lints)] diff --git a/src/test/ui/feature-gates/feature-gate-feature-gate.stderr b/src/test/ui/feature-gates/feature-gate-feature-gate.stderr index d79404263e452..ad97741dae4d0 100644 --- a/src/test/ui/feature-gates/feature-gate-feature-gate.stderr +++ b/src/test/ui/feature-gates/feature-gate-feature-gate.stderr @@ -4,7 +4,7 @@ error: unstable feature LL | #![feature(intrinsics)] | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/feature-gate-feature-gate.rs:1:11 | LL | #![forbid(unstable_features)] diff --git a/src/test/ui/feature-gates/feature-gate-no-debug-2.stderr b/src/test/ui/feature-gates/feature-gate-no-debug-2.stderr index 1f8f114d7da53..9a6f898f2a5a8 100644 --- a/src/test/ui/feature-gates/feature-gate-no-debug-2.stderr +++ b/src/test/ui/feature-gates/feature-gate-no-debug-2.stderr @@ -4,7 +4,7 @@ error: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was a LL | #[no_debug] | ^^^^^^^^^^^ help: remove this attribute | -note: lint level defined here +note: the lint level is defined here --> $DIR/feature-gate-no-debug-2.rs:1:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr index 5a1a4e36e06da..64f865e5b70ae 100644 --- a/src/test/ui/fn_must_use.stderr +++ b/src/test/ui/fn_must_use.stderr @@ -4,7 +4,7 @@ warning: unused return value of `need_to_use_this_value` that must be used LL | need_to_use_this_value(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/fn_must_use.rs:3:9 | LL | #![warn(unused_must_use)] diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 1d958e5bfeb40..a19051e8bc0b2 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -4,7 +4,7 @@ error: anonymous parameters are deprecated and will be removed in the next editi LL | fn f(u8) {} | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | -note: lint level defined here +note: the lint level is defined here --> $DIR/future-incompatible-lint-group.rs:1:9 | LL | #![deny(future_incompatible)] diff --git a/src/test/ui/generic/generic-no-mangle.stderr b/src/test/ui/generic/generic-no-mangle.stderr index f055a3ab83f76..ab2ad541e8640 100644 --- a/src/test/ui/generic/generic-no-mangle.stderr +++ b/src/test/ui/generic/generic-no-mangle.stderr @@ -6,7 +6,7 @@ LL | #[no_mangle] LL | pub fn foo() {} | ^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/generic-no-mangle.rs:1:9 | LL | #![deny(no_mangle_generic_items)] diff --git a/src/test/ui/imports/extern-crate-used.stderr b/src/test/ui/imports/extern-crate-used.stderr index 397bfa02902c9..1b9a2e4720d5f 100644 --- a/src/test/ui/imports/extern-crate-used.stderr +++ b/src/test/ui/imports/extern-crate-used.stderr @@ -4,7 +4,7 @@ error: unused extern crate LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/extern-crate-used.rs:6:9 | LL | #![deny(unused_extern_crates)] diff --git a/src/test/ui/imports/reexports.stderr b/src/test/ui/imports/reexports.stderr index b173884080f80..7b0d63574ec8e 100644 --- a/src/test/ui/imports/reexports.stderr +++ b/src/test/ui/imports/reexports.stderr @@ -40,7 +40,7 @@ warning: glob import doesn't reexport anything because no candidate is public en LL | pub use super::*; | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/reexports.rs:1:9 | LL | #![warn(unused_imports)] diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr index d7280d2583a76..69765b9227d6e 100644 --- a/src/test/ui/imports/unresolved-imports-used.stderr +++ b/src/test/ui/imports/unresolved-imports-used.stderr @@ -52,7 +52,7 @@ error: unused import: `qux::quy` LL | use qux::quy; | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unresolved-imports-used.rs:2:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/imports/unused-macro-use.stderr b/src/test/ui/imports/unused-macro-use.stderr index b7fb532c67cce..7137a90e45956 100644 --- a/src/test/ui/imports/unused-macro-use.stderr +++ b/src/test/ui/imports/unused-macro-use.stderr @@ -4,7 +4,7 @@ error: unused `#[macro_use]` import LL | #[macro_use] | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-macro-use.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/imports/unused.stderr b/src/test/ui/imports/unused.stderr index 0366b52ef6a5a..08128d794251b 100644 --- a/src/test/ui/imports/unused.stderr +++ b/src/test/ui/imports/unused.stderr @@ -4,7 +4,7 @@ error: unused import: `super::f` LL | pub(super) use super::f; | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed b/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed index 29c570daefd0b..2998f05efbae4 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed @@ -3,7 +3,7 @@ #![allow(unused)] #![deny(elided_lifetimes_in_paths)] -//~^ NOTE lint level defined here +//~^ NOTE the lint level is defined here use std::cell::{RefCell, Ref}; diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.rs b/src/test/ui/in-band-lifetimes/elided-lifetimes.rs index e59c9b4367f12..b729a15a29edd 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.rs +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.rs @@ -3,7 +3,7 @@ #![allow(unused)] #![deny(elided_lifetimes_in_paths)] -//~^ NOTE lint level defined here +//~^ NOTE the lint level is defined here use std::cell::{RefCell, Ref}; diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr b/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr index 5c50d7e2aac3f..1184f51680a0e 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr @@ -4,7 +4,7 @@ error: hidden lifetime parameters in types are deprecated LL | fn foo(x: &Foo) { | ^^^- help: indicate the anonymous lifetime: `<'_>` | -note: lint level defined here +note: the lint level is defined here --> $DIR/elided-lifetimes.rs:5:9 | LL | #![deny(elided_lifetimes_in_paths)] diff --git a/src/test/ui/invalid/invalid-plugin-attr.stderr b/src/test/ui/invalid/invalid-plugin-attr.stderr index 0d7315dd887ca..9d07eafcc8f20 100644 --- a/src/test/ui/invalid/invalid-plugin-attr.stderr +++ b/src/test/ui/invalid/invalid-plugin-attr.stderr @@ -12,7 +12,7 @@ error: unused attribute LL | #[plugin(bla)] | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/invalid-plugin-attr.rs:1:9 | LL | #![deny(unused_attributes)] diff --git a/src/test/ui/issues/issue-10656.stderr b/src/test/ui/issues/issue-10656.stderr index 818457f50794e..2e91a598dce40 100644 --- a/src/test/ui/issues/issue-10656.stderr +++ b/src/test/ui/issues/issue-10656.stderr @@ -5,7 +5,7 @@ LL | / #![deny(missing_docs)] LL | | #![crate_type="lib"] | |____________________^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-10656.rs:1:9 | LL | #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-12116.stderr b/src/test/ui/issues/issue-12116.stderr index 10db4f1c031d2..4d162eb77e725 100644 --- a/src/test/ui/issues/issue-12116.stderr +++ b/src/test/ui/issues/issue-12116.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-12116.rs:5:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr index 754b94bab75eb..aab2be78c9a4c 100644 --- a/src/test/ui/issues/issue-12369.stderr +++ b/src/test/ui/issues/issue-12369.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | &[10,a, ref rest @ ..] => 10 | ^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-12369.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-13727.stderr b/src/test/ui/issues/issue-13727.stderr index 4d1066516249b..07ca56a566ff1 100644 --- a/src/test/ui/issues/issue-13727.stderr +++ b/src/test/ui/issues/issue-13727.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | 512 => print!("0b1111\n"), | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-13727.rs:2:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-14221.stderr b/src/test/ui/issues/issue-14221.stderr index 9864c0840d878..63680f6ca56a7 100644 --- a/src/test/ui/issues/issue-14221.stderr +++ b/src/test/ui/issues/issue-14221.stderr @@ -21,7 +21,7 @@ LL | LL | B => "B", | ^ unreachable pattern | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-14221.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-14309.stderr b/src/test/ui/issues/issue-14309.stderr index f598e1f9e2f6d..799991f7ee4ba 100644 --- a/src/test/ui/issues/issue-14309.stderr +++ b/src/test/ui/issues/issue-14309.stderr @@ -4,14 +4,14 @@ error: `extern` block uses type `A`, which is not FFI-safe LL | fn foo(x: A); | ^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-14309.rs:1:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-14309.rs:4:1 | LL | / struct A { @@ -27,7 +27,7 @@ LL | fn bar(x: B); | = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-14309.rs:4:1 | LL | / struct A { @@ -43,7 +43,7 @@ LL | fn qux(x: A2); | = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-14309.rs:4:1 | LL | / struct A { @@ -59,7 +59,7 @@ LL | fn quux(x: B2); | = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-14309.rs:4:1 | LL | / struct A { @@ -75,7 +75,7 @@ LL | fn fred(x: D); | = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-14309.rs:4:1 | LL | / struct A { diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr index 5686ac3774215..45f854f93ecb9 100644 --- a/src/test/ui/issues/issue-16250.stderr +++ b/src/test/ui/issues/issue-16250.stderr @@ -4,7 +4,7 @@ error: `extern` block uses type `Foo`, which is not FFI-safe LL | pub fn foo(x: (Foo)); | ^^^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-16250.rs:1:9 | LL | #![deny(warnings)] @@ -12,7 +12,7 @@ LL | #![deny(warnings)] = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]` = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/issue-16250.rs:3:1 | LL | pub struct Foo; diff --git a/src/test/ui/issues/issue-17337.stderr b/src/test/ui/issues/issue-17337.stderr index 8973afb806817..4a8116b1ffdb9 100644 --- a/src/test/ui/issues/issue-17337.stderr +++ b/src/test/ui/issues/issue-17337.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'Foo::foo': text LL | .foo(); | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-17337.rs:2:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/issues/issue-17718-const-naming.stderr b/src/test/ui/issues/issue-17718-const-naming.stderr index e320c436f5b68..4c0aa0553ebd2 100644 --- a/src/test/ui/issues/issue-17718-const-naming.stderr +++ b/src/test/ui/issues/issue-17718-const-naming.stderr @@ -4,7 +4,7 @@ error: constant item is never used: `foo` LL | const foo: isize = 3; | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-17718-const-naming.rs:2:9 | LL | #![deny(warnings)] @@ -17,7 +17,7 @@ error: constant `foo` should have an upper case name LL | const foo: isize = 3; | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-17718-const-naming.rs:2:9 | LL | #![deny(warnings)] diff --git a/src/test/ui/issues/issue-17999.stderr b/src/test/ui/issues/issue-17999.stderr index b9ae03356e9bc..448208ef033f7 100644 --- a/src/test/ui/issues/issue-17999.stderr +++ b/src/test/ui/issues/issue-17999.stderr @@ -4,7 +4,7 @@ error: unused variable: `x` LL | let x = (); | ^ help: consider prefixing with an underscore: `_x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-17999.rs:1:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/issues/issue-2150.stderr b/src/test/ui/issues/issue-2150.stderr index 6e102ecb62fff..3f3702551069f 100644 --- a/src/test/ui/issues/issue-2150.stderr +++ b/src/test/ui/issues/issue-2150.stderr @@ -6,7 +6,7 @@ LL | panic!(); LL | for x in &v { i += 1; } | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-2150.rs:1:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/issues/issue-22599.stderr b/src/test/ui/issues/issue-22599.stderr index 12234293ac995..9c3b2cbe6c796 100644 --- a/src/test/ui/issues/issue-22599.stderr +++ b/src/test/ui/issues/issue-22599.stderr @@ -4,7 +4,7 @@ error: unused variable: `a` LL | v = match 0 { a => 0 }; | ^ help: consider prefixing with an underscore: `_a` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-22599.rs:1:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/issues/issue-27060.stderr b/src/test/ui/issues/issue-27060.stderr index bc44c1a4ac571..6bf6348631a70 100644 --- a/src/test/ui/issues/issue-27060.stderr +++ b/src/test/ui/issues/issue-27060.stderr @@ -4,7 +4,7 @@ error: borrow of packed field is unsafe and requires unsafe function or block (e LL | let _ = &good.data; | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-27060.rs:13:8 | LL | #[deny(safe_packed_borrows)] diff --git a/src/test/ui/issues/issue-30240-b.stderr b/src/test/ui/issues/issue-30240-b.stderr index e0dd4794db59a..59d64bc256b50 100644 --- a/src/test/ui/issues/issue-30240-b.stderr +++ b/src/test/ui/issues/issue-30240-b.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | "hello" => {} | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-30240-b.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-30302.stderr b/src/test/ui/issues/issue-30302.stderr index ac1b5235f4423..770ed3d4f0152 100644 --- a/src/test/ui/issues/issue-30302.stderr +++ b/src/test/ui/issues/issue-30302.stderr @@ -15,7 +15,7 @@ LL | LL | _ => false | ^ unreachable pattern | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-30302.rs:4:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-30730.stderr b/src/test/ui/issues/issue-30730.stderr index fcbab77b0073b..b299e99a3a908 100644 --- a/src/test/ui/issues/issue-30730.stderr +++ b/src/test/ui/issues/issue-30730.stderr @@ -4,7 +4,7 @@ error: unused import: `std::thread` LL | use std::thread; | ^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-30730.rs:2:9 | LL | #![deny(warnings)] diff --git a/src/test/ui/issues/issue-31221.stderr b/src/test/ui/issues/issue-31221.stderr index 0f3b4ba7d97ea..7d34914445637 100644 --- a/src/test/ui/issues/issue-31221.stderr +++ b/src/test/ui/issues/issue-31221.stderr @@ -6,7 +6,7 @@ LL | Var3 => (), LL | Var2 => (), | ^^^^ unreachable pattern | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-31221.rs:4:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.stderr b/src/test/ui/issues/issue-33140-traitobject-crate.stderr index f31ea9391ab4b..efa77f5ceb8ca 100644 --- a/src/test/ui/issues/issue-33140-traitobject-crate.stderr +++ b/src/test/ui/issues/issue-33140-traitobject-crate.stderr @@ -6,7 +6,7 @@ LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-33140-traitobject-crate.rs:3:9 | LL | #![warn(order_dependent_trait_objects)] diff --git a/src/test/ui/issues/issue-37515.stderr b/src/test/ui/issues/issue-37515.stderr index f084095969847..1aafa512d835c 100644 --- a/src/test/ui/issues/issue-37515.stderr +++ b/src/test/ui/issues/issue-37515.stderr @@ -4,7 +4,7 @@ warning: type alias is never used: `Z` LL | type Z = dyn for<'x> Send; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-37515.rs:3:9 | LL | #![warn(unused)] diff --git a/src/test/ui/issues/issue-41255.stderr b/src/test/ui/issues/issue-41255.stderr index 1ff58153c8864..b6e57afcd1292 100644 --- a/src/test/ui/issues/issue-41255.stderr +++ b/src/test/ui/issues/issue-41255.stderr @@ -4,7 +4,7 @@ error: floating-point types cannot be used in patterns LL | 5.0 => {}, | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-41255.rs:6:11 | LL | #![forbid(illegal_floating_point_literal_pattern)] diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.stderr b/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.stderr index 71fbba562cae1..321698e763696 100644 --- a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.stderr +++ b/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.stderr @@ -7,7 +7,7 @@ LL | let f = |v: &mut Vec<_>| { LL | unsafe { | ^^^^^^ unnecessary `unsafe` block | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:1:8 | LL | #[deny(unused_unsafe)] diff --git a/src/test/ui/issues/issue-46576.stderr b/src/test/ui/issues/issue-46576.stderr index 4b66219dd3d19..1e5e730ee649f 100644 --- a/src/test/ui/issues/issue-46576.stderr +++ b/src/test/ui/issues/issue-46576.stderr @@ -4,7 +4,7 @@ error: unused import: `BufRead` LL | use std::io::{BufRead, BufReader, Read}; | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-46576.rs:4:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/issues/issue-48131.stderr b/src/test/ui/issues/issue-48131.stderr index 6df065b9807f2..5acc4f16e9fc2 100644 --- a/src/test/ui/issues/issue-48131.stderr +++ b/src/test/ui/issues/issue-48131.stderr @@ -4,7 +4,7 @@ error: unnecessary `unsafe` block LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-48131.rs:3:9 | LL | #![deny(unused_unsafe)] diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs index 262f4931d42d4..5b253750db0b6 100644 --- a/src/test/ui/issues/issue-49934.rs +++ b/src/test/ui/issues/issue-49934.rs @@ -1,7 +1,7 @@ // check-pass #![feature(stmt_expr_attributes)] -#![warn(unused_attributes)] //~ NOTE lint level defined here +#![warn(unused_attributes)] //~ NOTE the lint level is defined here fn main() { // fold_stmt (Item) diff --git a/src/test/ui/issues/issue-49934.stderr b/src/test/ui/issues/issue-49934.stderr index dbec379e3c55b..64bf5214e6dd4 100644 --- a/src/test/ui/issues/issue-49934.stderr +++ b/src/test/ui/issues/issue-49934.stderr @@ -12,7 +12,7 @@ warning: unused attribute LL | #[derive(Debug)] | ^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-49934.rs:4:9 | LL | #![warn(unused_attributes)] diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index 02475ea97e3d1..cb6ca24c7124a 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -4,7 +4,7 @@ error: the trait `X` cannot be made into an object LL | fn foo(&self) where Self: Trait; | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 | LL | #![deny(where_clauses_object_safety)] diff --git a/src/test/ui/issues/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr index e094256f5c827..91b81ba6943ad 100644 --- a/src/test/ui/issues/issue-55511.stderr +++ b/src/test/ui/issues/issue-55511.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `std::cell::Cell` in a pattern, `std::cell::C LL | <() as Foo<'static>>::C => { } | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-55511.rs:1:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/issues/issue-56685.stderr b/src/test/ui/issues/issue-56685.stderr index 30fedbe1653c4..2cef3126b9ee0 100644 --- a/src/test/ui/issues/issue-56685.stderr +++ b/src/test/ui/issues/issue-56685.stderr @@ -4,7 +4,7 @@ error: unused variable: `x` LL | E::A(x) | E::B(x) => {} | ^ ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-56685.rs:2:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/issues/issue-57472.stderr b/src/test/ui/issues/issue-57472.stderr index b6dd7e2494186..26efdf6dbaf34 100644 --- a/src/test/ui/issues/issue-57472.stderr +++ b/src/test/ui/issues/issue-57472.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | Punned { bar: [_], .. } => println!("bar"), | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-57472.rs:2:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/issues/issue-59896.stderr b/src/test/ui/issues/issue-59896.stderr index ef78f27fa69a3..95b7938ae0383 100644 --- a/src/test/ui/issues/issue-59896.stderr +++ b/src/test/ui/issues/issue-59896.stderr @@ -7,7 +7,7 @@ LL | struct S; LL | use S; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-59896.rs:1:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr index da0ae1541bb8f..79cb6cfc35494 100644 --- a/src/test/ui/issues/issue-60622.stderr +++ b/src/test/ui/issues/issue-60622.stderr @@ -7,7 +7,7 @@ LL | fn a(&self) {} LL | b.a::<'_, T>(); | ^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-60622.rs:3:9 | LL | #![deny(warnings)] diff --git a/src/test/ui/issues/issue-6804.stderr b/src/test/ui/issues/issue-6804.stderr index f4188dc3566c2..c7411e27c255a 100644 --- a/src/test/ui/issues/issue-6804.stderr +++ b/src/test/ui/issues/issue-6804.stderr @@ -4,7 +4,7 @@ error: floating-point types cannot be used in patterns LL | NAN => {}, | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-6804.rs:4:9 | LL | #![deny(illegal_floating_point_literal_pattern)] diff --git a/src/test/ui/issues/issue-7246.stderr b/src/test/ui/issues/issue-7246.stderr index a11ce1654cad8..bb0221ecb86b4 100644 --- a/src/test/ui/issues/issue-7246.stderr +++ b/src/test/ui/issues/issue-7246.stderr @@ -6,7 +6,7 @@ LL | return; LL | if *ptr::null() {}; | ^^^^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-7246.rs:1:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr index 170747f840268..6b1d74094a10b 100644 --- a/src/test/ui/issues/issue-8460-const.stderr +++ b/src/test/ui/issues/issue-8460-const.stderr @@ -4,7 +4,7 @@ error: attempt to divide with overflow LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-8460-const.rs:4:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr index 6ad186fb21c66..63b9123e95097 100644 --- a/src/test/ui/issues/issue-8460-const2.stderr +++ b/src/test/ui/issues/issue-8460-const2.stderr @@ -4,7 +4,7 @@ error: attempt to divide with overflow LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-8460-const2.rs:4:9 | LL | #![deny(const_err)] diff --git a/src/test/ui/lint/dead-code/basic.stderr b/src/test/ui/lint/dead-code/basic.stderr index 194398e5a07a5..f7b9b9c613ae0 100644 --- a/src/test/ui/lint/dead-code/basic.stderr +++ b/src/test/ui/lint/dead-code/basic.stderr @@ -4,7 +4,7 @@ error: function is never used: `foo` LL | fn foo() { | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/basic.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr index 44b0a8f613e27..ed9a7ccd14b21 100644 --- a/src/test/ui/lint/dead-code/empty-unused-enum.stderr +++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr @@ -4,7 +4,7 @@ error: enum is never used: `E` LL | enum E {} | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/empty-unused-enum.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/lint/dead-code/impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr index f2a78cc65e26e..09b6d08eb8fb8 100644 --- a/src/test/ui/lint/dead-code/impl-trait.stderr +++ b/src/test/ui/lint/dead-code/impl-trait.stderr @@ -4,7 +4,7 @@ error: type alias is never used: `Unused` LL | type Unused = (); | ^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/impl-trait.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr index bac46a2e843cd..0a08aa6da9ac0 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr @@ -4,7 +4,7 @@ error: struct is never constructed: `Bar` LL | pub struct Bar; | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-dead-code-1.rs:5:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr index a578a76d9a075..b01ba57f98580 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr @@ -4,7 +4,7 @@ error: function is never used: `dead_fn` LL | fn dead_fn() {} | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-dead-code-2.rs:2:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr index 569196fffdd50..aab25c481e6c7 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr @@ -4,7 +4,7 @@ error: struct is never constructed: `Foo` LL | struct Foo; | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-dead-code-3.rs:3:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr index cc00fa4e42afd..3905d1a06bdfe 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr @@ -4,7 +4,7 @@ error: field is never read: `b` LL | b: bool, | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-dead-code-4.rs:3:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr index 9670d8e7a32e3..c0de469102077 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr @@ -4,7 +4,7 @@ error: variant is never constructed: `Variant2` LL | Variant2 | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-dead-code-5.rs:2:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/newline-span.stderr b/src/test/ui/lint/dead-code/newline-span.stderr index c5d0d60506744..fd74405f2b648 100644 --- a/src/test/ui/lint/dead-code/newline-span.stderr +++ b/src/test/ui/lint/dead-code/newline-span.stderr @@ -4,7 +4,7 @@ error: function is never used: `unused` LL | fn unused() { | ^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/newline-span.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr index 82df23bd9448b..b2acd5d4213b3 100644 --- a/src/test/ui/lint/dead-code/type-alias.stderr +++ b/src/test/ui/lint/dead-code/type-alias.stderr @@ -4,7 +4,7 @@ error: type alias is never used: `Unused` LL | type Unused = u8; | ^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/type-alias.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr index 142c2ccb99b05..9f368fdd2f816 100644 --- a/src/test/ui/lint/dead-code/unused-enum.stderr +++ b/src/test/ui/lint/dead-code/unused-enum.stderr @@ -4,7 +4,7 @@ error: struct is never constructed: `F` LL | struct F; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-enum.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/lint/dead-code/unused-struct-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr index 0037592e3de06..b93d6d4ac1866 100644 --- a/src/test/ui/lint/dead-code/unused-struct-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr @@ -4,7 +4,7 @@ error: variant is never constructed: `Bar` LL | Bar(B), | ^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-struct-variant.rs:1:9 | LL | #![deny(unused)] diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr index 2167b9d910d94..a547f5af4b082 100644 --- a/src/test/ui/lint/dead-code/unused-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-variant.stderr @@ -4,7 +4,7 @@ error: variant is never constructed: `Variant1` LL | Variant1, | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-variant.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/dead-code/with-core-crate.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr index 0b6ab67d9bfa5..2c63e60d67609 100644 --- a/src/test/ui/lint/dead-code/with-core-crate.stderr +++ b/src/test/ui/lint/dead-code/with-core-crate.stderr @@ -4,7 +4,7 @@ error: function is never used: `foo` LL | fn foo() { | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/with-core-crate.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr index 7ad92a4bc5e90..f5768626136e0 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr @@ -4,7 +4,7 @@ warning: `...` range patterns are deprecated LL | 1...2 => {} | ^^^ help: use `..=` for an inclusive range | -note: lint level defined here +note: the lint level is defined here --> $DIR/inclusive-range-pattern-syntax.rs:4:9 | LL | #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr index 6c94f88f13948..5a999a4fa0db9 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr +++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr @@ -20,7 +20,7 @@ warning: `#[inline]` is ignored on constants LL | #[inline] | ^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/inline-trait-and-foreign-items.rs:4:9 | LL | #![warn(unused_attributes)] diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index 0e18abc03fac0..b07474bb48673 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -4,7 +4,7 @@ warning: unused variable: `i_think_continually` LL | let i_think_continually = 2; | ^^^^^^^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_i_think_continually` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) @@ -49,7 +49,7 @@ warning: value assigned to `hours_are_suns` is never read LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) @@ -107,7 +107,7 @@ LL | let mut mut_unused_var = 1; | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/issue-54180-unused-ref-field.stderr index 817d9a46e83a6..840ecc0ce09ee 100644 --- a/src/test/ui/lint/issue-54180-unused-ref-field.stderr +++ b/src/test/ui/lint/issue-54180-unused-ref-field.stderr @@ -6,7 +6,7 @@ LL | E::Variant { ref field } => (), | | | help: try ignoring the field: `field: _` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-54180-unused-ref-field.rs:3:9 | LL | #![deny(unused)] diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr index 675dd4f07def6..b6d532c31017c 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr @@ -12,7 +12,7 @@ error: unnecessary parentheses around pattern LL | let (a) = 0; | ^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-54538-unused-parens-lint.rs:9:9 | LL | #![deny(unused_parens)] diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr index 68956f21e8f1b..09dc3640f99a6 100644 --- a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr @@ -4,7 +4,7 @@ error: structure field `lowerCamelCaseName` should have a snake case name LL | lowerCamelCaseName: bool, | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-attr-non-item-node.stderr b/src/test/ui/lint/lint-attr-non-item-node.stderr index 0d428c256e7bc..5835791409660 100644 --- a/src/test/ui/lint/lint-attr-non-item-node.stderr +++ b/src/test/ui/lint/lint-attr-non-item-node.stderr @@ -6,7 +6,7 @@ LL | break; LL | "unreachable"; | ^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-attr-non-item-node.rs:4:12 | LL | #[deny(unreachable_code)] diff --git a/src/test/ui/lint/lint-change-warnings.stderr b/src/test/ui/lint/lint-change-warnings.stderr index 336cb7ea84f0c..0926dada05d5a 100644 --- a/src/test/ui/lint/lint-change-warnings.stderr +++ b/src/test/ui/lint/lint-change-warnings.stderr @@ -4,7 +4,7 @@ error: denote infinite loops with `loop { ... }` LL | while true {} | ^^^^^^^^^^ help: use `loop` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-change-warnings.rs:1:9 | LL | #![deny(warnings)] @@ -25,7 +25,7 @@ error: denote infinite loops with `loop { ... }` LL | while true {} | ^^^^^^^^^^ help: use `loop` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-change-warnings.rs:18:10 | LL | #[forbid(warnings)] diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr index 81939e6ee206c..297ac2237a53f 100644 --- a/src/test/ui/lint/lint-ctypes-enum.stderr +++ b/src/test/ui/lint/lint-ctypes-enum.stderr @@ -4,14 +4,14 @@ error: `extern` block uses type `U`, which is not FFI-safe LL | fn uf(x: U); | ^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-ctypes-enum.rs:3:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes-enum.rs:9:1 | LL | enum U { A } @@ -25,7 +25,7 @@ LL | fn bf(x: B); | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes-enum.rs:10:1 | LL | enum B { C, D } @@ -39,7 +39,7 @@ LL | fn tf(x: T); | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes-enum.rs:11:1 | LL | enum T { E, F, G } diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr index e6bb49afb880f..9821f858d9caf 100644 --- a/src/test/ui/lint/lint-ctypes.stderr +++ b/src/test/ui/lint/lint-ctypes.stderr @@ -4,14 +4,14 @@ error: `extern` block uses type `Foo`, which is not FFI-safe LL | pub fn ptr_type1(size: *const Foo); | ^^^^^^^^^^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-ctypes.rs:4:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes.rs:24:1 | LL | pub struct Foo; @@ -25,7 +25,7 @@ LL | pub fn ptr_type2(size: *const Foo); | = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes.rs:24:1 | LL | pub struct Foo; @@ -117,7 +117,7 @@ LL | pub fn zero_size(p: ZeroSize); | = help: consider adding a member to this struct = note: this struct has no fields -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes.rs:20:1 | LL | pub struct ZeroSize; @@ -130,7 +130,7 @@ LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: composed only of `PhantomData` -note: type defined here +note: the type is defined here --> $DIR/lint-ctypes.rs:43:1 | LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData); diff --git a/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr b/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr index 020591ccff74d..ccb139e0ed615 100644 --- a/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr +++ b/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr @@ -4,7 +4,7 @@ error: unused import: `a::x` LL | use a::x; | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-directives-on-use-items-issue-10534.rs:1:9 | LL | #![deny(unused_imports)] @@ -16,7 +16,7 @@ error: unused import: `a::y` LL | use a::y; | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-directives-on-use-items-issue-10534.rs:20:12 | LL | #[deny(unused_imports)] diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.stderr index 203cb741539d6..658577213b3cd 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.stderr @@ -4,7 +4,7 @@ error: attempt to shift left with overflow LL | let n = 1u8 << 8; | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-exceeding-bitshifts.rs:4:9 | LL | #![deny(exceeding_bitshifts, const_err)] diff --git a/src/test/ui/lint/lint-exceeding-bitshifts2.stderr b/src/test/ui/lint/lint-exceeding-bitshifts2.stderr index 49ac54ab8345b..ac9f3b1e56bc3 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts2.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts2.stderr @@ -4,7 +4,7 @@ error: attempt to shift left with overflow LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-exceeding-bitshifts2.rs:4:9 | LL | #![deny(exceeding_bitshifts, const_err)] diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr index 59dab119682c1..e31c003985ed8 100644 --- a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr +++ b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr @@ -4,7 +4,7 @@ error: `allow_internal_unsafe` allows defining macros using unsafe without trigg LL | #[allow_internal_unsafe] | ^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-forbid-internal-unsafe.rs:1:11 | LL | #![forbid(unsafe_code)] diff --git a/src/test/ui/lint/lint-group-nonstandard-style.stderr b/src/test/ui/lint/lint-group-nonstandard-style.stderr index 1cc973d32c2d3..4ba49bf1ba7f5 100644 --- a/src/test/ui/lint/lint-group-nonstandard-style.stderr +++ b/src/test/ui/lint/lint-group-nonstandard-style.stderr @@ -4,7 +4,7 @@ warning: type `snake_case` should have an upper camel case name LL | struct snake_case; | ^^^^^^^^^^ help: convert the identifier to upper camel case: `SnakeCase` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group-nonstandard-style.rs:18:17 | LL | #![warn(nonstandard_style)] @@ -17,7 +17,7 @@ error: function `CamelCase` should have a snake case name LL | fn CamelCase() {} | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group-nonstandard-style.rs:1:9 | LL | #![deny(nonstandard_style)] @@ -30,7 +30,7 @@ error: function `CamelCase` should have a snake case name LL | fn CamelCase() {} | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group-nonstandard-style.rs:10:14 | LL | #[forbid(nonstandard_style)] @@ -43,7 +43,7 @@ error: static variable `bad` should have an upper case name LL | static bad: isize = 1; | ^^^ help: convert the identifier to upper case: `BAD` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group-nonstandard-style.rs:10:14 | LL | #[forbid(nonstandard_style)] @@ -56,7 +56,7 @@ warning: function `CamelCase` should have a snake case name LL | fn CamelCase() {} | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-group-nonstandard-style.rs:18:17 | LL | #![warn(nonstandard_style)] diff --git a/src/test/ui/lint/lint-impl-fn.stderr b/src/test/ui/lint/lint-impl-fn.stderr index 2c9a264287c96..24ec9c7e4f3bf 100644 --- a/src/test/ui/lint/lint-impl-fn.stderr +++ b/src/test/ui/lint/lint-impl-fn.stderr @@ -4,7 +4,7 @@ error: denote infinite loops with `loop { ... }` LL | fn bar(&self) { while true {} } | ^^^^^^^^^^ help: use `loop` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-impl-fn.rs:9:12 | LL | #[deny(while_true)] @@ -16,7 +16,7 @@ error: denote infinite loops with `loop { ... }` LL | fn foo(&self) { while true {} } | ^^^^^^^^^^ help: use `loop` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-impl-fn.rs:13:8 | LL | #[deny(while_true)] @@ -28,7 +28,7 @@ error: denote infinite loops with `loop { ... }` LL | while true {} | ^^^^^^^^^^ help: use `loop` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-impl-fn.rs:25:8 | LL | #[deny(while_true)] diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr index d95510ccd2d25..8780fac05b1eb 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr @@ -4,7 +4,7 @@ error: constant in pattern `a` should have an upper case name LL | (0, a) => 0, | ^ help: convert the identifier to upper case: `A` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-lowercase-static-const-pattern.rs:4:9 | LL | #![deny(non_upper_case_globals)] diff --git a/src/test/ui/lint/lint-match-arms.rs b/src/test/ui/lint/lint-match-arms.rs index 2c471a61054b2..5c2ccc60e1f4c 100644 --- a/src/test/ui/lint/lint-match-arms.rs +++ b/src/test/ui/lint/lint-match-arms.rs @@ -1,7 +1,7 @@ fn deny_on_arm() { match 0 { #[deny(unused_variables)] - //~^ NOTE lint level defined here + //~^ NOTE the lint level is defined here y => (), //~^ ERROR unused variable } diff --git a/src/test/ui/lint/lint-match-arms.stderr b/src/test/ui/lint/lint-match-arms.stderr index e4e3adab0a9b2..b124971f90512 100644 --- a/src/test/ui/lint/lint-match-arms.stderr +++ b/src/test/ui/lint/lint-match-arms.stderr @@ -4,7 +4,7 @@ error: unused variable: `y` LL | y => (), | ^ help: consider prefixing with an underscore: `_y` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-match-arms.rs:3:16 | LL | #[deny(unused_variables)] diff --git a/src/test/ui/lint/lint-misplaced-attr.stderr b/src/test/ui/lint/lint-misplaced-attr.stderr index cd4a89f91c4cc..3a7ca2f83aeba 100644 --- a/src/test/ui/lint/lint-misplaced-attr.stderr +++ b/src/test/ui/lint/lint-misplaced-attr.stderr @@ -4,7 +4,7 @@ error: unused attribute LL | #![crate_type = "bin"] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-misplaced-attr.rs:4:9 | LL | #![deny(unused_attributes)] diff --git a/src/test/ui/lint/lint-missing-copy-implementations.stderr b/src/test/ui/lint/lint-missing-copy-implementations.stderr index 7b6674e71bf19..e5f5ce20d1c90 100644 --- a/src/test/ui/lint/lint-missing-copy-implementations.stderr +++ b/src/test/ui/lint/lint-missing-copy-implementations.stderr @@ -6,7 +6,7 @@ LL | | pub field: i32 LL | | } | |_____^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-missing-copy-implementations.rs:3:9 | LL | #![deny(missing_copy_implementations)] diff --git a/src/test/ui/lint/lint-missing-doc.stderr b/src/test/ui/lint/lint-missing-doc.stderr index 3532c9315d8dc..a18a97e5f7fb5 100644 --- a/src/test/ui/lint/lint-missing-doc.stderr +++ b/src/test/ui/lint/lint-missing-doc.stderr @@ -4,7 +4,7 @@ error: missing documentation for a type alias LL | pub type PubTypedef = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-missing-doc.rs:3:9 | LL | #![deny(missing_docs)] diff --git a/src/test/ui/lint/lint-non-camel-case-types.stderr b/src/test/ui/lint/lint-non-camel-case-types.stderr index f82eefed4368a..875380b5dabc6 100644 --- a/src/test/ui/lint/lint-non-camel-case-types.stderr +++ b/src/test/ui/lint/lint-non-camel-case-types.stderr @@ -4,7 +4,7 @@ error: type `ONE_TWO_THREE` should have an upper camel case name LL | struct ONE_TWO_THREE; | ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OneTwoThree` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-camel-case-types.rs:1:11 | LL | #![forbid(non_camel_case_types)] diff --git a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr index f3303191a06fe..e295112932770 100644 --- a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr +++ b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr @@ -1,6 +1,6 @@ error: crate `NonSnakeCase` should have a snake case name | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-snake-case-crate-2.rs:4:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-non-snake-case-crate.stderr b/src/test/ui/lint/lint-non-snake-case-crate.stderr index 5cfd60a76e437..da6b89c1e0499 100644 --- a/src/test/ui/lint/lint-non-snake-case-crate.stderr +++ b/src/test/ui/lint/lint-non-snake-case-crate.stderr @@ -4,7 +4,7 @@ error: crate `NonSnakeCase` should have a snake case name LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-snake-case-crate.rs:3:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-non-snake-case-functions.stderr b/src/test/ui/lint/lint-non-snake-case-functions.stderr index c5eca89debb82..f6ac6b99b602f 100644 --- a/src/test/ui/lint/lint-non-snake-case-functions.stderr +++ b/src/test/ui/lint/lint-non-snake-case-functions.stderr @@ -4,7 +4,7 @@ error: method `Foo_Method` should have a snake case name LL | fn Foo_Method() {} | ^^^^^^^^^^ help: convert the identifier to snake case: `foo_method` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-snake-case-functions.rs:1:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-non-snake-case-lifetimes.stderr b/src/test/ui/lint/lint-non-snake-case-lifetimes.stderr index d638626495ace..d4fe26a43c2e9 100644 --- a/src/test/ui/lint/lint-non-snake-case-lifetimes.stderr +++ b/src/test/ui/lint/lint-non-snake-case-lifetimes.stderr @@ -4,7 +4,7 @@ error: lifetime `'FooBar` should have a snake case name LL | fn f<'FooBar>( | ^^^^^^^ help: convert the identifier to snake case: `'foo_bar` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-snake-case-lifetimes.rs:1:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-non-snake-case-modules.stderr b/src/test/ui/lint/lint-non-snake-case-modules.stderr index 847c43e1b04e4..c8b997c870704 100644 --- a/src/test/ui/lint/lint-non-snake-case-modules.stderr +++ b/src/test/ui/lint/lint-non-snake-case-modules.stderr @@ -4,7 +4,7 @@ error: module `FooBar` should have a snake case name LL | mod FooBar { | ^^^^^^ help: convert the identifier to snake case: `foo_bar` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-snake-case-modules.rs:1:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr index 2185d5a0ab48f..411ff51aad748 100644 --- a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr +++ b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr @@ -4,7 +4,7 @@ error: associated constant `not_upper` should have an upper case name LL | const not_upper: bool = true; | ^^^^^^^^^ help: convert the identifier to upper case: `NOT_UPPER` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-uppercase-associated-const.rs:1:9 | LL | #![deny(non_upper_case_globals)] diff --git a/src/test/ui/lint/lint-non-uppercase-statics.stderr b/src/test/ui/lint/lint-non-uppercase-statics.stderr index ceb83d08f2777..c6fd0a6e0ddf8 100644 --- a/src/test/ui/lint/lint-non-uppercase-statics.stderr +++ b/src/test/ui/lint/lint-non-uppercase-statics.stderr @@ -4,7 +4,7 @@ error: static variable `foo` should have an upper case name LL | static foo: isize = 1; | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-uppercase-statics.rs:1:11 | LL | #![forbid(non_upper_case_globals)] diff --git a/src/test/ui/lint/lint-owned-heap-memory.stderr b/src/test/ui/lint/lint-owned-heap-memory.stderr index c61b3d31558cb..2c6b47e494a52 100644 --- a/src/test/ui/lint/lint-owned-heap-memory.stderr +++ b/src/test/ui/lint/lint-owned-heap-memory.stderr @@ -4,7 +4,7 @@ error: type uses owned (Box type) pointers: std::boxed::Box LL | x: Box | ^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-owned-heap-memory.rs:2:11 | LL | #![forbid(box_pointers)] diff --git a/src/test/ui/lint/lint-qualification.stderr b/src/test/ui/lint/lint-qualification.stderr index 125aeb3db0366..149a782d97c2e 100644 --- a/src/test/ui/lint/lint-qualification.stderr +++ b/src/test/ui/lint/lint-qualification.stderr @@ -4,7 +4,7 @@ error: unnecessary qualification LL | foo::bar(); | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-qualification.rs:1:9 | LL | #![deny(unused_qualifications)] diff --git a/src/test/ui/lint/lint-range-endpoint-overflow.stderr b/src/test/ui/lint/lint-range-endpoint-overflow.stderr index 939451d6bc022..dff61e022ebb8 100644 --- a/src/test/ui/lint/lint-range-endpoint-overflow.stderr +++ b/src/test/ui/lint/lint-range-endpoint-overflow.stderr @@ -4,7 +4,7 @@ error: range endpoint is out of range for `u8` LL | let range_a = 0..256; | ^^^^^^ help: use an inclusive range instead: `0..=255` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-range-endpoint-overflow.rs:1:9 | LL | #![deny(overflowing_literals)] diff --git a/src/test/ui/lint/lint-removed-allow.stderr b/src/test/ui/lint/lint-removed-allow.stderr index 32af7389b6c7e..5ab95c89b9c7e 100644 --- a/src/test/ui/lint/lint-removed-allow.stderr +++ b/src/test/ui/lint/lint-removed-allow.stderr @@ -4,7 +4,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-removed-allow.rs:7:8 | LL | #[deny(unused_variables)] diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr index b4ab5f5ee62dd..a9ebd3e32712c 100644 --- a/src/test/ui/lint/lint-removed-cmdline.stderr +++ b/src/test/ui/lint/lint-removed-cmdline.stderr @@ -20,7 +20,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-removed-cmdline.rs:11:8 | LL | #[deny(warnings)] diff --git a/src/test/ui/lint/lint-removed.stderr b/src/test/ui/lint/lint-removed.stderr index 060ba31bced9a..2c043392f098c 100644 --- a/src/test/ui/lint/lint-removed.stderr +++ b/src/test/ui/lint/lint-removed.stderr @@ -12,7 +12,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-removed.rs:7:8 | LL | #[deny(unused_variables)] diff --git a/src/test/ui/lint/lint-renamed-allow.stderr b/src/test/ui/lint/lint-renamed-allow.stderr index 1d984cb8287ff..9da74f61b7569 100644 --- a/src/test/ui/lint/lint-renamed-allow.stderr +++ b/src/test/ui/lint/lint-renamed-allow.stderr @@ -4,7 +4,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-renamed-allow.rs:7:8 | LL | #[deny(unused)] diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr index 6401d9b77e007..235215598a2bd 100644 --- a/src/test/ui/lint/lint-renamed-cmdline.stderr +++ b/src/test/ui/lint/lint-renamed-cmdline.stderr @@ -20,7 +20,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-renamed-cmdline.rs:7:8 | LL | #[deny(unused)] diff --git a/src/test/ui/lint/lint-renamed.stderr b/src/test/ui/lint/lint-renamed.stderr index ba8eadf23aca5..dc43f2e4c46da 100644 --- a/src/test/ui/lint/lint-renamed.stderr +++ b/src/test/ui/lint/lint-renamed.stderr @@ -12,7 +12,7 @@ error: unused variable: `unused` LL | fn main() { let unused = (); } | ^^^^^^ help: consider prefixing with an underscore: `_unused` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-renamed.rs:3:8 | LL | #[deny(unused)] diff --git a/src/test/ui/lint/lint-shorthand-field.stderr b/src/test/ui/lint/lint-shorthand-field.stderr index 5c9b21ffdc7b7..2d1ca30f991ae 100644 --- a/src/test/ui/lint/lint-shorthand-field.stderr +++ b/src/test/ui/lint/lint-shorthand-field.stderr @@ -4,7 +4,7 @@ error: the `x:` in this pattern is redundant LL | x: x, | ^^^^ help: use shorthand field pattern: `x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-shorthand-field.rs:4:9 | LL | #![deny(non_shorthand_field_patterns)] diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 650373c90bcf2..734c6093e2b62 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -4,7 +4,7 @@ warning: use of deprecated item 'lint_stability::deprecated': text LL | deprecated(); | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-stability-deprecated.rs:7:9 | LL | #![warn(deprecated)] diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.stderr b/src/test/ui/lint/lint-stability-fields-deprecated.stderr index 488be75ae52b0..5210fb690e9d7 100644 --- a/src/test/ui/lint/lint-stability-fields-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-fields-deprecated.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': LL | let x = Deprecated { | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-stability-fields-deprecated.rs:3:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr index 6599da564f52b..5bac22594d665 100644 --- a/src/test/ui/lint/lint-stability2.stderr +++ b/src/test/ui/lint/lint-stability2.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'lint_stability::deprecated': text LL | macro_test!(); | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-stability2.rs:4:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr index 84274e6406972..566734743caba 100644 --- a/src/test/ui/lint/lint-stability3.stderr +++ b/src/test/ui/lint/lint-stability3.stderr @@ -4,7 +4,7 @@ error: use of deprecated item 'lint_stability::deprecated_text': text LL | macro_test_arg_nested!(deprecated_text); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-stability3.rs:4:9 | LL | #![deny(deprecated)] diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr index 0b3d292856707..bf510823b568f 100644 --- a/src/test/ui/lint/lint-type-limits2.stderr +++ b/src/test/ui/lint/lint-type-limits2.stderr @@ -12,7 +12,7 @@ warning: literal out of range for `i8` LL | 128 > bar() | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-type-limits2.rs:2:9 | LL | #![warn(overflowing_literals)] diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr index 70cd9c859ecf3..00441f99e60d9 100644 --- a/src/test/ui/lint/lint-type-limits3.stderr +++ b/src/test/ui/lint/lint-type-limits3.stderr @@ -12,7 +12,7 @@ warning: literal out of range for `i8` LL | while 200 != i { | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-type-limits3.rs:2:9 | LL | #![warn(overflowing_literals)] diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr index 6fcd9b58b2dc7..ec15313158d5b 100644 --- a/src/test/ui/lint/lint-type-overflow.stderr +++ b/src/test/ui/lint/lint-type-overflow.stderr @@ -4,7 +4,7 @@ error: literal out of range for `u8` LL | let x1: u8 = 256; | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-type-overflow.rs:1:9 | LL | #![deny(overflowing_literals)] diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index 761b095464fe8..dfc691ab91043 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -4,7 +4,7 @@ error: literal out of range for `i8` LL | let x2: i8 = --128; | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-type-overflow2.rs:3:9 | LL | #![deny(overflowing_literals)] diff --git a/src/test/ui/lint/lint-unconditional-recursion.stderr b/src/test/ui/lint/lint-unconditional-recursion.stderr index 5d2e8201b142d..1770d71e2e2fe 100644 --- a/src/test/ui/lint/lint-unconditional-recursion.stderr +++ b/src/test/ui/lint/lint-unconditional-recursion.stderr @@ -6,7 +6,7 @@ LL | fn foo() { LL | foo(); | ----- recursive call site | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unconditional-recursion.rs:1:9 | LL | #![deny(unconditional_recursion)] diff --git a/src/test/ui/lint/lint-unknown-lint.stderr b/src/test/ui/lint/lint-unknown-lint.stderr index b3ba6e31bc1ea..3a102769e855b 100644 --- a/src/test/ui/lint/lint-unknown-lint.stderr +++ b/src/test/ui/lint/lint-unknown-lint.stderr @@ -4,7 +4,7 @@ error: unknown lint: `not_a_real_lint` LL | #![allow(not_a_real_lint)] | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unknown-lint.rs:1:9 | LL | #![deny(unknown_lints)] diff --git a/src/test/ui/lint/lint-unnecessary-import-braces.stderr b/src/test/ui/lint/lint-unnecessary-import-braces.stderr index 41e274bc54508..2d289404ded74 100644 --- a/src/test/ui/lint/lint-unnecessary-import-braces.stderr +++ b/src/test/ui/lint/lint-unnecessary-import-braces.stderr @@ -4,7 +4,7 @@ error: braces around A is unnecessary LL | use test::{A}; | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unnecessary-import-braces.rs:1:9 | LL | #![deny(unused_import_braces)] diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr index ea58220d20c9f..3663f1d98bb9c 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.stderr +++ b/src/test/ui/lint/lint-unnecessary-parens.stderr @@ -4,7 +4,7 @@ error: unnecessary parentheses around `return` value LL | return (1); | ^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unnecessary-parens.rs:1:9 | LL | #![deny(unused_parens)] diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index 96ad0c33691db..8e56fd4139b1f 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -4,7 +4,7 @@ error: declaration of an `unsafe` function LL | unsafe fn baz() {} | ^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unsafe-code.rs:3:9 | LL | #![deny(unsafe_code)] diff --git a/src/test/ui/lint/lint-unused-extern-crate.stderr b/src/test/ui/lint/lint-unused-extern-crate.stderr index aa4a8dad24c94..46d8f3beeab42 100644 --- a/src/test/ui/lint/lint-unused-extern-crate.stderr +++ b/src/test/ui/lint/lint-unused-extern-crate.stderr @@ -4,7 +4,7 @@ error: unused extern crate LL | extern crate lint_unused_extern_crate5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-extern-crate.rs:7:9 | LL | #![deny(unused_extern_crates)] diff --git a/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/lint-unused-imports.stderr index 96d71a228a5f2..0574ca4569fbf 100644 --- a/src/test/ui/lint/lint-unused-imports.stderr +++ b/src/test/ui/lint/lint-unused-imports.stderr @@ -4,7 +4,7 @@ error: unused import: `std::fmt::{}` LL | use std::fmt::{}; | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-imports.rs:1:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/lint/lint-unused-mut-self.stderr b/src/test/ui/lint/lint-unused-mut-self.stderr index b5f6b717dc39c..16ad4758b92b8 100644 --- a/src/test/ui/lint/lint-unused-mut-self.stderr +++ b/src/test/ui/lint/lint-unused-mut-self.stderr @@ -6,7 +6,7 @@ LL | fn foo(mut self) {} | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-mut-self.rs:4:9 | LL | #![deny(unused_mut)] diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/lint-unused-mut-variables.stderr index c1ab0ab33d4cc..eda078da9a0ea 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.stderr +++ b/src/test/ui/lint/lint-unused-mut-variables.stderr @@ -6,7 +6,7 @@ LL | mut a: i32, | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-mut-variables.rs:5:9 | LL | #![deny(unused_mut)] @@ -212,7 +212,7 @@ LL | let mut b = vec![2]; | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-mut-variables.rs:198:8 | LL | #[deny(unused_mut)] diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/lint-unused-variables.stderr index f8419bf506660..57389f8d12010 100644 --- a/src/test/ui/lint/lint-unused-variables.stderr +++ b/src/test/ui/lint/lint-unused-variables.stderr @@ -4,7 +4,7 @@ error: unused variable: `a` LL | a: i32, | ^ help: consider prefixing with an underscore: `_a` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-variables.rs:5:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index a38f3e7626bca..7c2497758d955 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -24,7 +24,7 @@ warning: unused variable: `Foo` LL | Foo => {} | ^^^ help: consider prefixing with an underscore: `_Foo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-uppercase-variables.rs:1:9 | LL | #![warn(unused)] @@ -49,7 +49,7 @@ error: structure field `X` should have a snake case name LL | X: usize | ^ help: convert the identifier to snake case (notice the capitalization): `x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-uppercase-variables.rs:3:9 | LL | #![deny(non_snake_case)] diff --git a/src/test/ui/lint/lints-in-foreign-macros.stderr b/src/test/ui/lint/lints-in-foreign-macros.stderr index 3fc3c2281f2e3..0d2adb2ad0492 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.stderr +++ b/src/test/ui/lint/lints-in-foreign-macros.stderr @@ -7,7 +7,7 @@ LL | () => {use std::string::ToString;} LL | mod a { foo!(); } | ------- in this macro invocation | -note: lint level defined here +note: the lint level is defined here --> $DIR/lints-in-foreign-macros.rs:4:9 | LL | #![warn(unused_imports)] @@ -37,7 +37,7 @@ LL | | LL | | fn main() {} | |____________^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lints-in-foreign-macros.rs:5:9 | LL | #![warn(missing_docs)] diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr index febb4c193efee..4490d4afbd605 100644 --- a/src/test/ui/lint/must-use-ops.stderr +++ b/src/test/ui/lint/must-use-ops.stderr @@ -4,7 +4,7 @@ warning: unused comparison that must be used LL | val == 1; | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/must-use-ops.rs:5:9 | LL | #![warn(unused_must_use)] diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/must_use-array.stderr index a6dbd8e93d4d3..c42223b519851 100644 --- a/src/test/ui/lint/must_use-array.stderr +++ b/src/test/ui/lint/must_use-array.stderr @@ -4,7 +4,7 @@ error: unused array of `S` that must be used LL | singleton(); | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/must_use-array.rs:1:9 | LL | #![deny(unused_must_use)] diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr index be74362e29d62..11555d80825a4 100644 --- a/src/test/ui/lint/must_use-trait.stderr +++ b/src/test/ui/lint/must_use-trait.stderr @@ -4,7 +4,7 @@ error: unused implementer of `Critical` that must be used LL | get_critical(); | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/must_use-trait.rs:1:9 | LL | #![deny(unused_must_use)] diff --git a/src/test/ui/lint/must_use-tuple.stderr b/src/test/ui/lint/must_use-tuple.stderr index 45d2a439e52b0..de3c6f46c6867 100644 --- a/src/test/ui/lint/must_use-tuple.stderr +++ b/src/test/ui/lint/must_use-tuple.stderr @@ -4,7 +4,7 @@ error: unused `std::result::Result` in tuple element 0 that must be used LL | (Ok::<(), ()>(()),); | ^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/must_use-tuple.rs:1:9 | LL | #![deny(unused_must_use)] diff --git a/src/test/ui/lint/must_use-unit.stderr b/src/test/ui/lint/must_use-unit.stderr index 0a9939b2015b7..7f25a19350862 100644 --- a/src/test/ui/lint/must_use-unit.stderr +++ b/src/test/ui/lint/must_use-unit.stderr @@ -4,7 +4,7 @@ error: unused return value of `foo` that must be used LL | foo(); | ^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/must_use-unit.rs:2:9 | LL | #![deny(unused_must_use)] diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 136d564d1ab3d..712095e3208bd 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -4,7 +4,7 @@ error: `extern` block uses type `A`, which is not FFI-safe LL | pub fn a(_: A); | ^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/opaque-ty-ffi-unsafe.rs:3:9 | LL | #![deny(improper_ctypes)] diff --git a/src/test/ui/lint/reasons.rs b/src/test/ui/lint/reasons.rs index fa9f012c9262c..c64c9cf098212 100644 --- a/src/test/ui/lint/reasons.rs +++ b/src/test/ui/lint/reasons.rs @@ -3,11 +3,11 @@ #![feature(lint_reasons)] #![warn(elided_lifetimes_in_paths, - //~^ NOTE lint level defined here + //~^ NOTE the lint level is defined here reason = "explicit anonymous lifetimes aid reasoning about ownership")] #![warn( nonstandard_style, - //~^ NOTE lint level defined here + //~^ NOTE the lint level is defined here reason = r#"people shouldn't have to change their usual style habits to contribute to our project"# )] diff --git a/src/test/ui/lint/reasons.stderr b/src/test/ui/lint/reasons.stderr index 139b3f13fd6b2..30bb8daf48a22 100644 --- a/src/test/ui/lint/reasons.stderr +++ b/src/test/ui/lint/reasons.stderr @@ -5,7 +5,7 @@ LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>` | = note: explicit anonymous lifetimes aid reasoning about ownership -note: lint level defined here +note: the lint level is defined here --> $DIR/reasons.rs:5:9 | LL | #![warn(elided_lifetimes_in_paths, @@ -19,7 +19,7 @@ LL | let Social_exchange_psychology = CheaterDetectionMechanism {}; | = note: people shouldn't have to change their usual style habits to contribute to our project -note: lint level defined here +note: the lint level is defined here --> $DIR/reasons.rs:9:5 | LL | nonstandard_style, diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr index 2160df51a8375..8c5ee58dc121d 100644 --- a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr @@ -5,7 +5,7 @@ error: unnecessary trailing semicolon LL | let tst = 123;; | ^ help: remove this semicolon | -note: lint level defined here +note: the lint level is defined here --> $DIR/redundant-semi-proc-macro.rs:3:9 | LL | #![deny(redundant_semicolon)] diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr index 56925846e956b..6c9f0866c017a 100644 --- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr @@ -4,7 +4,7 @@ error: identifier contains non-ASCII characters LL | const חלודה: usize = 2; | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-non-ascii-idents.rs:2:9 | LL | #![deny(non_ascii_idents)] diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr index 4580d25665ef9..b270bd1f051c2 100644 --- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr @@ -4,7 +4,7 @@ error: identifier contains uncommon Unicode codepoints LL | const µ: f64 = 0.000001; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-uncommon-codepoints.rs:2:9 | LL | #![deny(uncommon_codepoints)] diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index e42ee0fa6401c..4e218ed0f1a92 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -12,7 +12,7 @@ warning: unnecessary parentheses around assigned value LL | let mut registry_no = (format!("NX-{}", 74205)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/suggestions.rs:3:21 | LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896 @@ -34,7 +34,7 @@ LL | let mut registry_no = (format!("NX-{}", 74205)); | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/suggestions.rs:3:9 | LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896 diff --git a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr index c1a4b393cd6ed..f7c42acb34419 100644 --- a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr +++ b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr @@ -4,7 +4,7 @@ error: trivial numeric cast: `i32` as `i32` LL | let lugubrious = 12i32 as i32; | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial-casts-featuring-type-ascription.rs:1:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] @@ -17,7 +17,7 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = haunted as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial-casts-featuring-type-ascription.rs:1:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] diff --git a/src/test/ui/lint/trivial-casts.stderr b/src/test/ui/lint/trivial-casts.stderr index f411db1ab0e5a..1544f553cee4c 100644 --- a/src/test/ui/lint/trivial-casts.stderr +++ b/src/test/ui/lint/trivial-casts.stderr @@ -4,7 +4,7 @@ error: trivial numeric cast: `i32` as `i32` LL | let lugubrious = 12i32 as i32; | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial-casts.rs:1:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] @@ -17,7 +17,7 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = haunted as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial-casts.rs:1:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index dabfb876fbb92..2432eb78b8732 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -4,7 +4,7 @@ warning: literal out of range for `i8` LL | let error = 255i8; | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/type-overflow.rs:2:9 | LL | #![warn(overflowing_literals)] diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index 169e77c8fa05d..6d669184deb3e 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -7,7 +7,7 @@ LL | let _val: &'static T = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: lint level defined here +note: the lint level is defined here --> $DIR/uninitialized-zeroed.rs:7:9 | LL | #![deny(invalid_value)] diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr index da21c2ac4ab87..abe07b1c6496c 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr +++ b/src/test/ui/lint/unreachable_pub-pub_crate.stderr @@ -6,7 +6,7 @@ LL | pub use std::fmt; | | | help: consider restricting its visibility: `pub(crate)` | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable_pub-pub_crate.rs:10:9 | LL | #![warn(unreachable_pub)] diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr index 2cb27a770edcd..6144d5bb6577c 100644 --- a/src/test/ui/lint/unreachable_pub.stderr +++ b/src/test/ui/lint/unreachable_pub.stderr @@ -6,7 +6,7 @@ LL | pub use std::fmt; | | | help: consider restricting its visibility: `crate` | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable_pub.rs:6:9 | LL | #![warn(unreachable_pub)] diff --git a/src/test/ui/lint/unused_import_warning_issue_45268.stderr b/src/test/ui/lint/unused_import_warning_issue_45268.stderr index 7392e99f7aef3..1d6338572f31a 100644 --- a/src/test/ui/lint/unused_import_warning_issue_45268.stderr +++ b/src/test/ui/lint/unused_import_warning_issue_45268.stderr @@ -4,7 +4,7 @@ warning: unused import: `test::Unused` LL | use test::Unused; // This is really unused, so warning is OK | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused_import_warning_issue_45268.rs:3:9 | LL | #![warn(unused_imports)] // Warning explanation here, it's OK diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr index 08f8548e0493d..809aad2468873 100644 --- a/src/test/ui/lint/unused_labels.stderr +++ b/src/test/ui/lint/unused_labels.stderr @@ -4,7 +4,7 @@ warning: unused label LL | 'unused_while_label: while 0 == 0 { | ^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused_labels.rs:8:9 | LL | #![warn(unused_labels)] diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index c503c100808db..09f0fc90032dc 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -4,7 +4,7 @@ LL | let _a = (1 / (2 + 3)); | ^^^^^^^^^^^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused_parens_json_suggestion.rs:10:9 | LL | #![deny(unused_parens)] diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr index 873f105435e08..c3bf77a3a6f2d 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -4,7 +4,7 @@ LL | if (_b) { | ^^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused_parens_remove_json_suggestion.rs:10:9 | LL | #![deny(unused_parens)] diff --git a/src/test/ui/lint/use-redundant.stderr b/src/test/ui/lint/use-redundant.stderr index fbd9f81f18f8a..85a5cce4dd071 100644 --- a/src/test/ui/lint/use-redundant.stderr +++ b/src/test/ui/lint/use-redundant.stderr @@ -4,7 +4,7 @@ warning: unused import: `m1::*` LL | use m1::*; | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/use-redundant.rs:2:9 | LL | #![warn(unused_imports)] diff --git a/src/test/ui/lint/warn-unused-inline-on-fn-prototypes.stderr b/src/test/ui/lint/warn-unused-inline-on-fn-prototypes.stderr index 006cc6c80a64e..843db8ce81502 100644 --- a/src/test/ui/lint/warn-unused-inline-on-fn-prototypes.stderr +++ b/src/test/ui/lint/warn-unused-inline-on-fn-prototypes.stderr @@ -4,7 +4,7 @@ error: `#[inline]` is ignored on function prototypes LL | #[inline] | ^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/warn-unused-inline-on-fn-prototypes.rs:1:9 | LL | #![deny(unused_attributes)] diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr index d054b1d497e5b..12680ab11568f 100644 --- a/src/test/ui/liveness/liveness-dead.stderr +++ b/src/test/ui/liveness/liveness-dead.stderr @@ -4,7 +4,7 @@ error: value assigned to `x` is never read LL | let mut x: isize = 3; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/liveness-dead.rs:2:9 | LL | #![deny(unused_assignments)] diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index 6ea20081e5018..7adb6a3295b0e 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -6,7 +6,7 @@ LL | continue; LL | drop(*x as i32); | ^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/liveness-unused.rs:1:9 | LL | #![warn(unused)] @@ -19,7 +19,7 @@ error: unused variable: `x` LL | fn f1(x: isize) { | ^ help: consider prefixing with an underscore: `_x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/liveness-unused.rs:2:9 | LL | #![deny(unused_variables)] @@ -57,7 +57,7 @@ error: value assigned to `x` is never read LL | x += 4; | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/liveness-unused.rs:3:9 | LL | #![deny(unused_assignments)] diff --git a/src/test/ui/macros/issue-61053-different-kleene.stderr b/src/test/ui/macros/issue-61053-different-kleene.stderr index 86474822a0c67..aa8bac13b61ab 100644 --- a/src/test/ui/macros/issue-61053-different-kleene.stderr +++ b/src/test/ui/macros/issue-61053-different-kleene.stderr @@ -4,7 +4,7 @@ error: meta-variable repeats with different Kleene operator LL | ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; | - expected repetition ^^ - conflicting repetition | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61053-different-kleene.rs:1:9 | LL | #![deny(meta_variable_misuse)] diff --git a/src/test/ui/macros/issue-61053-duplicate-binder.stderr b/src/test/ui/macros/issue-61053-duplicate-binder.stderr index fbd67b6c1e9c0..5a2af45d077c4 100644 --- a/src/test/ui/macros/issue-61053-duplicate-binder.stderr +++ b/src/test/ui/macros/issue-61053-duplicate-binder.stderr @@ -6,7 +6,7 @@ LL | ($x:tt $x:tt) => { $x }; | | | previous declaration | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61053-duplicate-binder.rs:1:9 | LL | #![deny(meta_variable_misuse)] diff --git a/src/test/ui/macros/issue-61053-missing-repetition.stderr b/src/test/ui/macros/issue-61053-missing-repetition.stderr index 6f89e276c169f..738f711f04e13 100644 --- a/src/test/ui/macros/issue-61053-missing-repetition.stderr +++ b/src/test/ui/macros/issue-61053-missing-repetition.stderr @@ -6,7 +6,7 @@ LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; | | | expected repetition | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61053-missing-repetition.rs:1:9 | LL | #![deny(meta_variable_misuse)] diff --git a/src/test/ui/macros/issue-61053-unbound.stderr b/src/test/ui/macros/issue-61053-unbound.stderr index 0fc0a7e283e92..0d64effc96752 100644 --- a/src/test/ui/macros/issue-61053-unbound.stderr +++ b/src/test/ui/macros/issue-61053-unbound.stderr @@ -4,7 +4,7 @@ error: unknown macro variable `k` LL | ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; | ^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61053-unbound.rs:1:9 | LL | #![deny(meta_variable_misuse)] diff --git a/src/test/ui/macros/macro-use-all-and-none.stderr b/src/test/ui/macros/macro-use-all-and-none.stderr index e7de7e7ad08c9..cbabf0672fa8d 100644 --- a/src/test/ui/macros/macro-use-all-and-none.stderr +++ b/src/test/ui/macros/macro-use-all-and-none.stderr @@ -4,7 +4,7 @@ warning: unused attribute LL | #[macro_use()] | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/macro-use-all-and-none.rs:4:9 | LL | #![warn(unused_attributes)] diff --git a/src/test/ui/match/match-no-arms-unreachable-after.stderr b/src/test/ui/match/match-no-arms-unreachable-after.stderr index 66e5c91ad2054..a0a3697266d4e 100644 --- a/src/test/ui/match/match-no-arms-unreachable-after.stderr +++ b/src/test/ui/match/match-no-arms-unreachable-after.stderr @@ -6,7 +6,7 @@ LL | match v { } LL | let x = 2; | ^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-no-arms-unreachable-after.rs:2:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr index b510a08ae3775..9e07d5ea31ea5 100644 --- a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr @@ -7,7 +7,7 @@ LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} LL | S.late::<'static>(&0, &0); | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/method-call-lifetime-args-lint-fail.rs:1:9 | LL | #![deny(late_bound_lifetime_arguments)] diff --git a/src/test/ui/methods/method-call-lifetime-args-lint.stderr b/src/test/ui/methods/method-call-lifetime-args-lint.stderr index eb1d4fe2e504e..f31f510a3a744 100644 --- a/src/test/ui/methods/method-call-lifetime-args-lint.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-lint.stderr @@ -7,7 +7,7 @@ LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} LL | S.late::<'static>(&0, &0); | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/method-call-lifetime-args-lint.rs:1:9 | LL | #![deny(late_bound_lifetime_arguments)] diff --git a/src/test/ui/missing_debug_impls.stderr b/src/test/ui/missing_debug_impls.stderr index b953058778791..5f8adb791f687 100644 --- a/src/test/ui/missing_debug_impls.stderr +++ b/src/test/ui/missing_debug_impls.stderr @@ -4,7 +4,7 @@ error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` LL | pub enum A {} | ^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/missing_debug_impls.rs:2:9 | LL | #![deny(missing_debug_implementations)] diff --git a/src/test/ui/never_type/never-assign-dead-code.stderr b/src/test/ui/never_type/never-assign-dead-code.stderr index 1860150fa8bc6..f0a11ae1bcc28 100644 --- a/src/test/ui/never_type/never-assign-dead-code.stderr +++ b/src/test/ui/never_type/never-assign-dead-code.stderr @@ -6,7 +6,7 @@ LL | let x: ! = panic!("aah"); LL | drop(x); | ^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/never-assign-dead-code.rs:6:9 | LL | #![warn(unused)] @@ -28,7 +28,7 @@ warning: unused variable: `x` LL | let x: ! = panic!("aah"); | ^ help: consider prefixing with an underscore: `_x` | -note: lint level defined here +note: the lint level is defined here --> $DIR/never-assign-dead-code.rs:6:9 | LL | #![warn(unused)] diff --git a/src/test/ui/nll/capture-mut-ref.stderr b/src/test/ui/nll/capture-mut-ref.stderr index 883b2d05a7f51..95d8e874a68d4 100644 --- a/src/test/ui/nll/capture-mut-ref.stderr +++ b/src/test/ui/nll/capture-mut-ref.stderr @@ -6,7 +6,7 @@ LL | let mut x = &mut 0; | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/capture-mut-ref.rs:4:9 | LL | #![deny(unused_mut)] diff --git a/src/test/ui/nll/issue-61424.stderr b/src/test/ui/nll/issue-61424.stderr index ae336b2fe1c03..41dd7254d75a3 100644 --- a/src/test/ui/nll/issue-61424.stderr +++ b/src/test/ui/nll/issue-61424.stderr @@ -6,7 +6,7 @@ LL | let mut x; | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61424.rs:1:9 | LL | #![deny(unused_mut)] diff --git a/src/test/ui/nll/unused-mut-issue-50343.stderr b/src/test/ui/nll/unused-mut-issue-50343.stderr index 261d678db6758..c86981a8dff15 100644 --- a/src/test/ui/nll/unused-mut-issue-50343.stderr +++ b/src/test/ui/nll/unused-mut-issue-50343.stderr @@ -6,7 +6,7 @@ LL | vec![(42, 22)].iter().map(|(mut x, _y)| ()).count(); | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-mut-issue-50343.rs:1:9 | LL | #![deny(unused_mut)] diff --git a/src/test/ui/no-patterns-in-args-2.stderr b/src/test/ui/no-patterns-in-args-2.stderr index ec7d2d9f0d114..905a89af4e587 100644 --- a/src/test/ui/no-patterns-in-args-2.stderr +++ b/src/test/ui/no-patterns-in-args-2.stderr @@ -10,7 +10,7 @@ error: patterns aren't allowed in methods without bodies LL | fn f1(mut arg: u8); | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/no-patterns-in-args-2.rs:1:9 | LL | #![deny(patterns_in_fns_without_body)] diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 87f69a484bbbc..7f7bb929a0d27 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | (1,) => {} | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/exhaustiveness-unreachable-pattern.rs:4:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.stderr b/src/test/ui/panic-handler/panic-handler-duplicate.stderr index 9999e3276469d..8603ef91beffd 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.stderr +++ b/src/test/ui/panic-handler/panic-handler-duplicate.stderr @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | -note: first defined here +note: the lang item is first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | LL | / fn panic(info: &PanicInfo) -> ! { diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index ac56513fd4706..f71c28e5aa641 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `panic_handler_std` depends on) + = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) error: argument should be `&PanicInfo` --> $DIR/panic-handler-std.rs:7:16 diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index f43f9bf301218..50bfbcec2475e 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -195,7 +195,7 @@ error: `...` range patterns are deprecated LL | if let 0...3 = 0 {} | ^^^ help: use `..=` for an inclusive range | -note: lint level defined here +note: the lint level is defined here --> $DIR/recover-range-pats.rs:8:9 | LL | #![deny(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr index caf9e8303ea37..62b3b507e1d26 100644 --- a/src/test/ui/path-lookahead.stderr +++ b/src/test/ui/path-lookahead.stderr @@ -4,7 +4,7 @@ warning: unnecessary parentheses around `return` value LL | return (::to_string(&arg)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses | -note: lint level defined here +note: the lint level is defined here --> $DIR/path-lookahead.rs:3:9 | LL | #![warn(unused_parens)] diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr index b32cf8cbb0efc..308a6c7c58e66 100644 --- a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr +++ b/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr @@ -4,7 +4,7 @@ error: irrefutable if-let pattern LL | if let _ = 5 {} | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/deny-irrefutable-let-patterns.rs:1:9 | LL | #![deny(irrefutable_let_patterns)] diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr index 0fbeb981ea015..5866df5cb1db8 100644 --- a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr +++ b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | 200 => {} | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/exhaustive_integer_patterns.rs:3:9 | LL | #![deny(unreachable_patterns)] @@ -88,7 +88,7 @@ LL | 0 .. 2 => {} LL | 1 ..= 2 => {} | ^^^^^^^ overlapping patterns | -note: lint level defined here +note: the lint level is defined here --> $DIR/exhaustive_integer_patterns.rs:4:9 | LL | #![deny(overlapping_patterns)] diff --git a/src/test/ui/pattern/usefulness/issue-43253.stderr b/src/test/ui/pattern/usefulness/issue-43253.stderr index cb4a0486eef9a..cdd3067a678a5 100644 --- a/src/test/ui/pattern/usefulness/issue-43253.stderr +++ b/src/test/ui/pattern/usefulness/issue-43253.stderr @@ -6,7 +6,7 @@ LL | 1..10 => {}, LL | 9..=10 => {}, | ^^^^^^ overlapping patterns | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-43253.rs:4:9 | LL | #![warn(overlapping_patterns)] @@ -18,7 +18,7 @@ warning: unreachable pattern LL | 9 => {}, | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-43253.rs:3:9 | LL | #![warn(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-arm-statics.stderr b/src/test/ui/pattern/usefulness/match-arm-statics.stderr index 3d9e900a4e988..a5dffebf69967 100644 --- a/src/test/ui/pattern/usefulness/match-arm-statics.stderr +++ b/src/test/ui/pattern/usefulness/match-arm-statics.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | (true, true) => () | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-arm-statics.rs:2:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr index 09484692fab08..0c582be8df8bc 100644 --- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | &[0x41, 0x41, 0x41, 0x41] => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-byte-array-patterns.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr index f242ecf2dae4e..49c38d2a9d3d7 100644 --- a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | _ => {}, | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-empty-exhaustive_patterns.rs:3:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr index 8412a113664c8..76a6d1d3eaa1b 100644 --- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr +++ b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | 5 ..= 6 => { } | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-range-fail-dominate.rs:1:9 | LL | #![deny(unreachable_patterns, overlapping_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-ref-ice.stderr b/src/test/ui/pattern/usefulness/match-ref-ice.stderr index c4bfa0afcc278..fad0940baa441 100644 --- a/src/test/ui/pattern/usefulness/match-ref-ice.stderr +++ b/src/test/ui/pattern/usefulness/match-ref-ice.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | [1, 2, 3] => (), | ^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-ref-ice.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-vec-fixed.stderr b/src/test/ui/pattern/usefulness/match-vec-fixed.stderr index ae2dd87b6954b..e388a06cb9a14 100644 --- a/src/test/ui/pattern/usefulness/match-vec-fixed.stderr +++ b/src/test/ui/pattern/usefulness/match-vec-fixed.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | [_, _, _] => {} | ^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-vec-fixed.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr index e9a751074c2e1..672fd92fb5ebd 100644 --- a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | [(1, 2), (2, 3), b] => (), | ^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/match-vec-unreachable.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr index 0c7401269dfc7..cd0cb2e887691 100644 --- a/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr +++ b/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | FOO => (), | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/slice-pattern-const-2.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr index eab4fc3f086da..3ba01b9eba3ce 100644 --- a/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr +++ b/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | FOO => (), | ^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/slice-pattern-const-3.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/slice-pattern-const.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const.stderr index d274d6d7c678b..1fffb9fedbf2e 100644 --- a/src/test/ui/pattern/usefulness/slice-pattern-const.stderr +++ b/src/test/ui/pattern/usefulness/slice-pattern-const.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | [84, 69, 83, 84] => (), | ^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/slice-pattern-const.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr index e24d10281170d..607ffb76595e9 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr +++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | [true, ..] => {} | ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/slice-patterns-reachability.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr index 0115fc081a970..fbee33de6f30a 100644 --- a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr +++ b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr @@ -6,7 +6,7 @@ LL | Foo { x: _x, y: _y } => (), LL | Foo { .. } => () | ^^^^^^^^^^ unreachable pattern | -note: lint level defined here +note: the lint level is defined here --> $DIR/struct-pattern-match-useless.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.stderr b/src/test/ui/pattern/usefulness/top-level-alternation.stderr index 7c7c4fc4eba28..76bc4f8d0910a 100644 --- a/src/test/ui/pattern/usefulness/top-level-alternation.stderr +++ b/src/test/ui/pattern/usefulness/top-level-alternation.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | while let 0..=2 | 1 = 0 {} | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/top-level-alternation.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/privacy/private-in-public-non-principal.stderr b/src/test/ui/privacy/private-in-public-non-principal.stderr index 4f2a5ea45aa32..2a41fae43c629 100644 --- a/src/test/ui/privacy/private-in-public-non-principal.stderr +++ b/src/test/ui/privacy/private-in-public-non-principal.stderr @@ -14,7 +14,7 @@ error: missing documentation for a method LL | pub fn check_doc_lint() {} | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/private-in-public-non-principal.rs:10:8 | LL | #[deny(missing_docs)] diff --git a/src/test/ui/privacy/private-in-public-warn.stderr b/src/test/ui/privacy/private-in-public-warn.stderr index 40aa47a7246c4..079331bffd228 100644 --- a/src/test/ui/privacy/private-in-public-warn.stderr +++ b/src/test/ui/privacy/private-in-public-warn.stderr @@ -4,7 +4,7 @@ error: private type `types::Priv` in public interface (error E0446) LL | pub type Alias = Priv; | ^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/private-in-public-warn.rs:5:9 | LL | #![deny(private_in_public)] diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index f21b11f5b32f8..010969c03afda 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -4,7 +4,7 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public i LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/pub-priv1.rs:3:9 | LL | #![deny(exported_private_dependencies)] diff --git a/src/test/ui/proc-macro/attributes-included.stderr b/src/test/ui/proc-macro/attributes-included.stderr index 0f74f45e102f7..27a215de032aa 100644 --- a/src/test/ui/proc-macro/attributes-included.stderr +++ b/src/test/ui/proc-macro/attributes-included.stderr @@ -4,7 +4,7 @@ warning: unused variable: `a` LL | let a: i32 = "foo"; | ^ help: consider prefixing with an underscore: `_a` | -note: lint level defined here +note: the lint level is defined here --> $DIR/attributes-included.rs:4:9 | LL | #![warn(unused)] diff --git a/src/test/ui/proc-macro/no-macro-use-attr.stderr b/src/test/ui/proc-macro/no-macro-use-attr.stderr index 50552ea7dbb68..27943a3f7bf8c 100644 --- a/src/test/ui/proc-macro/no-macro-use-attr.stderr +++ b/src/test/ui/proc-macro/no-macro-use-attr.stderr @@ -4,7 +4,7 @@ warning: unused extern crate LL | extern crate test_macros; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/no-macro-use-attr.rs:4:9 | LL | #![warn(unused_extern_crates)] diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.stderr b/src/test/ui/range/range-inclusive-pattern-precedence.stderr index fb0cf3801549f..8c4ebd10fc909 100644 --- a/src/test/ui/range/range-inclusive-pattern-precedence.stderr +++ b/src/test/ui/range/range-inclusive-pattern-precedence.stderr @@ -16,7 +16,7 @@ warning: `...` range patterns are deprecated LL | &0...9 => {} | ^^^^^^ help: use `..=` for an inclusive range: `&(0..=9)` | -note: lint level defined here +note: the lint level is defined here --> $DIR/range-inclusive-pattern-precedence.rs:9:9 | LL | #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr index 880dea1cc3516..692bd20f50940 100644 --- a/src/test/ui/reachable/expr_add.stderr +++ b/src/test/ui/reachable/expr_add.stderr @@ -7,7 +7,7 @@ LL | let x = Foo + return; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_add.rs:3:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr index 95006884242f9..a9b5832ba2c88 100644 --- a/src/test/ui/reachable/expr_again.stderr +++ b/src/test/ui/reachable/expr_again.stderr @@ -6,7 +6,7 @@ LL | continue; LL | println!("hi"); | ^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_again.rs:3:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr index b3138d3c33fc0..e144d7184af6a 100644 --- a/src/test/ui/reachable/expr_array.stderr +++ b/src/test/ui/reachable/expr_array.stderr @@ -6,7 +6,7 @@ LL | let x: [usize; 2] = [return, 22]; | | | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_array.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr index 3004da0406328..c51156b3f40cf 100644 --- a/src/test/ui/reachable/expr_assign.stderr +++ b/src/test/ui/reachable/expr_assign.stderr @@ -7,7 +7,7 @@ LL | x = return; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_assign.rs:5:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index 44baddd1e5503..8b696b7abcb72 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -6,7 +6,7 @@ LL | return; LL | 22 | ^^ unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_block.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr index b01a13e9df29a..ea6472cbeab34 100644 --- a/src/test/ui/reachable/expr_box.stderr +++ b/src/test/ui/reachable/expr_box.stderr @@ -7,7 +7,7 @@ LL | let x = box return; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_box.rs:3:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr index ae8b4dd87b5b9..a5ad9a329f06e 100644 --- a/src/test/ui/reachable/expr_call.stderr +++ b/src/test/ui/reachable/expr_call.stderr @@ -6,7 +6,7 @@ LL | foo(return, 22); | | | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_call.rs:5:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr index 81813d1d71c3f..3aa15bde9956b 100644 --- a/src/test/ui/reachable/expr_cast.stderr +++ b/src/test/ui/reachable/expr_cast.stderr @@ -7,7 +7,7 @@ LL | let x = {return} as !; | |any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_cast.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index ccd45ccec62c7..6ae635ae4b7e8 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -9,7 +9,7 @@ LL | | println!("Hello, world!"); LL | | } | |_____^ unreachable block in `if` expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_if.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index 5f279c9630d30..e5d395254a06d 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -6,7 +6,7 @@ LL | loop { return; } LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_loop.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index d39acdc290926..a8317192c2b32 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -6,7 +6,7 @@ LL | match () { () => return } LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_match.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr index 82a0745f0629f..41c3b8a39060f 100644 --- a/src/test/ui/reachable/expr_method.stderr +++ b/src/test/ui/reachable/expr_method.stderr @@ -6,7 +6,7 @@ LL | Foo.foo(return, 22); | | | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_method.rs:5:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr index 34129936fd762..defa870461028 100644 --- a/src/test/ui/reachable/expr_repeat.stderr +++ b/src/test/ui/reachable/expr_repeat.stderr @@ -7,7 +7,7 @@ LL | let x: [usize; 2] = [return; 2]; | |any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_repeat.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr index c0a94746d08eb..e1bef80aeb00e 100644 --- a/src/test/ui/reachable/expr_return.stderr +++ b/src/test/ui/reachable/expr_return.stderr @@ -7,7 +7,7 @@ LL | let x = {return {return {return;}}}; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_return.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_return_in_macro.stderr b/src/test/ui/reachable/expr_return_in_macro.stderr index 2bc6a763cfaea..3c562a7ee6f01 100644 --- a/src/test/ui/reachable/expr_return_in_macro.stderr +++ b/src/test/ui/reachable/expr_return_in_macro.stderr @@ -7,7 +7,7 @@ LL | return () LL | return early_return!(); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_return_in_macro.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr index b3ca06eada3d5..36b070456c56b 100644 --- a/src/test/ui/reachable/expr_struct.stderr +++ b/src/test/ui/reachable/expr_struct.stderr @@ -7,7 +7,7 @@ LL | let x = Foo { a: 22, b: 33, ..return }; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_struct.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr index aaaf6462da895..5ea6bf4abf6f2 100644 --- a/src/test/ui/reachable/expr_tup.stderr +++ b/src/test/ui/reachable/expr_tup.stderr @@ -6,7 +6,7 @@ LL | let x: (usize, usize) = (return, 2); | | | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_tup.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr index cb6e8d7039f2c..c56c64be721fe 100644 --- a/src/test/ui/reachable/expr_type.stderr +++ b/src/test/ui/reachable/expr_type.stderr @@ -7,7 +7,7 @@ LL | let x = {return}: !; | |any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_type.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index f5c3564217bba..063d841c25e39 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -13,7 +13,7 @@ LL | let x: ! = ! { return; }; | | any code following this expression is unreachable | unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_unary.rs:5:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr index edb1dd2b9bc70..83354574eafc4 100644 --- a/src/test/ui/reachable/expr_while.stderr +++ b/src/test/ui/reachable/expr_while.stderr @@ -10,7 +10,7 @@ LL | | println!("Hello, world!"); LL | | } | |_____^ unreachable block in `while` expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/expr_while.rs:4:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/unreachable-arm.stderr b/src/test/ui/reachable/unreachable-arm.stderr index 8e65745c7b099..1cbea8288d465 100644 --- a/src/test/ui/reachable/unreachable-arm.stderr +++ b/src/test/ui/reachable/unreachable-arm.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | Foo::A(_, 1) => { } | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-arm.rs:4:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/reachable/unreachable-code.stderr b/src/test/ui/reachable/unreachable-code.stderr index 184440db5df48..4b951263dbde6 100644 --- a/src/test/ui/reachable/unreachable-code.stderr +++ b/src/test/ui/reachable/unreachable-code.stderr @@ -7,7 +7,7 @@ LL | LL | let a = 3; | ^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-code.rs:1:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/unreachable-in-call.stderr b/src/test/ui/reachable/unreachable-in-call.stderr index 1d081d1c76228..cdfa79bf89946 100644 --- a/src/test/ui/reachable/unreachable-in-call.stderr +++ b/src/test/ui/reachable/unreachable-in-call.stderr @@ -6,7 +6,7 @@ LL | call(diverge(), LL | get_u8()); | ^^^^^^^^ unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-in-call.rs:2:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/unreachable-loop-patterns.stderr b/src/test/ui/reachable/unreachable-loop-patterns.stderr index bb5103320d2cf..680d22862d7fe 100644 --- a/src/test/ui/reachable/unreachable-loop-patterns.stderr +++ b/src/test/ui/reachable/unreachable-loop-patterns.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | for _ in unimplemented!() as Void {} | ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-loop-patterns.rs:5:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/reachable/unreachable-try-pattern.stderr b/src/test/ui/reachable/unreachable-try-pattern.stderr index 707038442a2b6..d141e382313bf 100644 --- a/src/test/ui/reachable/unreachable-try-pattern.stderr +++ b/src/test/ui/reachable/unreachable-try-pattern.stderr @@ -7,7 +7,7 @@ LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; | unreachable expression | any code following this expression is unreachable | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-try-pattern.rs:3:9 | LL | #![warn(unreachable_code)] @@ -19,7 +19,7 @@ warning: unreachable pattern LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-try-pattern.rs:4:9 | LL | #![warn(unreachable_patterns)] diff --git a/src/test/ui/reachable/unwarned-match-on-never.stderr b/src/test/ui/reachable/unwarned-match-on-never.stderr index 6b2fb4a33c1e8..a296d2a055e09 100644 --- a/src/test/ui/reachable/unwarned-match-on-never.stderr +++ b/src/test/ui/reachable/unwarned-match-on-never.stderr @@ -7,7 +7,7 @@ LL | // But matches in unreachable code are warned. LL | match x {} | ^^^^^^^^^^ unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/unwarned-match-on-never.rs:1:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr index 20d5564c16d15..c86556c89f43b 100644 --- a/src/test/ui/removing-extern-crate.stderr +++ b/src/test/ui/removing-extern-crate.stderr @@ -4,7 +4,7 @@ warning: unused extern crate LL | extern crate removing_extern_crate as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/removing-extern-crate.rs:6:9 | LL | #![warn(rust_2018_idioms)] diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr index 7fbf1157e56f8..4956226712d04 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr @@ -4,7 +4,7 @@ error: `extern` block uses type `types::NonExhaustiveEnum`, which is not FFI-saf LL | pub fn non_exhaustive_enum(_: NonExhaustiveEnum); | ^^^^^^^^^^^^^^^^^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/extern_crate_improper.rs:2:9 | LL | #![deny(improper_ctypes)] diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr index f2b9983af8602..f39e6ee298544 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | PartiallyInhabitedVariants::Struct { .. } => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-65157-repeated-match-arm.rs:2:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr index e3de94be1282e..8bfd6e91f4dec 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | Some(_x) => (), | ^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/patterns_same_crate.rs:1:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr index 8d9571d09a856..82099066a89d2 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -4,7 +4,7 @@ error: unused variable: `a` LL | #[cfg(something)] a: i32, | ^ help: consider prefixing with an underscore: `_a` | -note: lint level defined here +note: the lint level is defined here --> $DIR/param-attrs-cfg.rs:5:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr index 5281d576066da..030deda9af62e 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr index 5d601c2c006f7..e274d8ed0848c 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr index 4ac19afa706b0..067677fbfb6af 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr index 4000a47987854..31b294f379ce8 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr index 0e158c2fda560..c495c37f6a157 100644 --- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -4,7 +4,7 @@ warning: to use a constant of type `B` in a pattern, `B` must be annotated with LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 | LL | #![warn(indirect_structural_match)] diff --git a/src/test/ui/rust-2018/async-ident-allowed.stderr b/src/test/ui/rust-2018/async-ident-allowed.stderr index 2394bff11816d..43fc3f5e334ec 100644 --- a/src/test/ui/rust-2018/async-ident-allowed.stderr +++ b/src/test/ui/rust-2018/async-ident-allowed.stderr @@ -4,7 +4,7 @@ error: `async` is a keyword in the 2018 edition LL | let async = 3; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | -note: lint level defined here +note: the lint level is defined here --> $DIR/async-ident-allowed.rs:3:9 | LL | #![deny(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/async-ident.stderr b/src/test/ui/rust-2018/async-ident.stderr index b149533775633..6051c81f77c90 100644 --- a/src/test/ui/rust-2018/async-ident.stderr +++ b/src/test/ui/rust-2018/async-ident.stderr @@ -4,7 +4,7 @@ error: `async` is a keyword in the 2018 edition LL | fn async() {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | -note: lint level defined here +note: the lint level is defined here --> $DIR/async-ident.rs:2:9 | LL | #![deny(keyword_idents)] diff --git a/src/test/ui/rust-2018/dyn-keyword.stderr b/src/test/ui/rust-2018/dyn-keyword.stderr index fa79df49fb665..0fe11168c440f 100644 --- a/src/test/ui/rust-2018/dyn-keyword.stderr +++ b/src/test/ui/rust-2018/dyn-keyword.stderr @@ -4,7 +4,7 @@ error: `dyn` is a keyword in the 2018 edition LL | let dyn = (); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | -note: lint level defined here +note: the lint level is defined here --> $DIR/dyn-keyword.rs:5:9 | LL | #![deny(keyword_idents)] diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index 412ebe1a9c48f..0b400786d3507 100644 --- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-fully-qualified-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr b/src/test/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr index 3515d42260591..45bc5dbc44676 100644 --- a/src/test/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr +++ b/src/test/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr @@ -4,7 +4,7 @@ error: outlives requirements can be inferred LL | struct TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> { | ^^^^^ ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-infer-outlives-multispan.rs:2:9 | LL | #![deny(explicit_outlives_requirements)] diff --git a/src/test/ui/rust-2018/edition-lint-infer-outlives.stderr b/src/test/ui/rust-2018/edition-lint-infer-outlives.stderr index cddce94254b40..faa9f21e38ba2 100644 --- a/src/test/ui/rust-2018/edition-lint-infer-outlives.stderr +++ b/src/test/ui/rust-2018/edition-lint-infer-outlives.stderr @@ -4,7 +4,7 @@ error: outlives requirements can be inferred LL | struct TeeOutlivesAy<'a, T: 'a> { | ^^^^ help: remove this bound | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-infer-outlives.rs:4:9 | LL | #![deny(explicit_outlives_requirements)] diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 742203e998510..d554cc28621c2 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use foo::{bar::{baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-nested-empty-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr index 6cd8e9acd1096..040aa4a54806a 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-nested-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/edition-lint-paths.stderr b/src/test/ui/rust-2018/edition-lint-paths.stderr index 4f1904a1f8aba..dd36d07da56ed 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-paths.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` | -note: lint level defined here +note: the lint level is defined here --> $DIR/edition-lint-paths.rs:5:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr index 12a6110bfb406..bb50ec3f57dd6 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr @@ -4,7 +4,7 @@ error: unused extern crate LL | extern crate edition_lint_paths; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/extern-crate-idiomatic-in-2018.rs:9:9 | LL | #![deny(rust_2018_idioms)] diff --git a/src/test/ui/rust-2018/extern-crate-rename.stderr b/src/test/ui/rust-2018/extern-crate-rename.stderr index 4e33b1e959ab0..6ea762ed999a0 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.stderr +++ b/src/test/ui/rust-2018/extern-crate-rename.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use my_crate::foo; | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/extern-crate-rename.rs:8:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/extern-crate-submod.stderr b/src/test/ui/rust-2018/extern-crate-submod.stderr index e0b61dd265cc8..87a0d492675c7 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.stderr +++ b/src/test/ui/rust-2018/extern-crate-submod.stderr @@ -4,7 +4,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use m::edition_lint_paths::foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/extern-crate-submod.rs:9:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] diff --git a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr index 957a04cd9804a..2ef97e7f20e9f 100644 --- a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr +++ b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr @@ -7,7 +7,7 @@ LL | | extern crate edition_lint_paths; | |________________________________| | help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-54400-unused-extern-crate-attr-span.rs:6:9 | LL | #![deny(rust_2018_idioms)] diff --git a/src/test/ui/rust-2018/macro-use-warned-against.stderr b/src/test/ui/rust-2018/macro-use-warned-against.stderr index 944b56e9577b6..611b9d5dac9fd 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.stderr +++ b/src/test/ui/rust-2018/macro-use-warned-against.stderr @@ -4,7 +4,7 @@ warning: deprecated `#[macro_use]` directive used to import macros should be rep LL | #[macro_use] | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/macro-use-warned-against.rs:5:9 | LL | #![warn(macro_use_extern_crate, unused)] @@ -16,7 +16,7 @@ warning: unused `#[macro_use]` import LL | #[macro_use] | ^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/macro-use-warned-against.rs:5:33 | LL | #![warn(macro_use_extern_crate, unused)] diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 4777565452a31..8df93c56e93f0 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -4,7 +4,7 @@ warning: unused extern crate LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/remove-extern-crate.rs:7:9 | LL | #![warn(rust_2018_idioms)] diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr index 5add50e87f787..8495fe62575bf 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr @@ -4,7 +4,7 @@ warning: absolute paths must start with `self`, `super`, `crate`, or an external LL | #[foo] | ^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/suggestions-not-always-applicable.rs:8:9 | LL | #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr index 29cc68c439e9d..a5cb839ec0ee4 100644 --- a/src/test/ui/rust-2018/try-ident.stderr +++ b/src/test/ui/rust-2018/try-ident.stderr @@ -4,7 +4,7 @@ warning: `try` is a keyword in the 2018 edition LL | try(); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | -note: lint level defined here +note: the lint level is defined here --> $DIR/try-ident.rs:4:9 | LL | #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr index eb65d4150642a..b92d5048b3899 100644 --- a/src/test/ui/rust-2018/try-macro.stderr +++ b/src/test/ui/rust-2018/try-macro.stderr @@ -4,7 +4,7 @@ warning: `try` is a keyword in the 2018 edition LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | -note: lint level defined here +note: the lint level is defined here --> $DIR/try-macro.rs:6:9 | LL | #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/single-use-lifetime/fn-types.stderr b/src/test/ui/single-use-lifetime/fn-types.stderr index bec24be07af63..584c889506ba5 100644 --- a/src/test/ui/single-use-lifetime/fn-types.stderr +++ b/src/test/ui/single-use-lifetime/fn-types.stderr @@ -6,7 +6,7 @@ LL | a: for<'a> fn(&'a u32), | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/fn-types.rs:1:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.stderr b/src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.stderr index ef118a22ccbd7..b251e8a438ac1 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.stderr @@ -7,7 +7,7 @@ LL | fn a(x: &'a u32, y: &'b u32) { | this lifetime is only used here | help: elide the single-use lifetime | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-fn-argument-in-band.rs:4:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr index 25aa8bb6fb0bc..f78970ac0a41d 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr @@ -6,7 +6,7 @@ LL | fn a<'a>(x: &'a u32) { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-fn-argument.rs:1:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr index 8115a1e64011f..35fd782e13320 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr @@ -6,7 +6,7 @@ LL | impl<'f> Foo<'f> { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-inherent-impl-header.rs:1:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr index 48bd9f19126b2..10fb40b9d142d 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr @@ -6,7 +6,7 @@ LL | fn inherent_a<'a>(&self, data: &'a u32) { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-inherent-method-argument.rs:1:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr index 9c93da4627156..da9e253461191 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr @@ -6,7 +6,7 @@ LL | impl<'f> Foo<'f> { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-inherent-method-return.rs:1:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr index 047e0591e4b9a..55d11add7b6b1 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr @@ -6,7 +6,7 @@ LL | fn next<'g>(&'g mut self) -> Option { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/one-use-in-trait-method-argument.rs:4:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr b/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr index 6f0ba02b5067b..c16b244fafd00 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr +++ b/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr @@ -6,7 +6,7 @@ LL | impl<'f> Foo<'f> { | | | this lifetime... | -note: lint level defined here +note: the lint level is defined here --> $DIR/two-uses-in-inherent-method-argument-and-return.rs:4:9 | LL | #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/zero-uses-in-fn.stderr b/src/test/ui/single-use-lifetime/zero-uses-in-fn.stderr index b9c3bd89748ff..59c0164e32414 100644 --- a/src/test/ui/single-use-lifetime/zero-uses-in-fn.stderr +++ b/src/test/ui/single-use-lifetime/zero-uses-in-fn.stderr @@ -4,7 +4,7 @@ error: lifetime parameter `'a` never used LL | fn september<'a>() {} | -^^- help: elide the unused lifetime | -note: lint level defined here +note: the lint level is defined here --> $DIR/zero-uses-in-fn.rs:5:9 | LL | #![deny(unused_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/zero-uses-in-impl.stderr b/src/test/ui/single-use-lifetime/zero-uses-in-impl.stderr index 650a9b4600ea2..b6e42d3e717f0 100644 --- a/src/test/ui/single-use-lifetime/zero-uses-in-impl.stderr +++ b/src/test/ui/single-use-lifetime/zero-uses-in-impl.stderr @@ -4,7 +4,7 @@ error: lifetime parameter `'a` never used LL | impl<'a> Foo {} | -^^- help: elide the unused lifetime | -note: lint level defined here +note: the lint level is defined here --> $DIR/zero-uses-in-impl.rs:3:9 | LL | #![deny(unused_lifetimes)] diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index b2160e66a74d4..69d1150abba47 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -4,7 +4,7 @@ warning: unused variable: `theOtherTwo` LL | let theOtherTwo = 2; | ^^^^^^^^^^^ help: consider prefixing with an underscore: `_theOtherTwo` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-24690.rs:8:9 | LL | #![warn(unused)] diff --git a/src/test/ui/span/lint-unused-unsafe.stderr b/src/test/ui/span/lint-unused-unsafe.stderr index ac8107990c2bd..c35a3349121b7 100644 --- a/src/test/ui/span/lint-unused-unsafe.stderr +++ b/src/test/ui/span/lint-unused-unsafe.stderr @@ -4,7 +4,7 @@ error: unnecessary `unsafe` block LL | fn bad1() { unsafe {} } | ^^^^^^ unnecessary `unsafe` block | -note: lint level defined here +note: the lint level is defined here --> $DIR/lint-unused-unsafe.rs:4:9 | LL | #![deny(unused_unsafe)] diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 8b65e798b6ef5..4eb775155a54d 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -7,7 +7,7 @@ LL | $b $a; LL | m!(S struct); | ------------- in this macro invocation | -note: lint level defined here +note: the lint level is defined here --> $DIR/macro-span-replacement.rs:3:9 | LL | #![warn(unused)] diff --git a/src/test/ui/span/multispan-import-lint.stderr b/src/test/ui/span/multispan-import-lint.stderr index a54c86cdb0fdf..4faa9e128d19a 100644 --- a/src/test/ui/span/multispan-import-lint.stderr +++ b/src/test/ui/span/multispan-import-lint.stderr @@ -4,7 +4,7 @@ warning: unused imports: `Eq`, `Ord`, `PartialEq`, `PartialOrd` LL | use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd}; | ^^ ^^^ ^^^^^^^^^ ^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/multispan-import-lint.rs:3:9 | LL | #![warn(unused)] diff --git a/src/test/ui/span/unused-warning-point-at-identifier.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr index a4715d4adeb88..f8d38d7b4b8fb 100644 --- a/src/test/ui/span/unused-warning-point-at-identifier.stderr +++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr @@ -4,7 +4,7 @@ warning: enum is never used: `Enum` LL | enum Enum { | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-warning-point-at-identifier.rs:3:9 | LL | #![warn(unused)] diff --git a/src/test/ui/stable-features.stderr b/src/test/ui/stable-features.stderr index 537c3f082eff6..831b40b8612c8 100644 --- a/src/test/ui/stable-features.stderr +++ b/src/test/ui/stable-features.stderr @@ -4,7 +4,7 @@ error: the feature `test_accepted_feature` has been stable since 1.0.0 and no lo LL | #![feature(test_accepted_feature)] | ^^^^^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/stable-features.rs:4:9 | LL | #![deny(stable_features)] diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr index 46943f40066ff..0e2eb7616cf9d 100644 --- a/src/test/ui/suggestions/issue-61963.stderr +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -4,7 +4,7 @@ error: trait objects without an explicit `dyn` are deprecated LL | bar: Box, | ^^^ help: use `dyn`: `dyn Bar` | -note: lint level defined here +note: the lint level is defined here --> $DIR/issue-61963.rs:3:9 | LL | #![deny(bare_trait_objects)] diff --git a/src/test/ui/suggestions/unused-closure-argument.stderr b/src/test/ui/suggestions/unused-closure-argument.stderr index 5cfdd79659b27..d83ab08e71efc 100644 --- a/src/test/ui/suggestions/unused-closure-argument.stderr +++ b/src/test/ui/suggestions/unused-closure-argument.stderr @@ -4,7 +4,7 @@ error: unused variable: `x` LL | .map(|Point { x, y }| y) | ^ help: try ignoring the field: `x: _` | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-closure-argument.rs:1:9 | LL | #![deny(unused_variables)] diff --git a/src/test/ui/test-attrs/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr index cb118cdb4103c..d3bcea2951364 100644 --- a/src/test/ui/test-attrs/test-warns-dead-code.stderr +++ b/src/test/ui/test-attrs/test-warns-dead-code.stderr @@ -4,7 +4,7 @@ error: function is never used: `dead` LL | fn dead() {} | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/test-warns-dead-code.rs:3:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/tool_lints-fail.stderr b/src/test/ui/tool_lints-fail.stderr index a61157f21b8e5..16f678144a37d 100644 --- a/src/test/ui/tool_lints-fail.stderr +++ b/src/test/ui/tool_lints-fail.stderr @@ -4,7 +4,7 @@ error: unknown lint: `clippy` LL | #![deny(clippy)] | ^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/tool_lints-fail.rs:4:9 | LL | #![deny(unknown_lints)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr index 2f4b2df24cd54..9fe19c860b07f 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr @@ -4,7 +4,7 @@ error: Trait bound i32: std::marker::Copy does not depend on any type or lifetim LL | struct A where i32: Copy; | ^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial-bounds-lint.rs:3:9 | LL | #![deny(trivial_bounds)] diff --git a/src/test/ui/trivial_casts.stderr b/src/test/ui/trivial_casts.stderr index 8fa44372f0b4f..70954f00bad0e 100644 --- a/src/test/ui/trivial_casts.stderr +++ b/src/test/ui/trivial_casts.stderr @@ -4,7 +4,7 @@ error: trivial numeric cast: `i32` as `i32` LL | let _ = 42_i32 as i32; | ^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial_casts.rs:4:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] @@ -25,7 +25,7 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = x as *const u32; | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/trivial_casts.rs:4:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] diff --git a/src/test/ui/try-block/try-block-unreachable-code-lint.stderr b/src/test/ui/try-block/try-block-unreachable-code-lint.stderr index 54fed04d400e9..c883994c876f8 100644 --- a/src/test/ui/try-block/try-block-unreachable-code-lint.stderr +++ b/src/test/ui/try-block/try-block-unreachable-code-lint.stderr @@ -11,7 +11,7 @@ LL | | } LL | | } | |_________^ unreachable expression | -note: lint level defined here +note: the lint level is defined here --> $DIR/try-block-unreachable-code-lint.rs:6:9 | LL | #![warn(unreachable_code)] diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index db8767273b423..870b1eec48c0c 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -7,12 +7,12 @@ LL | fn f() -> Self::V { 0 } = note: `#[deny(ambiguous_associated_items)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57644 -note: `V` could refer to variant defined here +note: `V` could refer to the variant defined here --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5 | LL | V | ^ -note: `V` could also refer to associated type defined here +note: `V` could also refer to the associated type defined here --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5 | LL | type V; diff --git a/src/test/ui/underscore-imports/basic.stderr b/src/test/ui/underscore-imports/basic.stderr index 9ca60e8e0a955..891730dc84387 100644 --- a/src/test/ui/underscore-imports/basic.stderr +++ b/src/test/ui/underscore-imports/basic.stderr @@ -4,7 +4,7 @@ warning: unused import: `m::Tr1 as _` LL | use m::Tr1 as _; | ^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/basic.rs:4:9 | LL | #![warn(unused_imports, unused_extern_crates)] diff --git a/src/test/ui/underscore-imports/unused-2018.stderr b/src/test/ui/underscore-imports/unused-2018.stderr index 861b3f1d4fd1e..2afb9a10e2ccc 100644 --- a/src/test/ui/underscore-imports/unused-2018.stderr +++ b/src/test/ui/underscore-imports/unused-2018.stderr @@ -4,7 +4,7 @@ error: unused import: `core::any` LL | use core::any; | ^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-2018.rs:3:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/uninhabited/uninhabited-patterns.stderr b/src/test/ui/uninhabited/uninhabited-patterns.stderr index 3e5329cfb3011..655569ad6e086 100644 --- a/src/test/ui/uninhabited/uninhabited-patterns.stderr +++ b/src/test/ui/uninhabited/uninhabited-patterns.stderr @@ -4,7 +4,7 @@ error: unreachable pattern LL | &[..] => (), | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/uninhabited-patterns.rs:6:9 | LL | #![deny(unreachable_patterns)] diff --git a/src/test/ui/union/union-fields-1.stderr b/src/test/ui/union/union-fields-1.stderr index be145c9496c6c..87621cc01b1b9 100644 --- a/src/test/ui/union/union-fields-1.stderr +++ b/src/test/ui/union/union-fields-1.stderr @@ -4,7 +4,7 @@ error: field is never read: `c` LL | c: u8, | ^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/union-fields-1.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/union/union-lint-dead-code.stderr b/src/test/ui/union/union-lint-dead-code.stderr index 5fe26dc253844..7de70ec33801f 100644 --- a/src/test/ui/union/union-lint-dead-code.stderr +++ b/src/test/ui/union/union-lint-dead-code.stderr @@ -4,7 +4,7 @@ error: field is never read: `b` LL | b: bool, | ^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/union-lint-dead-code.rs:1:9 | LL | #![deny(dead_code)] diff --git a/src/test/ui/union/union-repr-c.stderr b/src/test/ui/union/union-repr-c.stderr index c8bc0380dee68..ae84cc7811bb3 100644 --- a/src/test/ui/union/union-repr-c.stderr +++ b/src/test/ui/union/union-repr-c.stderr @@ -4,14 +4,14 @@ error: `extern` block uses type `W`, which is not FFI-safe LL | static FOREIGN2: W; | ^ not FFI-safe | -note: lint level defined here +note: the lint level is defined here --> $DIR/union-repr-c.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union = note: this union has unspecified layout -note: type defined here +note: the type is defined here --> $DIR/union-repr-c.rs:9:1 | LL | / union W { diff --git a/src/test/ui/unnecessary-extern-crate.stderr b/src/test/ui/unnecessary-extern-crate.stderr index 1e6d755234336..14ba9d052f425 100644 --- a/src/test/ui/unnecessary-extern-crate.stderr +++ b/src/test/ui/unnecessary-extern-crate.stderr @@ -4,7 +4,7 @@ error: unused extern crate LL | extern crate libc; | ^^^^^^^^^^^^^^^^^^ help: remove it | -note: lint level defined here +note: the lint level is defined here --> $DIR/unnecessary-extern-crate.rs:3:9 | LL | #![deny(unused_extern_crates)] diff --git a/src/test/ui/unreachable-code-ret.stderr b/src/test/ui/unreachable-code-ret.stderr index c22342ce7218d..3b93ef97f3206 100644 --- a/src/test/ui/unreachable-code-ret.stderr +++ b/src/test/ui/unreachable-code-ret.stderr @@ -6,7 +6,7 @@ LL | return; LL | println!("Paul is dead"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | -note: lint level defined here +note: the lint level is defined here --> $DIR/unreachable-code-ret.rs:3:9 | LL | #![deny(unreachable_code)] diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.stderr b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.stderr index 28b18d50fff19..0dba8496efd39 100644 --- a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.stderr +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.stderr @@ -4,7 +4,7 @@ error: unnecessary `unsafe` block LL | unsafe { println!("foo"); } | ^^^^^^ unnecessary `unsafe` block | -note: lint level defined here +note: the lint level is defined here --> $DIR/unsafe-around-compiler-generated-unsafe.rs:3:9 | LL | #![deny(unused_unsafe)] diff --git a/src/test/ui/unused/unused-attr.stderr b/src/test/ui/unused/unused-attr.stderr index 956b870715eb2..fd7412db2257c 100644 --- a/src/test/ui/unused/unused-attr.stderr +++ b/src/test/ui/unused/unused-attr.stderr @@ -4,7 +4,7 @@ error: unused attribute LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-attr.rs:1:9 | LL | #![deny(unused_attributes)] diff --git a/src/test/ui/unused/unused-macro-rules.stderr b/src/test/ui/unused/unused-macro-rules.stderr index 5c0b9f262b8c7..9bb3c3f3dec8c 100644 --- a/src/test/ui/unused/unused-macro-rules.stderr +++ b/src/test/ui/unused/unused-macro-rules.stderr @@ -6,7 +6,7 @@ LL | | () => {}; LL | | } | |_^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-macro-rules.rs:1:9 | LL | #![deny(unused_macros)] @@ -31,7 +31,7 @@ LL | | () => {}; LL | | } | |_____^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-macro-rules.rs:23:12 | LL | #[deny(unused_macros)] diff --git a/src/test/ui/unused/unused-macro.stderr b/src/test/ui/unused/unused-macro.stderr index d18fe82564e03..f5eb76179bf4b 100644 --- a/src/test/ui/unused/unused-macro.stderr +++ b/src/test/ui/unused/unused-macro.stderr @@ -6,7 +6,7 @@ LL | | () => {} LL | | } | |_^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-macro.rs:2:9 | LL | #![deny(unused_macros)] @@ -20,7 +20,7 @@ LL | | () => {} LL | | } | |_____^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-macro.rs:14:12 | LL | #[deny(unused_macros)] diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.stderr b/src/test/ui/unused/unused-mut-warning-captured-var.stderr index d5b731406d6fc..39d470e02a80f 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.stderr +++ b/src/test/ui/unused/unused-mut-warning-captured-var.stderr @@ -6,7 +6,7 @@ LL | let mut x = 1; | | | help: remove this `mut` | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-mut-warning-captured-var.rs:1:11 | LL | #![forbid(unused_mut)] diff --git a/src/test/ui/unused/unused-result.rs b/src/test/ui/unused/unused-result.rs index 538d30943edbb..a65e98990dceb 100644 --- a/src/test/ui/unused/unused-result.rs +++ b/src/test/ui/unused/unused-result.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] #![deny(unused_results, unused_must_use)] -//~^ NOTE: lint level defined here -//~| NOTE: lint level defined here +//~^ NOTE: the lint level is defined here +//~| NOTE: the lint level is defined here #[must_use] enum MustUse { Test } diff --git a/src/test/ui/unused/unused-result.stderr b/src/test/ui/unused/unused-result.stderr index e2aee75f3ed31..1b1dcab3a1bc9 100644 --- a/src/test/ui/unused/unused-result.stderr +++ b/src/test/ui/unused/unused-result.stderr @@ -4,7 +4,7 @@ error: unused `MustUse` that must be used LL | foo::(); | ^^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-result.rs:2:25 | LL | #![deny(unused_results, unused_must_use)] @@ -24,7 +24,7 @@ error: unused result LL | foo::(); | ^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/unused-result.rs:2:9 | LL | #![deny(unused_results, unused_must_use)] diff --git a/src/test/ui/use/use-nested-groups-unused-imports.stderr b/src/test/ui/use/use-nested-groups-unused-imports.stderr index c8df6cbc57dca..987d1dcf5f00d 100644 --- a/src/test/ui/use/use-nested-groups-unused-imports.stderr +++ b/src/test/ui/use/use-nested-groups-unused-imports.stderr @@ -4,7 +4,7 @@ error: unused imports: `*`, `Foo`, `baz::{}`, `foobar::*` LL | use foo::{Foo, bar::{baz::{}, foobar::*}, *}; | ^^^ ^^^^^^^ ^^^^^^^^^ ^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/use-nested-groups-unused-imports.rs:3:9 | LL | #![deny(unused_imports)] diff --git a/src/test/ui/useless-comment.stderr b/src/test/ui/useless-comment.stderr index 925e307963692..e5e4290d0e1b8 100644 --- a/src/test/ui/useless-comment.stderr +++ b/src/test/ui/useless-comment.stderr @@ -6,7 +6,7 @@ LL | /// foo LL | mac!(); | ------- rustdoc does not generate documentation for macro expansions | -note: lint level defined here +note: the lint level is defined here --> $DIR/useless-comment.rs:3:9 | LL | #![deny(unused_doc_comments)] diff --git a/src/test/ui/variants/variant-size-differences.stderr b/src/test/ui/variants/variant-size-differences.stderr index c82c253f610d0..241a757d44523 100644 --- a/src/test/ui/variants/variant-size-differences.stderr +++ b/src/test/ui/variants/variant-size-differences.stderr @@ -4,7 +4,7 @@ error: enum variant is more than three times larger (1024 bytes) than the next l LL | VBig([u8; 1024]), | ^^^^^^^^^^^^^^^^ | -note: lint level defined here +note: the lint level is defined here --> $DIR/variant-size-differences.rs:1:9 | LL | #![deny(variant_size_differences)] From 2d7f8b31db062b695175c940d7f0c13281e45bb2 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 24 Jan 2020 17:43:57 +0100 Subject: [PATCH 0606/1253] Use Self instead of self return type --- src/libcore/fmt/builders.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index dd0f3ccb15841..8ba0e422e8f13 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -133,7 +133,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> { + pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self { self.result = self.result.and_then(|_| { if self.is_pretty() { if !self.has_fields { @@ -330,7 +330,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> { + pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self { self.result = self.result.and_then(|_| { if self.is_pretty() { if self.fields == 0 { @@ -492,7 +492,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> { + pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self { self.inner.entry(entry); self } @@ -521,7 +521,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entries(&mut self, entries: I) -> &mut DebugSet<'a, 'b> + pub fn entries(&mut self, entries: I) -> &mut Self where D: fmt::Debug, I: IntoIterator, @@ -624,7 +624,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> { + pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self { self.inner.entry(entry); self } @@ -653,7 +653,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entries(&mut self, entries: I) -> &mut DebugList<'a, 'b> + pub fn entries(&mut self, entries: I) -> &mut Self where D: fmt::Debug, I: IntoIterator, @@ -760,7 +760,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self { self.key(key).value(value) } @@ -797,7 +797,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ); /// ``` #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] - pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self { self.result = self.result.and_then(|_| { assert!( !self.has_key, @@ -862,7 +862,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ); /// ``` #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] - pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self { self.result = self.result.and_then(|_| { assert!(self.has_key, "attempted to format a map value before its key"); @@ -908,7 +908,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entries(&mut self, entries: I) -> &mut DebugMap<'a, 'b> + pub fn entries(&mut self, entries: I) -> &mut Self where K: fmt::Debug, V: fmt::Debug, From 06af44238f2b7a82995dc0a354403ab68dab7cc5 Mon Sep 17 00:00:00 2001 From: BaoshanPang Date: Fri, 17 Jan 2020 09:29:09 -0800 Subject: [PATCH 0607/1253] Support feature process_set_argv0 for VxWorks --- src/libstd/sys/vxworks/ext/process.rs | 18 ++++++++++++++ .../sys/vxworks/process/process_common.rs | 24 +++++++++++++++---- .../sys/vxworks/process/process_vxworks.rs | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/vxworks/ext/process.rs b/src/libstd/sys/vxworks/ext/process.rs index e535c4aa122f0..31e691dd1360b 100644 --- a/src/libstd/sys/vxworks/ext/process.rs +++ b/src/libstd/sys/vxworks/ext/process.rs @@ -2,6 +2,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::ffi::OsStr; use crate::io; use crate::process; use crate::sys; @@ -105,6 +106,15 @@ pub trait CommandExt { /// cross-platform `spawn` instead. #[stable(feature = "process_exec2", since = "1.9.0")] fn exec(&mut self) -> io::Error; + + /// Set executable argument + /// + /// Set the first process argument, `argv[0]`, to something other than the + /// default executable path. + #[unstable(feature = "process_set_argv0", issue = "66510")] + fn arg0(&mut self, arg: S) -> &mut process::Command + where + S: AsRef; } #[stable(feature = "rust1", since = "1.0.0")] @@ -130,6 +140,14 @@ impl CommandExt for process::Command { fn exec(&mut self) -> io::Error { self.as_inner_mut().exec(sys::process::Stdio::Inherit) } + + fn arg0(&mut self, arg: S) -> &mut process::Command + where + S: AsRef, + { + self.as_inner_mut().set_arg_0(arg.as_ref()); + self + } } /// Unix-specific extensions to [`process::ExitStatus`]. diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs index a8139a27537a9..6d5506bec5f7d 100644 --- a/src/libstd/sys/vxworks/process/process_common.rs +++ b/src/libstd/sys/vxworks/process/process_common.rs @@ -90,8 +90,8 @@ impl Command { let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), + args: vec![program.clone()], program, - args: Vec::new(), env: Default::default(), cwd: None, uid: None, @@ -104,11 +104,19 @@ impl Command { } } + pub fn set_arg_0(&mut self, arg: &OsStr) { + // Set a new arg0 + let arg = os2c(arg, &mut self.saw_nul); + debug_assert!(self.argv.0.len() > 1); + self.argv.0[0] = arg.as_ptr(); + self.args[0] = arg; + } + pub fn arg(&mut self, arg: &OsStr) { // Overwrite the trailing NULL pointer in `argv` and then add a new null // pointer. let arg = os2c(arg, &mut self.saw_nul); - self.argv.0[self.args.len() + 1] = arg.as_ptr(); + self.argv.0[self.args.len()] = arg.as_ptr(); self.argv.0.push(ptr::null()); // Also make sure we keep track of the owned value to schedule a @@ -133,6 +141,10 @@ impl Command { &self.argv.0 } + pub fn get_program(&self) -> &CStr { + &*self.program + } + #[allow(dead_code)] pub fn get_cwd(&self) -> &Option { &self.cwd @@ -315,8 +327,12 @@ impl ChildStdio { impl fmt::Debug for Command { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.program)?; - for arg in &self.args { + if self.program != self.args[0] { + write!(f, "[{:?}] ", self.program)?; + } + write!(f, "{:?}", self.args[0])?; + + for arg in &self.args[1..] { write!(f, " {:?}", arg)?; } Ok(()) diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs index ced70dea27f99..f7e84ae3de9c7 100644 --- a/src/libstd/sys/vxworks/process/process_vxworks.rs +++ b/src/libstd/sys/vxworks/process/process_vxworks.rs @@ -67,7 +67,7 @@ impl Command { let _lock = sys::os::env_lock(); let ret = libc::rtpSpawn( - self.get_argv()[0], // executing program + self.get_program().as_ptr(), self.get_argv().as_ptr() as *mut *const c_char, // argv c_envp as *mut *const c_char, 100 as c_int, // initial priority From 7b49c7d743beebc0f1f9dffcdfee8dab8b8c51ed Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 7 Jan 2020 07:03:45 -0800 Subject: [PATCH 0608/1253] Update LLVM to fix crash on Emscripten targets Adds a small Rust regression test for #66308. r? @alexcrichton --- src/test/ui/issues/issue-66308.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/test/ui/issues/issue-66308.rs diff --git a/src/test/ui/issues/issue-66308.rs b/src/test/ui/issues/issue-66308.rs new file mode 100644 index 0000000000000..5dc9378422cfd --- /dev/null +++ b/src/test/ui/issues/issue-66308.rs @@ -0,0 +1,8 @@ +// build-pass +// compile-flags: --crate-type lib + +// Regression test for LLVM crash affecting Emscripten targets + +pub fn foo() { + (0..0).rev().next(); +} From 601aa407ee8b520e676eb7adb61f83cad0c6a9b6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 24 Jan 2020 10:25:30 -0800 Subject: [PATCH 0609/1253] Add opt-level=0 to test --- src/test/ui/issues/issue-66308.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-66308.rs b/src/test/ui/issues/issue-66308.rs index 5dc9378422cfd..8460b359ae38a 100644 --- a/src/test/ui/issues/issue-66308.rs +++ b/src/test/ui/issues/issue-66308.rs @@ -1,5 +1,5 @@ // build-pass -// compile-flags: --crate-type lib +// compile-flags: --crate-type lib -C opt-level=0 // Regression test for LLVM crash affecting Emscripten targets From d14a323e74d0770960553fe79d0bcd578c393cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2020 10:35:13 -0800 Subject: [PATCH 0610/1253] Use more accurate return path spans No longer suggest `Box::new(if foo { Type1 } else { Type2 })`, instead suggesting `if foo { Box::new(Type1) } else { Box::new(Type2) }`. --- .../traits/error_reporting/suggestions.rs | 53 +++++++++++++---- src/test/ui/error-codes/E0746.fixed | 4 +- src/test/ui/error-codes/E0746.rs | 4 +- src/test/ui/error-codes/E0746.stderr | 2 +- .../dyn-trait-return-should-be-impl-trait.rs | 11 +++- ...n-trait-return-should-be-impl-trait.stderr | 57 +++++++++++-------- .../feature-gate-never_type_fallback.stderr | 2 +- 7 files changed, 91 insertions(+), 42 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 12c8de17d10f9..84f1260385553 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -600,12 +600,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Visit to make sure there's a single `return` type to suggest `impl Trait`, // otherwise suggest using `Box` or an enum. - let mut visitor = ReturnsVisitor(vec![]); + let mut visitor = ReturnsVisitor::new(); visitor.visit_body(&body); let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - let mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); + let mut ret_types = + visitor.returns.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); let (last_ty, all_returns_have_same_type) = ret_types.clone().fold( (None, true), |(last_ty, mut same): (std::option::Option>, bool), ty| { @@ -677,7 +678,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Suggest `-> Box` and `Box::new(returned_value)`. // Get all the return values and collect their span and suggestion. let mut suggestions = visitor - .0 + .returns .iter() .map(|expr| { ( @@ -737,10 +738,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { let body = hir.body(*body_id); // Point at all the `return`s in the function as they have failed trait bounds. - let mut visitor = ReturnsVisitor(vec![]); + let mut visitor = ReturnsVisitor::new(); visitor.visit_body(&body); let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - for expr in &visitor.0 { + for expr in &visitor.returns { if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { let ty = self.resolve_vars_if_possible(&returned_ty); err.span_label(expr.span, &format!("this returned value is of type `{}`", ty)); @@ -1691,7 +1692,16 @@ pub fn suggest_constraining_type_param( /// Collect all the returned expressions within the input expression. /// Used to point at the return spans when we want to suggest some change to them. -struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); +struct ReturnsVisitor<'v> { + returns: Vec<&'v hir::Expr<'v>>, + in_block_tail: bool, +} + +impl ReturnsVisitor<'_> { + fn new() -> Self { + ReturnsVisitor { returns: vec![], in_block_tail: false } + } +} impl<'v> Visitor<'v> for ReturnsVisitor<'v> { type Map = rustc::hir::map::Map<'v>; @@ -1701,20 +1711,41 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if let hir::ExprKind::Ret(Some(ex)) = ex.kind { - self.0.push(ex); + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => { + self.returns.push(ex); + } + hir::ExprKind::Block(block, _) if self.in_block_tail => { + self.in_block_tail = false; + for stmt in block.stmts { + hir::intravisit::walk_stmt(self, stmt); + } + self.in_block_tail = true; + if let Some(expr) = block.expr { + self.visit_expr(expr); + } + } + hir::ExprKind::Match(_, arms, _) if self.in_block_tail => { + for arm in arms { + self.visit_expr(arm.body); + } + } + // We need to walk to find `return`s in the entire body. + _ if !self.in_block_tail => hir::intravisit::walk_expr(self, ex), + _ => self.returns.push(ex), } - hir::intravisit::walk_expr(self, ex); } fn visit_body(&mut self, body: &'v hir::Body<'v>) { + let prev = self.in_block_tail; if body.generator_kind().is_none() { if let hir::ExprKind::Block(block, None) = body.value.kind { - if let Some(expr) = block.expr { - self.0.push(expr); + if block.expr.is_some() { + self.in_block_tail = true; } } } hir::intravisit::walk_body(self, body); + self.in_block_tail = prev; } } diff --git a/src/test/ui/error-codes/E0746.fixed b/src/test/ui/error-codes/E0746.fixed index ca8319aa020dc..70c7f791a2b88 100644 --- a/src/test/ui/error-codes/E0746.fixed +++ b/src/test/ui/error-codes/E0746.fixed @@ -10,9 +10,9 @@ fn foo() -> impl Trait { Struct } fn bar() -> impl Trait { //~ ERROR E0746 if true { - return 0; + return 0u32; } - 42 + 42u32 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index bf5ba8fff562a..fbf18246e1648 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -10,9 +10,9 @@ fn foo() -> dyn Trait { Struct } fn bar() -> dyn Trait { //~ ERROR E0746 if true { - return 0; + return 0u32; } - 42 + 42u32 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index e7a8fd304cabe..05c61f1149fb5 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -17,7 +17,7 @@ LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` +help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` | LL | fn bar() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index 93414379fd41a..dfcc22aee3485 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -22,6 +22,13 @@ fn bal() -> dyn Trait { //~ ERROR E0746 } 42 } +fn bax() -> dyn Trait { //~ ERROR E0746 + if true { + Struct + } else { + 42 + } +} fn bam() -> Box { if true { return Struct; //~ ERROR mismatched types @@ -52,9 +59,9 @@ fn baw() -> Box { // Suggest using `impl Trait` fn bat() -> dyn Trait { //~ ERROR E0746 if true { - return 0; + return 0u32; } - 42 + 42u32 } fn bay() -> dyn Trait { //~ ERROR E0746 if true { diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 0df6e8f8dc77c..fbad7ec124cb9 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -95,8 +95,27 @@ LL | } LL | Box::new(42) | +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13 + | +LL | fn bax() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on trait objects, see + = note: if all the returned values were of the same type you could use `impl Trait` as the return type + = note: for information on `impl Trait`, see + = note: you can create a new `enum` with a variant for each returned type +help: return a boxed trait object instead + | +LL | fn bax() -> Box { +LL | if true { +LL | Box::new(Struct) +LL | } else { +LL | Box::new(42) + | + error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:16 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16 | LL | fn bam() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -112,7 +131,7 @@ LL | return Struct; = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:5 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5 | LL | fn bam() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -128,7 +147,7 @@ LL | 42 = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:16 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16 | LL | fn baq() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -144,7 +163,7 @@ LL | return 0; = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:35:5 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5 | LL | fn baq() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -160,7 +179,7 @@ LL | 42 = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:39:9 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9 | LL | fn baz() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -176,7 +195,7 @@ LL | Struct = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:41:9 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9 | LL | fn baz() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -192,7 +211,7 @@ LL | 42 = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9 | LL | fn baw() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -208,7 +227,7 @@ LL | 0 = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9 | LL | fn baw() -> Box { | -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type @@ -224,38 +243,30 @@ LL | 42 = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html error[E0746]: return type cannot have an unboxed trait object - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` +help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` | LL | fn bat() -> impl Trait { | ^^^^^^^^^^ error[E0746]: return type cannot have an unboxed trait object - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:59:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:66:13 | LL | fn bay() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = note: for information on trait objects, see - = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see - = note: you can create a new `enum` with a variant for each returned type -help: return a boxed trait object instead - | -LL | fn bay() -> Box { -LL | Box::new(if true { -LL | 0u32 -LL | } else { -LL | 42u32 -LL | }) +help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` | +LL | fn bay() -> impl Trait { + | ^^^^^^^^^^ -error: aborting due to 18 previous errors +error: aborting due to 19 previous errors Some errors have detailed explanations: E0277, E0308, E0746. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 77288f1badac5..08e16f4693645 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -5,7 +5,7 @@ LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` LL | LL | panic!() - | -------- this returned value is of type `()` + | -------- this returned value is of type `!` | = note: the return type of a function must have a statically known size = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) From 110871a37a4c62a52ad85f941d8450794f277539 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 24 Jan 2020 11:12:33 -0800 Subject: [PATCH 0611/1253] New fix --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index a6f4c1bb07d58..a56b846ec7c96 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit a6f4c1bb07d58df5956d2c49be68547143f77b18 +Subproject commit a56b846ec7c96d8dc86418819baee40d70c92974 From 34d51b33787c9b2f59cb3283c8b57a290ab86437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2020 11:18:45 -0800 Subject: [PATCH 0612/1253] Increase suggestion code window from 6 lines to 20 --- src/librustc_errors/emitter.rs | 11 ++++++++--- src/test/ui/issues/issue-22644.stderr | 3 ++- .../unboxed-closure-sugar-lifetime-elision.stderr | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index b0e0cb611afaf..2149e46a1cfbc 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -456,9 +456,14 @@ impl Emitter for SilentEmitter { fn emit_diagnostic(&mut self, _: &Diagnostic) {} } -/// maximum number of lines we will print for each error; arbitrary. +/// Maximum number of lines we will print for each error; arbitrary. pub const MAX_HIGHLIGHT_LINES: usize = 6; -/// maximum number of suggestions to be shown +/// Maximum number of lines we will print for a multiline suggestion; arbitrary. +/// +/// This should be replaced with a more involved mechanism to output multiline suggestions that +/// more closely mimmics the regular diagnostic output, where irrelevant code lines are ellided. +pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 20; +/// Maximum number of suggestions to be shown /// /// Arbitrary, but taken from trait import suggestion limit pub const MAX_SUGGESTIONS: usize = 4; @@ -1521,7 +1526,7 @@ impl EmitterWriter { draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); let mut line_pos = 0; let mut lines = complete.lines(); - for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) { + for line in lines.by_ref().take(MAX_SUGGESTION_HIGHLIGHT_LINES) { // Print the span column to avoid confusion buffer.puts( row_num, diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 2bddcc2ba56ce..105cf73652586 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -74,7 +74,8 @@ LL | LL | as LL | LL | - ... +LL | usize) + | error: `<` is interpreted as a start of generic arguments for `usize`, not a shift --> $DIR/issue-22644.rs:32:31 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 0a028e44919a6..469425ea44ded 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -13,7 +13,8 @@ LL | dyn Foo(&isize) -> &isize >(); LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, LL | dyn Foo(&isize) -> (&isize, &isize) >(); LL | - ... +LL | let _: dyn Foo(&isize, &usize) -> &'lifetime usize; + | error: aborting due to previous error From d493dccef7ae1d2ca739fe828bf9556b44dc460a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2020 11:47:54 -0800 Subject: [PATCH 0613/1253] Apply `resolve_vars_if_possible` to returned types for more accurate suggestions --- src/librustc/traits/error_reporting/suggestions.rs | 8 ++++++-- .../impl-trait/dyn-trait-return-should-be-impl-trait.rs | 8 ++++---- .../dyn-trait-return-should-be-impl-trait.stderr | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 84f1260385553..cc2c97096e966 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -605,11 +605,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - let mut ret_types = - visitor.returns.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); + let mut ret_types = visitor + .returns + .iter() + .filter_map(|expr| tables.node_type_opt(expr.hir_id)) + .map(|ty| self.resolve_vars_if_possible(&ty)); let (last_ty, all_returns_have_same_type) = ret_types.clone().fold( (None, true), |(last_ty, mut same): (std::option::Option>, bool), ty| { + let ty = self.resolve_vars_if_possible(&ty); same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error; (Some(ty), same) }, diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index dfcc22aee3485..08bab5734fd7a 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -59,15 +59,15 @@ fn baw() -> Box { // Suggest using `impl Trait` fn bat() -> dyn Trait { //~ ERROR E0746 if true { - return 0u32; + return 0; } - 42u32 + 42 } fn bay() -> dyn Trait { //~ ERROR E0746 if true { - 0u32 + 0 } else { - 42u32 + 42 } } diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index fbad7ec124cb9..664a897c593fc 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -249,7 +249,7 @@ LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bat() -> impl Trait { | ^^^^^^^^^^ @@ -261,7 +261,7 @@ LL | fn bay() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bay() -> impl Trait { | ^^^^^^^^^^ From 45832839087da140eeb2a85a8b98927ec27ba21c Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 24 Jan 2020 20:52:16 +0000 Subject: [PATCH 0614/1253] Update new tests --- src/test/ui/borrowck/issue-7573.nll.stderr | 2 +- src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr | 2 +- src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr | 2 +- .../ui/borrowck/regions-escape-unboxed-closure.nll.stderr | 2 +- .../expect-region-supply-region.nll.stderr | 4 ++-- ...ions-bounded-method-type-parameters-trait-bound.nll.stderr | 2 +- src/test/ui/regions/regions-nested-fns.nll.stderr | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr index 0da715bbdb764..20afecfe5de79 100644 --- a/src/test/ui/borrowck/issue-7573.nll.stderr +++ b/src/test/ui/borrowck/issue-7573.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/issue-7573.rs:21:9 | LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); - | ---------------- `lines_to_use` is declared here, outside of the closure body + | ---------------- `lines_to_use` declared here, outside of the closure body LL | LL | let push_id = |installed_id: &CrateId| { | ------------ `installed_id` is a reference that is only valid in the closure body diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr index 4797a9d456cc1..68a0fe0b4f07b 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/regions-escape-bound-fn-2.rs:8:18 | LL | let mut x = None; - | ----- `x` is declared here, outside of the closure body + | ----- `x` declared here, outside of the closure body LL | with_int(|y| x = Some(y)); | - ^^^^^^^^^^^ `y` escapes the closure body here | | diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr index 2b3a9816e454d..d304de92c7e18 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/regions-escape-bound-fn.rs:8:18 | LL | let mut x: Option<&isize> = None; - | ----- `x` is declared here, outside of the closure body + | ----- `x` declared here, outside of the closure body LL | with_int(|y| x = Some(y)); | - ^^^^^^^^^^^ `y` escapes the closure body here | | diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr index 8ceefd25344a4..d9931302f75fc 100644 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/regions-escape-unboxed-closure.rs:6:23 | LL | let mut x: Option<&isize> = None; - | ----- `x` is declared here, outside of the closure body + | ----- `x` declared here, outside of the closure body LL | with_int(&mut |y| x = Some(y)); | - ^^^^^^^^^^^ `y` escapes the closure body here | | diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr index f816f27a89236..d7d716ed4cb0a 100644 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/expect-region-supply-region.rs:18:9 | LL | let mut f: Option<&u32> = None; - | ----- `f` is declared here, outside of the closure body + | ----- `f` declared here, outside of the closure body LL | closure_expecting_bound(|x| { | - `x` is a reference that is only valid in the closure body LL | f = Some(x); @@ -12,7 +12,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/expect-region-supply-region.rs:28:9 | LL | let mut f: Option<&u32> = None; - | ----- `f` is declared here, outside of the closure body + | ----- `f` declared here, outside of the closure body LL | closure_expecting_bound(|x: &u32| { | - `x` is a reference that is only valid in the closure body LL | f = Some(x); diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr index d352d119a70e8..92a3942c916b7 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr @@ -4,7 +4,7 @@ error[E0521]: borrowed data escapes outside of function LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { | - - `b` is a reference that is only valid in the function body | | - | `a` is declared here, outside of the function body + | `a` declared here, outside of the function body LL | // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. LL | f.method(b); | ^^^^^^^^^^^ `b` escapes the function body here diff --git a/src/test/ui/regions/regions-nested-fns.nll.stderr b/src/test/ui/regions/regions-nested-fns.nll.stderr index 305a76815aca9..9d966486f98d1 100644 --- a/src/test/ui/regions/regions-nested-fns.nll.stderr +++ b/src/test/ui/regions/regions-nested-fns.nll.stderr @@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/regions-nested-fns.rs:10:9 | LL | let mut ay = &y; - | ------ `ay` is declared here, outside of the closure body + | ------ `ay` declared here, outside of the closure body LL | LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { | - `z` is a reference that is only valid in the closure body From 600e385c43904eb4a5337427f3f6fb169fe32234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2020 14:03:35 -0800 Subject: [PATCH 0615/1253] review comments --- .../traits/error_reporting/suggestions.rs | 18 ++++++++---------- src/librustc_errors/emitter.rs | 2 +- src/test/ui/error-codes/E0746.fixed | 4 ++-- src/test/ui/error-codes/E0746.rs | 4 ++-- src/test/ui/error-codes/E0746.stderr | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index cc2c97096e966..b2aec78c175ad 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -600,7 +600,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Visit to make sure there's a single `return` type to suggest `impl Trait`, // otherwise suggest using `Box` or an enum. - let mut visitor = ReturnsVisitor::new(); + let mut visitor = ReturnsVisitor::default(); visitor.visit_body(&body); let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); @@ -742,7 +742,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { let body = hir.body(*body_id); // Point at all the `return`s in the function as they have failed trait bounds. - let mut visitor = ReturnsVisitor::new(); + let mut visitor = ReturnsVisitor::default(); visitor.visit_body(&body); let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); for expr in &visitor.returns { @@ -1696,17 +1696,12 @@ pub fn suggest_constraining_type_param( /// Collect all the returned expressions within the input expression. /// Used to point at the return spans when we want to suggest some change to them. +#[derive(Default)] struct ReturnsVisitor<'v> { returns: Vec<&'v hir::Expr<'v>>, in_block_tail: bool, } -impl ReturnsVisitor<'_> { - fn new() -> Self { - ReturnsVisitor { returns: vec![], in_block_tail: false } - } -} - impl<'v> Visitor<'v> for ReturnsVisitor<'v> { type Map = rustc::hir::map::Map<'v>; @@ -1715,6 +1710,10 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + // Visit every expression to detect `return` paths, either through the function's tail + // expression or `return` statements. We walk all nodes to find `return` statements, but + // we only care about tail expressions when `in_block_tail` is `true`, which means that + // they're in the return path of the function body. match ex.kind { hir::ExprKind::Ret(Some(ex)) => { self.returns.push(ex); @@ -1741,7 +1740,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } fn visit_body(&mut self, body: &'v hir::Body<'v>) { - let prev = self.in_block_tail; + assert!(!self.in_block_tail); if body.generator_kind().is_none() { if let hir::ExprKind::Block(block, None) = body.value.kind { if block.expr.is_some() { @@ -1750,6 +1749,5 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } } hir::intravisit::walk_body(self, body); - self.in_block_tail = prev; } } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 2149e46a1cfbc..b62e4223fea10 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -461,7 +461,7 @@ pub const MAX_HIGHLIGHT_LINES: usize = 6; /// Maximum number of lines we will print for a multiline suggestion; arbitrary. /// /// This should be replaced with a more involved mechanism to output multiline suggestions that -/// more closely mimmics the regular diagnostic output, where irrelevant code lines are ellided. +/// more closely mimmics the regular diagnostic output, where irrelevant code lines are elided. pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 20; /// Maximum number of suggestions to be shown /// diff --git a/src/test/ui/error-codes/E0746.fixed b/src/test/ui/error-codes/E0746.fixed index 70c7f791a2b88..ca8319aa020dc 100644 --- a/src/test/ui/error-codes/E0746.fixed +++ b/src/test/ui/error-codes/E0746.fixed @@ -10,9 +10,9 @@ fn foo() -> impl Trait { Struct } fn bar() -> impl Trait { //~ ERROR E0746 if true { - return 0u32; + return 0; } - 42u32 + 42 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index fbf18246e1648..bf5ba8fff562a 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -10,9 +10,9 @@ fn foo() -> dyn Trait { Struct } fn bar() -> dyn Trait { //~ ERROR E0746 if true { - return 0u32; + return 0; } - 42u32 + 42 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 05c61f1149fb5..e7a8fd304cabe 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -17,7 +17,7 @@ LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `u32`, which implements `Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bar() -> impl Trait { | ^^^^^^^^^^ From b626202087dff72216c14e08e11d936136dc2126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2020 18:03:09 -0800 Subject: [PATCH 0616/1253] Do not ICE on multipart suggestions touching multiple files When encountering a multipart suggestion with spans belonging to different contexts, skip that suggestion. --- src/librustc_errors/lib.rs | 11 ++++++----- .../ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 827e9b831f32d..17b293401f89e 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -185,16 +185,17 @@ impl CodeSuggestion { !invalid }) .cloned() - .map(|mut substitution| { + .filter_map(|mut substitution| { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. substitution.parts.sort_by_key(|part| part.span.lo()); // Find the bounding span. - let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); - let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap(); + let lo = substitution.parts.iter().map(|part| part.span.lo()).min()?; + let hi = substitution.parts.iter().map(|part| part.span.hi()).max()?; let bounding_span = Span::with_root_ctxt(lo, hi); - let lines = cm.span_to_lines(bounding_span).unwrap(); + // The different spans might belong to different contexts, if so ignore suggestion. + let lines = cm.span_to_lines(bounding_span).ok()?; assert!(!lines.lines.is_empty()); // To build up the result, we do this for each span: @@ -244,7 +245,7 @@ impl CodeSuggestion { while buf.ends_with('\n') { buf.pop(); } - (buf, substitution.parts, only_capitalization) + Some((buf, substitution.parts, only_capitalization)) }) .collect() } diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 0d7fb845a40ee..a316d8f1698ac 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:357:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 1605276cc2ff3319a7f360b389be1a53d0d5751c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 23 Jan 2020 18:19:59 -0500 Subject: [PATCH 0617/1253] Add some type-alias-impl-trait regression tests Fixes #57611 Fixes #57807 --- .../issue-57611-trait-alias.rs | 27 ++++++++++++++++ .../issue-57611-trait-alias.stderr | 23 ++++++++++++++ .../issue-57807-associated-type.rs | 31 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs new file mode 100644 index 0000000000000..1c2051e7eaeeb --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -0,0 +1,27 @@ +// Regression test for issue #57611 +// Ensures that we don't ICE +// FIXME: This should compile, but it currently doesn't + +#![feature(trait_alias)] +#![feature(type_alias_impl_trait)] + +trait Foo { + type Bar: Baz; + + fn bar(&self) -> Self::Bar; +} + +struct X; + +impl Foo for X { + type Bar = impl Baz; //~ ERROR type mismatch in closure arguments + //~^ ERROR type mismatch resolving + + fn bar(&self) -> Self::Bar { + |x| x + } +} + +trait Baz = Fn(&A) -> &B; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr new file mode 100644 index 0000000000000..f648b7bfc991d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -0,0 +1,23 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-57611-trait-alias.rs:17:5 + | +LL | type Bar = impl Baz; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` +... +LL | |x| x + | ----- found signature of `fn(_) -> _` + | + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-57611-trait-alias.rs:21:9: 21:14] as std::ops::FnOnce<(&'r X,)>>::Output == &'r X` + --> $DIR/issue-57611-trait-alias.rs:17:5 + | +LL | type Bar = impl Baz; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime + | + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs new file mode 100644 index 0000000000000..fcab2c7db2605 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs @@ -0,0 +1,31 @@ +// Regression test for issue #57807 - ensure +// that we properly unify associated types within +// a type alias impl trait +// check-pass +#![feature(type_alias_impl_trait)] + +trait Bar { + type A; +} + +impl Bar for () { + type A = (); +} + +trait Foo { + type A; + type B: Bar
; + + fn foo() -> Self::B; +} + +impl Foo for () { + type A = (); + type B = impl Bar; + + fn foo() -> Self::B { + () + } +} + +fn main() {} From ea42b1c5b85f649728e3a3b334489bac6dce890a Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 24 Jan 2020 21:24:24 -0500 Subject: [PATCH 0618/1253] [self-profiler] Use `ThreadId::as_u64()` instead of transmute --- src/librustc_data_structures/lib.rs | 1 + src/librustc_data_structures/profiling.rs | 9 ++------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 6db2910bca496..aaac7fb4460cd 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -23,6 +23,7 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] +#![feature(thread_id_value)] #![cfg_attr(unix, feature(libc))] #![allow(rustc::default_hash_types)] diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 44cef727f034b..35bc6e298ac60 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -88,7 +88,6 @@ use std::fs; use std::path::Path; use std::process; use std::sync::Arc; -use std::thread::ThreadId; use std::time::{Duration, Instant}; use std::u32; @@ -149,10 +148,6 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("query-keys", EventFilter::QUERY_KEYS), ]; -fn thread_id_to_u32(tid: ThreadId) -> u32 { - unsafe { std::mem::transmute::(tid) as u32 } -} - /// Something that uniquely identifies a query invocation. pub struct QueryInvocationId(pub u32); @@ -318,7 +313,7 @@ impl SelfProfilerRef { ) { drop(self.exec(event_filter, |profiler| { let event_id = StringId::new_virtual(query_invocation_id.0); - let thread_id = thread_id_to_u32(std::thread::current().id()); + let thread_id = std::thread::current().id().as_u64() as u32; profiler.profiler.record_instant_event( event_kind(profiler), @@ -477,7 +472,7 @@ impl<'a> TimingGuard<'a> { event_kind: StringId, event_id: EventId, ) -> TimingGuard<'a> { - let thread_id = thread_id_to_u32(std::thread::current().id()); + let thread_id = std::thread::current().id().as_u64() as u32; let raw_profiler = &profiler.profiler; let timing_guard = raw_profiler.start_recording_interval_event(event_kind, event_id, thread_id); From 2acf5a30bac39d6fd326b0d82b047b9e59b64692 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 24 Jan 2020 21:35:21 -0500 Subject: [PATCH 0619/1253] [self-profiler] Clean up `EventFilter` --- src/librustc_data_structures/profiling.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 35bc6e298ac60..90f74328a1d51 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -128,17 +128,13 @@ bitflags::bitflags! { Self::QUERY_PROVIDERS.bits | Self::QUERY_BLOCKED.bits | Self::INCR_CACHE_LOADS.bits; - - // empty() and none() aren't const-fns unfortunately - const NONE = 0; - const ALL = !Self::NONE.bits; } } // keep this in sync with the `-Z self-profile-events` help message in librustc_session/options.rs const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ - ("none", EventFilter::NONE), - ("all", EventFilter::ALL), + ("none", EventFilter::empty()), + ("all", EventFilter::all()), ("default", EventFilter::DEFAULT), ("generic-activity", EventFilter::GENERIC_ACTIVITIES), ("query-provider", EventFilter::QUERY_PROVIDERS), @@ -180,7 +176,7 @@ impl SelfProfilerRef { // If there is no SelfProfiler then the filter mask is set to NONE, // ensuring that nothing ever tries to actually access it. let event_filter_mask = - profiler.as_ref().map(|p| p.event_filter_mask).unwrap_or(EventFilter::NONE); + profiler.as_ref().map(|p| p.event_filter_mask).unwrap_or(EventFilter::empty()); SelfProfilerRef { profiler, From cdc6898a900014792649c557a97668236dd0d1fd Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 25 Jan 2020 17:58:10 +0900 Subject: [PATCH 0620/1253] Update submodules to rust-lang --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 62cbbdd9a3a06..003e50d0788e4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,13 +15,13 @@ url = https://github.com/rust-lang/book.git [submodule "src/tools/rls"] path = src/tools/rls - url = https://github.com/rust-lang-nursery/rls.git + url = https://github.com/rust-lang/rls.git [submodule "src/tools/clippy"] path = src/tools/clippy - url = https://github.com/rust-lang-nursery/rust-clippy.git + url = https://github.com/rust-lang/rust-clippy.git [submodule "src/tools/rustfmt"] path = src/tools/rustfmt - url = https://github.com/rust-lang-nursery/rustfmt.git + url = https://github.com/rust-lang/rustfmt.git [submodule "src/tools/miri"] path = src/tools/miri url = https://github.com/rust-lang/miri.git From ae31436ac739d2fe9fdb45fec1364db6007bd359 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 24 Jan 2020 21:04:17 +0100 Subject: [PATCH 0621/1253] Don't use spaces before type ascription like colons --- src/librustc/ty/print/pretty.rs | 6 +++--- src/test/ui/error-codes/e0119/complex-impl.stderr | 2 +- .../issue-62326-parameter-out-of-range.rs | 3 +-- .../issue-62326-parameter-out-of-range.stderr | 2 +- src/test/ui/reject-specialized-drops-8142.rs | 6 +++--- src/test/ui/reject-specialized-drops-8142.stderr | 6 +++--- src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/enum.stderr | 6 +++--- src/test/ui/rfc-2093-infer-outlives/explicit-dyn.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/explicit-enum.stderr | 2 +- .../ui/rfc-2093-infer-outlives/explicit-projection.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/explicit-struct.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/infer-static.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/nested-enum.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/nested-regions.stderr | 6 +++--- src/test/ui/rfc-2093-infer-outlives/nested-structs.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/nested-union.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/projection.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/reference.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/self-dyn.stderr | 2 +- src/test/ui/rfc-2093-infer-outlives/self-structs.stderr | 2 +- src/test/ui/trivial-bounds/trivial-bounds-lint.stderr | 6 +++--- 23 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 7dd3c8f4a7295..db539f9195c9d 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -889,7 +889,7 @@ pub trait PrettyPrinter<'tcx>: // fallback p!(write("{:?}", ct.val)); if print_ty { - p!(write(" : "), print(ct.ty)); + p!(write(": "), print(ct.ty)); } } }; @@ -1009,7 +1009,7 @@ pub trait PrettyPrinter<'tcx>: // fallback p!(write("{:?}", ct)); if print_ty { - p!(write(" : "), print(ty)); + p!(write(": "), print(ty)); } } } @@ -1610,7 +1610,7 @@ where type Error = P::Error; fn print(&self, mut cx: P) -> Result { define_scoped_cx!(cx); - p!(print(self.0), write(" : "), print(self.1)); + p!(print(self.0), write(": "), print(self.1)); Ok(cx) } } diff --git a/src/test/ui/error-codes/e0119/complex-impl.stderr b/src/test/ui/error-codes/e0119/complex-impl.stderr index 0c18a1fbd1fd2..2cc09e8b1479c 100644 --- a/src/test/ui/error-codes/e0119/complex-impl.stderr +++ b/src/test/ui/error-codes/e0119/complex-impl.stderr @@ -6,7 +6,7 @@ LL | impl External for (Q, R) {} | = note: conflicting implementation in crate `complex_impl_support`: - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box, V, W>) - where >::Output == V, ::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, ::Output: std::marker::Copy; + where >::Output == V, ::Item == T, 'b: 'a, T: 'a, U: std::ops::FnOnce<(T,)>, U: 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, ::Output: std::marker::Copy; error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/complex-impl.rs:9:1 diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs index db0da40aab08d..60466d0bcd040 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs @@ -4,9 +4,8 @@ // FIXME(generic-associated-types) Investigate why this doesn't compile. trait Iterator { -//~^ ERROR the requirement `for<'a> ::Item<'a> : 'a` is not satisfied + //~^ ERROR the requirement `for<'a> ::Item<'a>: 'a` is not satisfied type Item<'a>: 'a; } - fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr index 07169700f3935..4dc69cdd1dcf0 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr @@ -1,4 +1,4 @@ -error[E0280]: the requirement `for<'a> ::Item<'a> : 'a` is not satisfied +error[E0280]: the requirement `for<'a> ::Item<'a>: 'a` is not satisfied --> $DIR/issue-62326-parameter-out-of-range.rs:6:1 | LL | trait Iterator { diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/reject-specialized-drops-8142.rs index d7fec8802f08b..c4671736d79ec 100644 --- a/src/test/ui/reject-specialized-drops-8142.rs +++ b/src/test/ui/reject-specialized-drops-8142.rs @@ -21,11 +21,11 @@ struct TupleStruct(T); union Union { f: T } impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT - //~^ ERROR `Drop` impl requires `'adds_bnd : 'al` + //~^ ERROR `Drop` impl requires `'adds_bnd: 'al` fn drop(&mut self) { } } impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT - //~^ ERROR `Drop` impl requires `'adds_bnd : 'al` + //~^ ERROR `Drop` impl requires `'adds_bnd: 'al` fn drop(&mut self) { } } impl<'ml> Drop for M<'ml> { fn drop(&mut self) { } } // ACCEPT @@ -44,7 +44,7 @@ impl Drop for Q { fn drop(&mut self) { } } // REJECT //~^ ERROR `Drop` impl requires `AddsBnd: Bound` impl<'rbnd,AddsRBnd:'rbnd> Drop for R { fn drop(&mut self) { } } // REJECT -//~^ ERROR `Drop` impl requires `AddsRBnd : 'rbnd` +//~^ ERROR `Drop` impl requires `AddsRBnd: 'rbnd` impl Drop for S { fn drop(&mut self) { } } // ACCEPT diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index 14618df90cb62..c09418de51830 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -10,7 +10,7 @@ note: the implementor must specify the same requirement LL | union Union { f: T } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0367]: `Drop` impl requires `'adds_bnd : 'al` but the struct it is implemented for does not +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 | LL | impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT @@ -22,7 +22,7 @@ note: the implementor must specify the same requirement LL | struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0367]: `Drop` impl requires `'adds_bnd : 'al` but the struct it is implemented for does not +error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not --> $DIR/reject-specialized-drops-8142.rs:27:67 | LL | impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT @@ -73,7 +73,7 @@ note: the implementor must specify the same requirement LL | struct Q { x: *const Tq } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0367]: `Drop` impl requires `AddsRBnd : 'rbnd` but the struct it is implemented for does not +error[E0367]: `Drop` impl requires `AddsRBnd: 'rbnd` but the struct it is implemented for does not --> $DIR/reject-specialized-drops-8142.rs:46:21 | LL | impl<'rbnd,AddsRBnd:'rbnd> Drop for R { fn drop(&mut self) { } } // REJECT diff --git a/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr b/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr index 3368e35d304f0..1da8e648251ad 100644 --- a/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr @@ -6,7 +6,7 @@ LL | | bar: std::slice::IterMut<'a, T> LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/enum.stderr b/src/test/ui/rfc-2093-infer-outlives/enum.stderr index dd56c1f79c712..868ca2c4587d1 100644 --- a/src/test/ui/rfc-2093-infer-outlives/enum.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/enum.stderr @@ -6,7 +6,7 @@ LL | | One(Bar<'a, T>) LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: rustc_outlives --> $DIR/enum.rs:13:1 @@ -16,7 +16,7 @@ LL | | field2: &'b U LL | | } | |_^ | - = note: U : 'b + = note: U: 'b error: rustc_outlives --> $DIR/enum.rs:19:1 @@ -26,7 +26,7 @@ LL | | One(&'c Yang) LL | | } | |_^ | - = note: K : 'c + = note: K: 'c error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-dyn.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-dyn.stderr index c87ef6c391b11..adb718ad794a6 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-dyn.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-dyn.stderr @@ -7,7 +7,7 @@ LL | | foo: Box> LL | | } | |_^ | - = note: A : 'a + = note: A: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-enum.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-enum.stderr index 611df047cffc3..062f5d5e9a73d 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-enum.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-enum.stderr @@ -6,7 +6,7 @@ LL | | One(Bar<'a, U>) LL | | } | |_^ | - = note: U : 'a + = note: U: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-projection.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-projection.stderr index 8e9b158ab7c9d..a85aa3d7565ba 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-projection.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-projection.stderr @@ -7,7 +7,7 @@ LL | | foo: >::Type LL | | } | |_^ | - = note: B : 'a + = note: B: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-struct.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-struct.stderr index cbff2b777fe71..309c54bb44934 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-struct.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-struct.stderr @@ -6,7 +6,7 @@ LL | | bar: Bar<'b, U> LL | | } | |_^ | - = note: U : 'b + = note: U: 'b error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr index 8aa246e8bfeb3..47c283faf5073 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr @@ -6,7 +6,7 @@ LL | | bar: Bar<'b, U> LL | | } | |_^ | - = note: U : 'b + = note: U: 'b error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr index 106db765f7ead..6fbb7cf4cb8a6 100644 --- a/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr @@ -6,7 +6,7 @@ LL | | bar: Bar LL | | } | |_^ | - = note: U : 'static + = note: U: 'static error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-enum.stderr b/src/test/ui/rfc-2093-infer-outlives/nested-enum.stderr index 6b143ba7eb963..10387f51b1e44 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-enum.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/nested-enum.stderr @@ -7,7 +7,7 @@ LL | | One(Bar<'a, T>) LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-regions.stderr b/src/test/ui/rfc-2093-infer-outlives/nested-regions.stderr index 4d8f7b7c8c465..ffdd5542bb4b5 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-regions.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/nested-regions.stderr @@ -6,9 +6,9 @@ LL | | x: &'a &'b T LL | | } | |_^ | - = note: 'b : 'a - = note: T : 'a - = note: T : 'b + = note: 'b: 'a + = note: T: 'a + = note: T: 'b error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-structs.stderr b/src/test/ui/rfc-2093-infer-outlives/nested-structs.stderr index 17d7c014e1029..86bcbe640e4bc 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-structs.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/nested-structs.stderr @@ -6,7 +6,7 @@ LL | | field1: Bar<'a, T> LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr b/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr index a42285a56d089..e0f248fa38a04 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr @@ -6,7 +6,7 @@ LL | | field1: Bar<'a, T> LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/projection.stderr b/src/test/ui/rfc-2093-infer-outlives/projection.stderr index 8a91c44c5806e..3746bab4d5496 100644 --- a/src/test/ui/rfc-2093-infer-outlives/projection.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/projection.stderr @@ -6,7 +6,7 @@ LL | | bar: &'a T::Item LL | | } | |_^ | - = note: ::Item : 'a + = note: ::Item: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/reference.stderr b/src/test/ui/rfc-2093-infer-outlives/reference.stderr index adb1c4a629042..d69aaf6f849fa 100644 --- a/src/test/ui/rfc-2093-infer-outlives/reference.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/reference.stderr @@ -6,7 +6,7 @@ LL | | bar: &'a T, LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/self-dyn.stderr b/src/test/ui/rfc-2093-infer-outlives/self-dyn.stderr index 0be14a6956f45..77577fe09457e 100644 --- a/src/test/ui/rfc-2093-infer-outlives/self-dyn.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/self-dyn.stderr @@ -7,7 +7,7 @@ LL | | foo: Box> LL | | } | |_^ | - = note: A : 'a + = note: A: 'a error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/self-structs.stderr b/src/test/ui/rfc-2093-infer-outlives/self-structs.stderr index b32c9743e9edb..b972ad8446602 100644 --- a/src/test/ui/rfc-2093-infer-outlives/self-structs.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/self-structs.stderr @@ -6,7 +6,7 @@ LL | | field1: dyn Bar<'a, 'b, T> LL | | } | |_^ | - = note: T : 'a + = note: T: 'a error: aborting due to previous error diff --git a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr index 2f4b2df24cd54..37cf6f89d6737 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr @@ -22,19 +22,19 @@ error: Trait bound i32: Z does not depend on any type or lifetime parameters LL | fn global_projection() where i32: Z {} | ^^^^^^^^^^ -error: Lifetime bound i32 : 'static does not depend on any type or lifetime parameters +error: Lifetime bound i32: 'static does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-lint.rs:29:34 | LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {} | ^^^^^^^ -error: Lifetime bound &'static str : 'static does not depend on any type or lifetime parameters +error: Lifetime bound &'static str: 'static does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-lint.rs:29:57 | LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {} | ^^^^^^^ -error: Lifetime bound 'static : 'static does not depend on any type or lifetime parameters +error: Lifetime bound 'static: 'static does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-lint.rs:35:37 | LL | fn global_outlives() where 'static: 'static {} From 7fb8f7d85dcfc135926da5b11042e21b060e98a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 25 Jan 2020 17:41:55 +0100 Subject: [PATCH 0622/1253] clean up error codeS E0229 and E0261 --- src/librustc_error_codes/error_codes/E0229.md | 4 +++- src/librustc_error_codes/error_codes/E0261.md | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0229.md b/src/librustc_error_codes/error_codes/E0229.md index a8bd341a62ba0..a8fab057d43a0 100644 --- a/src/librustc_error_codes/error_codes/E0229.md +++ b/src/librustc_error_codes/error_codes/E0229.md @@ -1,5 +1,7 @@ An associated type binding was done outside of the type parameter declaration -and `where` clause. Erroneous code example: +and `where` clause. + +Erroneous code example: ```compile_fail,E0229 pub trait Foo { diff --git a/src/librustc_error_codes/error_codes/E0261.md b/src/librustc_error_codes/error_codes/E0261.md index 21cf8e70452e0..e326843739638 100644 --- a/src/librustc_error_codes/error_codes/E0261.md +++ b/src/librustc_error_codes/error_codes/E0261.md @@ -1,7 +1,6 @@ -When using a lifetime like `'a` in a type, it must be declared before being -used. +An undeclared lifetime was used. -These two examples illustrate the problem: +Erroneous code example: ```compile_fail,E0261 // error, use of undeclared lifetime name `'a` From 7e3c51d085d9eaa2204cc18763bc7d98b66435fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 16 Jan 2020 00:00:00 +0000 Subject: [PATCH 0623/1253] Instrument C / C++ in MemorySanitizer example Modify the example to instrument C / C++ in addition to Rust, since it will be generally required (e.g., when using libbacktrace for symbolication). Additionally use rustc specific flag to track the origins of unitialized memory rather than LLVM one. --- .../unstable-book/src/compiler-flags/sanitizer.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index cbb90bd3bb331..c799374354b3e 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -96,7 +96,7 @@ Shadow byte legend (one shadow byte represents 8 application bytes): ## MemorySanitizer Use of uninitialized memory. Note that we are using `-Zbuild-std` to instrument -standard library, and passing `-msan-track-origins=2` to the LLVM to track +the standard library, and passing `-Zsanitizer-track-origins` to track the origins of uninitialized memory: ```shell @@ -111,7 +111,15 @@ fn main() { } } -$ env RUSTFLAGS="-Zsanitizer=memory -Cllvm-args=-msan-track-origins=2" cargo -Zbuild-std run --target x86_64-unknown-linux-gnu +$ export \ + CC=clang \ + CXX=clang++ \ + CFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ + CXXFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ + RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \ + RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' +$ cargo clean +$ cargo -Zbuild-std run --target x86_64-unknown-linux-gnu ==9416==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x560c04f7488a in core::fmt::num::imp::fmt_u64::haa293b0b098501ca $RUST/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/src/libcore/fmt/num.rs:202:16 ... From 16709f032cfaa0b37a83bc798f0dd4a30d2b2c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 25 Jan 2020 12:26:33 -0800 Subject: [PATCH 0624/1253] Revert suggestion window size change --- src/librustc_errors/emitter.rs | 2 +- src/test/ui/issues/issue-22644.stderr | 3 +-- .../unboxed-closure-sugar-lifetime-elision.stderr | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index b62e4223fea10..7218730538a4b 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -462,7 +462,7 @@ pub const MAX_HIGHLIGHT_LINES: usize = 6; /// /// This should be replaced with a more involved mechanism to output multiline suggestions that /// more closely mimmics the regular diagnostic output, where irrelevant code lines are elided. -pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 20; +pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 6; /// Maximum number of suggestions to be shown /// /// Arbitrary, but taken from trait import suggestion limit diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 105cf73652586..2bddcc2ba56ce 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -74,8 +74,7 @@ LL | LL | as LL | LL | -LL | usize) - | + ... error: `<` is interpreted as a start of generic arguments for `usize`, not a shift --> $DIR/issue-22644.rs:32:31 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 469425ea44ded..0a028e44919a6 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -13,8 +13,7 @@ LL | dyn Foo(&isize) -> &isize >(); LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, LL | dyn Foo(&isize) -> (&isize, &isize) >(); LL | -LL | let _: dyn Foo(&isize, &usize) -> &'lifetime usize; - | + ... error: aborting due to previous error From 3fb18104761fe5b6a8a70435ccff54c65400f360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 25 Jan 2020 12:46:43 -0800 Subject: [PATCH 0625/1253] Use better bound names in `-Zverbose` mode --- src/librustc/infer/error_reporting/mod.rs | 10 +++++++--- .../propagate-from-trait-match.stderr | 2 +- src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr | 4 ++-- .../ty-outlives/projection-no-regions-closure.stderr | 4 ++-- .../ui/nll/ty-outlives/projection-no-regions-fn.stderr | 4 ++-- .../ty-outlives/projection-one-region-closure.stderr | 4 ++-- .../projection-two-region-trait-bound-closure.stderr | 4 ++-- .../ty-param-closure-approximate-lower-bound.stderr | 2 +- .../ty-param-closure-outlives-from-return-type.stderr | 4 ++-- .../ty-param-closure-outlives-from-where-clause.stderr | 4 ++-- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 77182b97fd450..58566bdcc3549 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1778,8 +1778,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let mut err = match *sub { - ty::ReEarlyBound(_) - | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(..), .. }) => { + ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. }) + | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }) => { // Does the required lifetime have a nice name we can print? let mut err = struct_span_err!( self.tcx.sess, @@ -1788,7 +1788,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "{} may not live long enough", labeled_user_string ); - binding_suggestion(&mut err, type_param_span, bound_kind, sub); + // Explicitely use the name instead of `sub`'s `Display` impl. The `Display` impl + // for the bound is not suitable for suggestions when `-Zverbose` is set because it + // uses `Debug` output, so we handle it specially here so that suggestions are + // always correct. + binding_suggestion(&mut err, type_param_span, bound_kind, name); err } diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 5317bb6a1b13e..b705ad9009a29 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -45,7 +45,7 @@ LL | | require(value); LL | | }); | |_____^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr index 32a494c5d1687..053aef951f264 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr @@ -4,7 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | fn no_region<'a, T>(x: Box) -> impl Debug + 'a | ^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error[E0309]: the parameter type `T` may not live long enough --> $DIR/impl-trait-outlives.rs:22:42 @@ -12,7 +12,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a | ^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index bff8c662d0def..84365465eda86 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -31,7 +31,7 @@ error[E0309]: the associated type `::Item` may not liv LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `::Item: 'a`... note: external requirements --> $DIR/projection-no-regions-closure.rs:34:23 @@ -92,7 +92,7 @@ error[E0309]: the associated type `::Item` may not liv LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `::Item: 'a`... note: external requirements --> $DIR/projection-no-regions-closure.rs:52:23 diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr index 190a2cdfc07aa..b0338de9333b4 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr @@ -4,7 +4,7 @@ error[E0309]: the associated type `::Item` may not liv LL | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `::Item: 'a`... error[E0309]: the associated type `::Item` may not live long enough --> $DIR/projection-no-regions-fn.rs:28:5 @@ -12,7 +12,7 @@ error[E0309]: the associated type `::Item` may not liv LL | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `::Item: 'a`... error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 6d1fbcb8f5bfd..118a849f98416 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -33,7 +33,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:15 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(DefId(0:16 ~ projection_one_region_closure[317d]::no_relationships_late[0]::'a[0]), 'a))`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:45:39 @@ -82,7 +82,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:56:39 diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 1bd97c1caa4ae..ff402f89ae861 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -32,7 +32,7 @@ error[E0309]: the associated type `>::AssocType` may LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `>::AssocType: ReFree(DefId(0:17 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(DefId(0:18 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]::'a[0]), 'a))`... + = help: consider adding an explicit lifetime bound `>::AssocType: 'a`... note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 @@ -67,7 +67,7 @@ error[E0309]: the associated type `>::AssocType` may LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `>::AssocType: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `>::AssocType: 'a`... note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:61:29 diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index a213f423e3c8d..9b08a10749673 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -53,7 +53,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | twice(cell, value, |a, b| invoke(a, b)); | ^^^^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:12 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(DefId(0:13 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::'a[0]), 'a))`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index a488637bbc5c2..3cd1f4358710f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -31,7 +31,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | with_signature(x, |y| y) | ^^^^^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-return-type.rs:41:5 @@ -39,7 +39,7 @@ error[E0309]: the parameter type `T` may not live long enough LL | x | ^ | - = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... + = help: consider adding an explicit lifetime bound `T: 'a`... error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 62dfe94e38493..4740ed645f1da 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -46,7 +46,7 @@ LL | | require(&x, &y) LL | | }) | |_____^ | - = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:11 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(DefId(0:12 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::'a[0]), 'a))`... + = help: consider adding an explicit lifetime bound `T: 'a`... note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 @@ -126,7 +126,7 @@ LL | | require(&x, &y) LL | | }) | |_____^ | - = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:19 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(DefId(0:20 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::'a[0]), 'a))`... + = help: consider adding an explicit lifetime bound `T: 'a`... note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 From 787c458eeb20e447989124e2900e02e8e03b1c51 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 20 Jan 2020 22:22:36 +0200 Subject: [PATCH 0626/1253] Don't use ExpnKind::descr to get the name of a bang macro. --- src/librustc_lint/internal.rs | 6 ++++-- src/librustc_save_analysis/lib.rs | 21 ++++++++++++++------- src/librustc_span/hygiene.rs | 6 ++++-- src/tools/clippy | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 91aeccbb5e334..8480c85075dd4 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -6,6 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; +use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::symbol::{sym, Symbol}; use syntax::ast::{Ident, Item, ItemKind}; @@ -226,8 +227,9 @@ impl EarlyLintPass for LintPassImpl { if last.ident.name == sym::LintPass { let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); let call_site = expn_data.call_site; - if expn_data.kind.descr() != sym::impl_lint_pass - && call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass + if expn_data.kind != ExpnKind::Macro(MacroKind::Bang, sym::impl_lint_pass) + && call_site.ctxt().outer_expn_data().kind + != ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass) { cx.struct_span_lint( LINT_PASS_IMPL_WITHOUT_MACRO, diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 537fe198a0c39..f44ce6f4eac27 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -776,12 +776,19 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callsite_span = self.span_from_span(callsite); let callee = span.source_callee()?; - // Ignore attribute macros, their spans are usually mangled - if let ExpnKind::Macro(MacroKind::Attr, _) | ExpnKind::Macro(MacroKind::Derive, _) = - callee.kind - { - return None; - } + let mac_name = match callee.kind { + ExpnKind::Macro(mac_kind, name) => match mac_kind { + MacroKind::Bang => name, + + // Ignore attribute macros, their spans are usually mangled + // FIXME(eddyb) is this really the case anymore? + MacroKind::Attr | MacroKind::Derive => return None, + }, + + // These are not macros. + // FIXME(eddyb) maybe there is a way to handle them usefully? + ExpnKind::Root | ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => return None, + }; // If the callee is an imported macro from an external crate, need to get // the source span and name from the session, as their spans are localized @@ -799,7 +806,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callee_span = self.span_from_span(callee.def_site); Some(MacroRef { span: callsite_span, - qualname: callee.kind.descr().to_string(), // FIXME: generate the real qualname + qualname: mac_name.to_string(), // FIXME: generate the real qualname callee_span, }) } diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index fd1f07c743beb..366201d66c4c1 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -140,7 +140,9 @@ impl ExpnId { loop { let expn_data = self.expn_data(); // Stop going up the backtrace once include! is encountered - if expn_data.is_root() || expn_data.kind.descr() == sym::include { + if expn_data.is_root() + || expn_data.kind == ExpnKind::Macro(MacroKind::Bang, sym::include) + { break; } self = expn_data.call_site.ctxt().outer_expn(); @@ -717,7 +719,7 @@ impl ExpnData { } /// Expansion kind. -#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] +#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum ExpnKind { /// No expansion, aka root expansion. Only `ExpnId::root()` has this kind. Root, diff --git a/src/tools/clippy b/src/tools/clippy index 3e74853d1f989..fa046d2e7f14c 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 3e74853d1f9893cf2a47f28b658711d8f9f97b6b +Subproject commit fa046d2e7f14cda09d14230cc8c772e1565e0757 From a7b0aa0675f6e81bdb62e614c020a6862381c98a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 21 Jan 2020 01:02:01 +0200 Subject: [PATCH 0627/1253] rustc_span: move pretty syntax from macro_backtrace to ExpnKind::descr. --- src/librustc_expand/expand.rs | 5 +---- src/librustc_span/hygiene.rs | 14 +++++++++----- src/librustc_span/lib.rs | 12 +----------- .../ui/did_you_mean/recursion_limit_macro.stderr | 2 +- src/test/ui/infinite/infinite-macro-expansion.rs | 2 +- .../ui/infinite/infinite-macro-expansion.stderr | 2 +- src/test/ui/issues/issue-16098.rs | 2 +- src/test/ui/issues/issue-16098.stderr | 2 +- src/test/ui/macros/trace_faulty_macros.stderr | 2 +- src/tools/cargo | 2 +- 10 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 3254d0c913da3..f915f44c17ab9 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -596,10 +596,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let suggested_limit = self.cx.ecfg.recursion_limit * 2; let mut err = self.cx.struct_span_err( expn_data.call_site, - &format!( - "recursion limit reached while expanding the macro `{}`", - expn_data.kind.descr() - ), + &format!("recursion limit reached while expanding `{}`", expn_data.kind.descr()), ); err.help(&format!( "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index 366201d66c4c1..a368a881674d8 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -732,12 +732,16 @@ pub enum ExpnKind { } impl ExpnKind { - pub fn descr(&self) -> Symbol { + pub fn descr(&self) -> String { match *self { - ExpnKind::Root => kw::PathRoot, - ExpnKind::Macro(_, descr) => descr, - ExpnKind::AstPass(kind) => Symbol::intern(kind.descr()), - ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()), + ExpnKind::Root => kw::PathRoot.to_string(), + ExpnKind::Macro(macro_kind, name) => match macro_kind { + MacroKind::Bang => format!("{}!", name), + MacroKind::Attr => format!("#[{}]", name), + MacroKind::Derive => format!("#[derive({})]", name), + }, + ExpnKind::AstPass(kind) => kind.descr().to_string(), + ExpnKind::Desugaring(kind) => format!("desugaring of {}", kind.descr()), } } } diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 5779d17e3e51e..764312021efaf 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -455,19 +455,9 @@ impl Span { } // Don't print recursive invocations. if !expn_data.call_site.source_equal(&prev_span) { - let (pre, post) = match expn_data.kind { - ExpnKind::Root => break, - ExpnKind::Desugaring(..) => ("desugaring of ", ""), - ExpnKind::AstPass(..) => ("", ""), - ExpnKind::Macro(macro_kind, _) => match macro_kind { - MacroKind::Bang => ("", "!"), - MacroKind::Attr => ("#[", "]"), - MacroKind::Derive => ("#[derive(", ")]"), - }, - }; result.push(MacroBacktrace { call_site: expn_data.call_site, - macro_decl_name: format!("{}{}{}", pre, expn_data.kind.descr(), post), + macro_decl_name: expn_data.kind.descr(), def_site_span: expn_data.def_site, }); } diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index 6640ced5c9ecb..1cc59051605cd 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -1,4 +1,4 @@ -error: recursion limit reached while expanding the macro `recurse` +error: recursion limit reached while expanding `recurse!` --> $DIR/recursion_limit_macro.rs:10:31 | LL | ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; diff --git a/src/test/ui/infinite/infinite-macro-expansion.rs b/src/test/ui/infinite/infinite-macro-expansion.rs index 968d8360bb0e5..6ea0bc73dc057 100644 --- a/src/test/ui/infinite/infinite-macro-expansion.rs +++ b/src/test/ui/infinite/infinite-macro-expansion.rs @@ -1,5 +1,5 @@ macro_rules! recursive { - () => (recursive!()) //~ ERROR recursion limit reached while expanding the macro `recursive` + () => (recursive!()) //~ ERROR recursion limit reached while expanding `recursive!` } fn main() { diff --git a/src/test/ui/infinite/infinite-macro-expansion.stderr b/src/test/ui/infinite/infinite-macro-expansion.stderr index 0c0c6596760e2..159312e5c1b53 100644 --- a/src/test/ui/infinite/infinite-macro-expansion.stderr +++ b/src/test/ui/infinite/infinite-macro-expansion.stderr @@ -1,4 +1,4 @@ -error: recursion limit reached while expanding the macro `recursive` +error: recursion limit reached while expanding `recursive!` --> $DIR/infinite-macro-expansion.rs:2:12 | LL | () => (recursive!()) diff --git a/src/test/ui/issues/issue-16098.rs b/src/test/ui/issues/issue-16098.rs index a1131f80e906a..00acc20fc9e5e 100644 --- a/src/test/ui/issues/issue-16098.rs +++ b/src/test/ui/issues/issue-16098.rs @@ -4,7 +4,7 @@ macro_rules! prob1 { }; ($n:expr) => { if ($n % 3 == 0) || ($n % 5 == 0) { - $n + prob1!($n - 1); //~ ERROR recursion limit reached while expanding the macro `prob1` + $n + prob1!($n - 1); //~ ERROR recursion limit reached while expanding `prob1!` } else { prob1!($n - 1); } diff --git a/src/test/ui/issues/issue-16098.stderr b/src/test/ui/issues/issue-16098.stderr index f890baf8eba04..2b9657d46283b 100644 --- a/src/test/ui/issues/issue-16098.stderr +++ b/src/test/ui/issues/issue-16098.stderr @@ -1,4 +1,4 @@ -error: recursion limit reached while expanding the macro `prob1` +error: recursion limit reached while expanding `prob1!` --> $DIR/issue-16098.rs:7:18 | LL | $n + prob1!($n - 1); diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index f06e6581ff7fb..4e86daffb61ba 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -20,7 +20,7 @@ LL | my_faulty_macro!(); = note: to `my_faulty_macro ! (bcd) ;` = note: expanding `my_faulty_macro! { bcd }` -error: recursion limit reached while expanding the macro `my_recursive_macro` +error: recursion limit reached while expanding `my_recursive_macro!` --> $DIR/trace_faulty_macros.rs:22:9 | LL | my_recursive_macro!(); diff --git a/src/tools/cargo b/src/tools/cargo index f6449ba236db3..b68b0978ab801 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit f6449ba236db31995255ac5e4cad4ab88296a7c6 +Subproject commit b68b0978ab8012f871c80736fb910d14b89c4498 From 75284f8cbdfa17046156528dc3aa5303f8752f97 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 21 Jan 2020 01:27:14 +0200 Subject: [PATCH 0628/1253] rustc_span: replace MacroBacktrace with ExpnData. --- src/librustc_errors/emitter.rs | 12 ++++++------ src/librustc_errors/json.rs | 9 +++++---- src/librustc_span/lib.rs | 20 ++------------------ 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 7218730538a4b..49c8be2829220 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -21,6 +21,7 @@ use crate::{ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; +use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; use std::cmp::{max, min, Reverse}; use std::io; @@ -346,15 +347,15 @@ pub trait Emitter { for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() { // Only show macro locations that are local // and display them like a span_note - if trace.def_site_span.is_dummy() { + if trace.def_site.is_dummy() { continue; } if always_backtrace { new_labels.push(( - trace.def_site_span, + trace.def_site, format!( "in this expansion of `{}`{}", - trace.macro_decl_name, + trace.kind.descr(), if backtrace_len > 2 { // if backtrace_len == 1 it'll be pointed // at by "in this macro invocation" @@ -366,9 +367,8 @@ pub trait Emitter { )); } // Check to make sure we're not in any <*macros> - if !sm.span_to_filename(trace.def_site_span).is_macros() - && !trace.macro_decl_name.starts_with("desugaring of ") - && !trace.macro_decl_name.starts_with("#[") + if !sm.span_to_filename(trace.def_site).is_macros() + && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _)) || always_backtrace { new_labels.push(( diff --git a/src/librustc_errors/json.rs b/src/librustc_errors/json.rs index 29d3122636e62..21be9527b6cab 100644 --- a/src/librustc_errors/json.rs +++ b/src/librustc_errors/json.rs @@ -17,7 +17,8 @@ use crate::{Applicability, DiagnosticId}; use crate::{CodeSuggestion, SubDiagnostic}; use rustc_data_structures::sync::Lrc; -use rustc_span::{MacroBacktrace, MultiSpan, Span, SpanLabel}; +use rustc_span::hygiene::ExpnData; +use rustc_span::{MultiSpan, Span, SpanLabel}; use std::io::{self, Write}; use std::path::Path; use std::sync::{Arc, Mutex}; @@ -317,7 +318,7 @@ impl DiagnosticSpan { is_primary: bool, label: Option, suggestion: Option<(&String, Applicability)>, - mut backtrace: vec::IntoIter, + mut backtrace: vec::IntoIter, je: &JsonEmitter, ) -> DiagnosticSpan { let start = je.sm.lookup_char_pos(span.lo()); @@ -325,10 +326,10 @@ impl DiagnosticSpan { let backtrace_step = backtrace.next().map(|bt| { let call_site = Self::from_span_full(bt.call_site, false, None, None, backtrace, je); let def_site_span = - Self::from_span_full(bt.def_site_span, false, None, None, vec![].into_iter(), je); + Self::from_span_full(bt.def_site, false, None, None, vec![].into_iter(), je); Box::new(DiagnosticSpanMacroExpansion { span: call_site, - macro_decl_name: bt.macro_decl_name, + macro_decl_name: bt.kind.descr(), def_site_span, }) }); diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 764312021efaf..3f23eb15829de 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -445,7 +445,7 @@ impl Span { self.ctxt().outer_expn_data().allow_internal_unsafe } - pub fn macro_backtrace(mut self) -> Vec { + pub fn macro_backtrace(mut self) -> Vec { let mut prev_span = DUMMY_SP; let mut result = vec![]; loop { @@ -455,11 +455,7 @@ impl Span { } // Don't print recursive invocations. if !expn_data.call_site.source_equal(&prev_span) { - result.push(MacroBacktrace { - call_site: expn_data.call_site, - macro_decl_name: expn_data.kind.descr(), - def_site_span: expn_data.def_site, - }); + result.push(expn_data.clone()); } prev_span = self; @@ -1501,18 +1497,6 @@ pub struct FileLines { pub static SPAN_DEBUG: AtomicRef) -> fmt::Result> = AtomicRef::new(&(default_span_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); -#[derive(Debug)] -pub struct MacroBacktrace { - /// span where macro was applied to generate this code - pub call_site: Span, - - /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") - pub macro_decl_name: String, - - /// span where macro was defined (possibly dummy) - pub def_site_span: Span, -} - // _____________________________________________________________________________ // SpanLinesError, SpanSnippetError, DistinctSources, MalformedSourceMapPositions // From 6980f82c0d152446506fee4d4a45d8afdf4ad9a4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 21 Jan 2020 01:46:53 +0200 Subject: [PATCH 0629/1253] rustc_span: return an impl Iterator instead of a Vec from macro_backtrace. --- src/librustc_errors/emitter.rs | 8 ++++---- src/librustc_errors/json.rs | 4 ++-- src/librustc_span/lib.rs | 33 ++++++++++++++++++--------------- src/librustc_span/source_map.rs | 3 +-- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 49c8be2829220..f9e23e96fa8a8 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -343,8 +343,9 @@ pub trait Emitter { if call_sp != *sp && !always_backtrace { before_after.push((*sp, call_sp)); } - let backtrace_len = sp.macro_backtrace().len(); - for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() { + let macro_backtrace: Vec<_> = sp.macro_backtrace().collect(); + let backtrace_len = macro_backtrace.len(); + for (i, trace) in macro_backtrace.iter().rev().enumerate() { // Only show macro locations that are local // and display them like a span_note if trace.def_site.is_dummy() { @@ -398,8 +399,7 @@ pub trait Emitter { continue; } if sm.span_to_filename(sp_label.span.clone()).is_macros() && !always_backtrace { - let v = sp_label.span.macro_backtrace(); - if let Some(use_site) = v.last() { + if let Some(use_site) = sp_label.span.macro_backtrace().last() { before_after.push((sp_label.span.clone(), use_site.call_site.clone())); } } diff --git a/src/librustc_errors/json.rs b/src/librustc_errors/json.rs index 21be9527b6cab..3ddf9b09893ba 100644 --- a/src/librustc_errors/json.rs +++ b/src/librustc_errors/json.rs @@ -309,7 +309,7 @@ impl DiagnosticSpan { // backtrace ourselves, but the `macro_backtrace` helper makes // some decision, such as dropping some frames, and I don't // want to duplicate that logic here. - let backtrace = span.macro_backtrace().into_iter(); + let backtrace = span.macro_backtrace(); DiagnosticSpan::from_span_full(span, is_primary, label, suggestion, backtrace, je) } @@ -318,7 +318,7 @@ impl DiagnosticSpan { is_primary: bool, label: Option, suggestion: Option<(&String, Applicability)>, - mut backtrace: vec::IntoIter, + mut backtrace: impl Iterator, je: &JsonEmitter, ) -> DiagnosticSpan { let start = je.sm.lookup_char_pos(span.lo()); diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 3f23eb15829de..413bd77daae24 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -445,23 +445,26 @@ impl Span { self.ctxt().outer_expn_data().allow_internal_unsafe } - pub fn macro_backtrace(mut self) -> Vec { + pub fn macro_backtrace(mut self) -> impl Iterator { let mut prev_span = DUMMY_SP; - let mut result = vec![]; - loop { - let expn_data = self.ctxt().outer_expn_data(); - if expn_data.is_root() { - break; - } - // Don't print recursive invocations. - if !expn_data.call_site.source_equal(&prev_span) { - result.push(expn_data.clone()); - } + std::iter::from_fn(move || { + loop { + let expn_data = self.ctxt().outer_expn_data(); + if expn_data.is_root() { + return None; + } - prev_span = self; - self = expn_data.call_site; - } - result + let is_recursive = expn_data.call_site.source_equal(&prev_span); + + prev_span = self; + self = expn_data.call_site; + + // Don't print recursive invocations. + if !is_recursive { + return Some(expn_data); + } + } + }) } /// Returns a `Span` that would enclose both `self` and `end`. diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index e0b93b9ce2555..c250df43a2733 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -947,8 +947,7 @@ impl SourceMap { } pub fn call_span_if_macro(&self, sp: Span) -> Span { if self.span_to_filename(sp.clone()).is_macros() { - let v = sp.macro_backtrace(); - if let Some(use_site) = v.last() { + if let Some(use_site) = sp.macro_backtrace().last() { return use_site.call_site; } } From 85079f8b1fa8291593735b9b577e8e0dc22ad3b6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 26 Jan 2020 17:24:40 +0100 Subject: [PATCH 0630/1253] Fix run button positionning in case of scrolling --- src/librustdoc/html/highlight.rs | 11 ++++------- src/librustdoc/html/static/rustdoc.css | 4 +++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 5bea1b5614159..2a603d9900fb9 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -22,7 +22,7 @@ use syntax::token::{self, Token}; pub fn render_with_highlighting( src: &str, class: Option<&str>, - extension: Option<&str>, + playground_button: Option<&str>, tooltip: Option<(&str, &str)>, ) -> String { debug!("highlighting: ================\n{}\n==============", src); @@ -58,10 +58,7 @@ pub fn render_with_highlighting( Ok(highlighted_source) => { write_header(class, &mut out).unwrap(); write!(out, "{}", highlighted_source).unwrap(); - if let Some(extension) = extension { - write!(out, "{}", extension).unwrap(); - } - write_footer(&mut out).unwrap(); + write_footer(&mut out, playground_button).unwrap(); } Err(()) => { // If errors are encountered while trying to highlight, just emit @@ -433,6 +430,6 @@ fn write_header(class: Option<&str>, out: &mut dyn Write) -> io::Result<()> { write!(out, "
\n", class.unwrap_or(""))
 }
 
-fn write_footer(out: &mut dyn Write) -> io::Result<()> {
-    write!(out, "
\n") +fn write_footer(out: &mut dyn Write, playground_button: Option<&str>) -> io::Result<()> { + write!(out, "{}\n", if let Some(button) = playground_button { button } else { "" }) } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index a91fdb7a10e0d..0dfe82c501469 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -136,7 +136,7 @@ summary { outline: none; } -code, pre { +code, pre, a.test-arrow { font-family: "Source Code Pro", monospace; } .docblock code, .docblock-short code { @@ -305,6 +305,7 @@ nav.sub { .rustdoc:not(.source) .example-wrap { display: inline-flex; margin-bottom: 10px; + position: relative; } .example-wrap { @@ -878,6 +879,7 @@ a.test-arrow { font-size: 130%; top: 5px; right: 5px; + z-index: 1; } a.test-arrow:hover{ text-decoration: none; From 697fdc568e28fbb376567eda4edb2c2a05db68de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jan 2020 23:01:21 -0800 Subject: [PATCH 0631/1253] Suggest defining type parameter when appropriate ``` error[E0412]: cannot find type `T` in this scope --> file.rs:3:12 | 3 | impl Trait for Struct {} | - ^ not found in this scope | | | help: you might be missing a type parameter: `` ``` Fix #64298. --- src/librustc_resolve/diagnostics.rs | 5 + src/librustc_resolve/late.rs | 110 ++++++++++-------- src/librustc_resolve/late/diagnostics.rs | 51 +++++++- src/librustc_resolve/lib.rs | 9 +- src/libsyntax/ast.rs | 14 +++ src/test/ui/dyn-trait-compatibility.stderr | 12 +- src/test/ui/hygiene/globs.stderr | 15 ++- src/test/ui/issues/issue-58712.stderr | 4 +- src/test/ui/privacy/privacy-ns1.stderr | 4 + src/test/ui/proc-macro/generate-mod.stderr | 12 ++ .../no-extern-crate-in-type.stderr | 4 + .../type-alias/issue-62364-self-ty-arg.stderr | 4 +- 12 files changed, 178 insertions(+), 66 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 77dfe3d9f1d5a..b762e0b08ac04 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1415,11 +1415,15 @@ crate fn show_candidates( better: bool, found_use: bool, ) { + if candidates.is_empty() { + return; + } // we want consistent results across executions, but candidates are produced // by iterating through a hash map, so make sure they are ordered: let mut path_strings: Vec<_> = candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); path_strings.sort(); + path_strings.dedup(); let better = if better { "better " } else { "" }; let msg_diff = match path_strings.len() { @@ -1444,6 +1448,7 @@ crate fn show_candidates( msg.push('\n'); msg.push_str(&candidate); } + err.note(&msg); } } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 5e08ac8e2c38a..faa9eb3bc2fa7 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -323,7 +323,7 @@ impl<'a> PathSource<'a> { } #[derive(Default)] -struct DiagnosticMetadata { +struct DiagnosticMetadata<'ast> { /// The current trait's associated types' ident, used for diagnostic suggestions. current_trait_assoc_types: Vec, @@ -333,6 +333,13 @@ struct DiagnosticMetadata { /// The current self item if inside an ADT (used for better errors). current_self_item: Option, + /// The current trait (used to suggest). + current_item: Option<&'ast Item>, + + /// When processing generics and encountering a type not found, suggest introducing a type + /// param. + currently_processing_generics: bool, + /// The current enclosing function (used for better errors). current_function: Option, @@ -347,7 +354,7 @@ struct DiagnosticMetadata { current_let_binding: Option<(Span, Option, Option)>, } -struct LateResolutionVisitor<'a, 'b> { +struct LateResolutionVisitor<'a, 'b, 'ast> { r: &'b mut Resolver<'a>, /// The module that represents the current item scope. @@ -364,30 +371,32 @@ struct LateResolutionVisitor<'a, 'b> { current_trait_ref: Option<(Module<'a>, TraitRef)>, /// Fields used to add information to diagnostic errors. - diagnostic_metadata: DiagnosticMetadata, + diagnostic_metadata: DiagnosticMetadata<'ast>, } /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. -impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { - fn visit_item(&mut self, item: &'tcx Item) { +impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { + fn visit_item(&mut self, item: &'ast Item) { + let prev = replace(&mut self.diagnostic_metadata.current_item, Some(item)); self.resolve_item(item); + self.diagnostic_metadata.current_item = prev; } - fn visit_arm(&mut self, arm: &'tcx Arm) { + fn visit_arm(&mut self, arm: &'ast Arm) { self.resolve_arm(arm); } - fn visit_block(&mut self, block: &'tcx Block) { + fn visit_block(&mut self, block: &'ast Block) { self.resolve_block(block); } - fn visit_anon_const(&mut self, constant: &'tcx AnonConst) { + fn visit_anon_const(&mut self, constant: &'ast AnonConst) { debug!("visit_anon_const {:?}", constant); self.with_constant_rib(|this| { visit::walk_anon_const(this, constant); }); } - fn visit_expr(&mut self, expr: &'tcx Expr) { + fn visit_expr(&mut self, expr: &'ast Expr) { self.resolve_expr(expr, None); } - fn visit_local(&mut self, local: &'tcx Local) { + fn visit_local(&mut self, local: &'ast Local) { let local_spans = match local.pat.kind { // We check for this to avoid tuple struct fields. PatKind::Wild => None, @@ -401,7 +410,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { self.resolve_local(local); self.diagnostic_metadata.current_let_binding = original; } - fn visit_ty(&mut self, ty: &'tcx Ty) { + fn visit_ty(&mut self, ty: &'ast Ty) { match ty.kind { TyKind::Path(ref qself, ref path) => { self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); @@ -417,7 +426,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { } visit::walk_ty(self, ty); } - fn visit_poly_trait_ref(&mut self, tref: &'tcx PolyTraitRef, m: &'tcx TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) { self.smart_resolve_path( tref.trait_ref.ref_id, None, @@ -426,7 +435,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { ); visit::walk_poly_trait_ref(self, tref, m); } - fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) { + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { match foreign_item.kind { ForeignItemKind::Fn(_, ref generics) => { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { @@ -443,7 +452,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { } } } - fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, sp: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'ast>, declaration: &'ast FnDecl, sp: Span, _: NodeId) { let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp)); debug!("(resolving function) entering function"); let rib_kind = match fn_kind { @@ -472,7 +481,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { self.diagnostic_metadata.current_function = previous_value; } - fn visit_generics(&mut self, generics: &'tcx Generics) { + fn visit_generics(&mut self, generics: &'ast Generics) { // For type parameter defaults, we have to ban access // to following type parameters, as the InternalSubsts can only // provide previous type parameters as they're built. We @@ -534,11 +543,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { } } - fn visit_generic_arg(&mut self, arg: &'tcx GenericArg) { + fn visit_generic_arg(&mut self, arg: &'ast GenericArg) { debug!("visit_generic_arg({:?})", arg); + let prev = replace(&mut self.diagnostic_metadata.currently_processing_generics, true); match arg { GenericArg::Type(ref ty) => { - // We parse const arguments as path types as we cannot distiguish them durring + // We parse const arguments as path types as we cannot distiguish them during // parsing. We try to resolve that ambiguity by attempting resolution the type // namespace first, and if that fails we try again in the value namespace. If // resolution in the value namespace succeeds, we have an generic const argument on @@ -556,7 +566,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { ) .is_some() }; - if !check_ns(TypeNS) && check_ns(ValueNS) { // This must be equivalent to `visit_anon_const`, but we cannot call it // directly due to visitor lifetimes so we have to copy-paste some code. @@ -574,6 +583,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { this.visit_path(path, ty.id); }); + self.diagnostic_metadata.currently_processing_generics = prev; return; } } @@ -584,11 +594,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { GenericArg::Lifetime(lt) => self.visit_lifetime(lt), GenericArg::Const(ct) => self.visit_anon_const(ct), } + self.diagnostic_metadata.currently_processing_generics = prev; } } -impl<'a, 'b> LateResolutionVisitor<'a, '_> { - fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> { +impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { + fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b, 'ast> { // During late resolution we only track the module component of the parent scope, // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; @@ -724,7 +735,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { None } - fn resolve_adt(&mut self, item: &Item, generics: &Generics) { + fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) { debug!("resolve_adt"); self.with_current_self_item(item, |this| { this.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { @@ -778,7 +789,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } - fn resolve_item(&mut self, item: &Item) { + fn resolve_item(&mut self, item: &'ast Item) { let name = item.ident.name; debug!("(resolving item) resolving {} ({:?})", name, item.kind); @@ -1024,16 +1035,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { let path: Vec<_> = Segment::from_path(&trait_ref.path); - let res = self - .smart_resolve_path_fragment( - trait_ref.ref_id, - None, - &path, - trait_ref.path.span, - PathSource::Trait(AliasPossibility::No), - CrateLint::SimplePath(trait_ref.ref_id), - ) - .base_res(); + let res = self.smart_resolve_path_fragment( + trait_ref.ref_id, + None, + &path, + trait_ref.path.span, + PathSource::Trait(AliasPossibility::No), + CrateLint::SimplePath(trait_ref.ref_id), + ); + let res = res.base_res(); if res != Res::Err { new_id = Some(res.def_id()); let span = trait_ref.path.span; @@ -1070,11 +1080,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { fn resolve_implementation( &mut self, - generics: &Generics, - opt_trait_reference: &Option, - self_type: &Ty, + generics: &'ast Generics, + opt_trait_reference: &'ast Option, + self_type: &'ast Ty, item_id: NodeId, - impl_items: &[AssocItem], + impl_items: &'ast [AssocItem], ) { debug!("resolve_implementation"); // If applicable, create a rib for the type parameters. @@ -1179,7 +1189,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } - fn resolve_params(&mut self, params: &[Param]) { + fn resolve_params(&mut self, params: &'ast [Param]) { let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; for Param { pat, ty, .. } in params { self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings); @@ -1188,7 +1198,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } - fn resolve_local(&mut self, local: &Local) { + fn resolve_local(&mut self, local: &'ast Local) { // Resolve the type. walk_list!(self, visit_ty, &local.ty); @@ -1307,7 +1317,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } /// Check the consistency of the outermost or-patterns. - fn check_consistent_bindings_top(&mut self, pat: &Pat) { + fn check_consistent_bindings_top(&mut self, pat: &'ast Pat) { pat.walk(&mut |pat| match pat.kind { PatKind::Or(ref ps) => { self.check_consistent_bindings(ps); @@ -1317,7 +1327,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { }) } - fn resolve_arm(&mut self, arm: &Arm) { + fn resolve_arm(&mut self, arm: &'ast Arm) { self.with_rib(ValueNS, NormalRibKind, |this| { this.resolve_pattern_top(&arm.pat, PatternSource::Match); walk_list!(this, visit_expr, &arm.guard); @@ -1326,14 +1336,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } /// Arising from `source`, resolve a top level pattern. - fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) { + fn resolve_pattern_top(&mut self, pat: &'ast Pat, pat_src: PatternSource) { let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; self.resolve_pattern(pat, pat_src, &mut bindings); } fn resolve_pattern( &mut self, - pat: &Pat, + pat: &'ast Pat, pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet); 1]>, ) { @@ -1544,7 +1554,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { id: NodeId, qself: Option<&QSelf>, path: &Path, - source: PathSource<'_>, + source: PathSource<'ast>, ) { self.smart_resolve_path_fragment( id, @@ -1562,7 +1572,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { qself: Option<&QSelf>, path: &[Segment], span: Span, - source: PathSource<'_>, + source: PathSource<'ast>, crate_lint: CrateLint, ) -> PartialRes { let ns = source.namespace(); @@ -1573,7 +1583,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { let def_id = this.parent_scope.module.normal_ancestor_id; let node_id = this.r.definitions.as_local_node_id(def_id).unwrap(); let better = res.is_some(); - this.r.use_injections.push(UseError { err, candidates, node_id, better }); + let suggestion = + if res.is_none() { this.report_missing_type_error(path) } else { None }; + this.r.use_injections.push(UseError { err, candidates, node_id, better, suggestion }); PartialRes::new(Res::Err) }; @@ -1838,11 +1850,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } - fn resolve_labeled_block(&mut self, label: Option
{ } Some(Equal) => { self.is_empty = Some(true); + self.start = plus_n.clone(); return Some(plus_n); } _ => {} } } + self.start = self.end.clone(); self.is_empty = Some(true); None } @@ -477,12 +479,14 @@ impl DoubleEndedIterator for ops::RangeInclusive { } Some(Equal) => { self.is_empty = Some(true); + self.end = minus_n.clone(); return Some(minus_n); } _ => {} } } + self.end = self.start.clone(); self.is_empty = Some(true); None } diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index d38b35165695c..6c0bc6bbbad22 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -343,38 +343,21 @@ pub struct RangeInclusive { pub(crate) is_empty: Option, // This field is: // - `None` when next() or next_back() was never called - // - `Some(false)` when `start <= end` assuming no overflow - // - `Some(true)` otherwise + // - `Some(false)` when `start < end` + // - `Some(true)` when `end < start` + // - `Some(false)` when `start == end` and the range hasn't yet completed iteration + // - `Some(true)` when `start == end` and the range has completed iteration // The field cannot be a simple `bool` because the `..=` constructor can // accept non-PartialOrd types, also we want the constructor to be const. } -trait RangeInclusiveEquality: Sized { - fn canonicalized_is_empty(range: &RangeInclusive) -> bool; -} - -impl RangeInclusiveEquality for T { - #[inline] - default fn canonicalized_is_empty(range: &RangeInclusive) -> bool { - range.is_empty.unwrap_or_default() - } -} - -impl RangeInclusiveEquality for T { - #[inline] - fn canonicalized_is_empty(range: &RangeInclusive) -> bool { - range.is_empty() - } -} - #[stable(feature = "inclusive_range", since = "1.26.0")] impl PartialEq for RangeInclusive { #[inline] fn eq(&self, other: &Self) -> bool { self.start == other.start && self.end == other.end - && RangeInclusiveEquality::canonicalized_is_empty(self) - == RangeInclusiveEquality::canonicalized_is_empty(other) + && self.is_exhausted() == other.is_exhausted() } } @@ -386,7 +369,8 @@ impl Hash for RangeInclusive { fn hash(&self, state: &mut H) { self.start.hash(state); self.end.hash(state); - RangeInclusiveEquality::canonicalized_is_empty(self).hash(state); + // Ideally we would hash `is_exhausted` here as well, but there's no + // way for us to call it. } } @@ -485,6 +469,14 @@ impl fmt::Debug for RangeInclusive { } } +impl> RangeInclusive { + // Returns true if this is a range that started non-empty, and was iterated + // to exhaustion. + fn is_exhausted(&self) -> bool { + Some(true) == self.is_empty && self.start == self.end + } +} + impl> RangeInclusive { /// Returns `true` if `item` is contained in the range. /// diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 9b4d201573238..e79a775325f4a 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -5584,21 +5584,18 @@ where #[doc(hidden)] // intermediate trait for specialization of slice's PartialOrd -trait SlicePartialOrd { - fn partial_compare(&self, other: &[B]) -> Option; +trait SlicePartialOrd: Sized { + fn partial_compare(left: &[Self], right: &[Self]) -> Option; } -impl SlicePartialOrd for [A] -where - A: PartialOrd, -{ - default fn partial_compare(&self, other: &[A]) -> Option { - let l = cmp::min(self.len(), other.len()); +impl SlicePartialOrd for A { + default fn partial_compare(left: &[A], right: &[A]) -> Option { + let l = cmp::min(left.len(), right.len()); // Slice to the loop iteration range to enable bound check // elimination in the compiler - let lhs = &self[..l]; - let rhs = &other[..l]; + let lhs = &left[..l]; + let rhs = &right[..l]; for i in 0..l { match lhs[i].partial_cmp(&rhs[i]) { @@ -5607,36 +5604,61 @@ where } } - self.len().partial_cmp(&other.len()) + left.len().partial_cmp(&right.len()) } } -impl SlicePartialOrd for [A] +// This is the impl that we would like to have. Unfortunately it's not sound. +// See `partial_ord_slice.rs`. +/* +impl SlicePartialOrd for A where A: Ord, { - default fn partial_compare(&self, other: &[A]) -> Option { - Some(SliceOrd::compare(self, other)) + default fn partial_compare(left: &[A], right: &[A]) -> Option { + Some(SliceOrd::compare(left, right)) + } +} +*/ + +impl SlicePartialOrd for A { + fn partial_compare(left: &[A], right: &[A]) -> Option { + Some(SliceOrd::compare(left, right)) + } +} + +trait AlwaysApplicableOrd: SliceOrd + Ord {} + +macro_rules! always_applicable_ord { + ($([$($p:tt)*] $t:ty,)*) => { + $(impl<$($p)*> AlwaysApplicableOrd for $t {})* } } +always_applicable_ord! { + [] u8, [] u16, [] u32, [] u64, [] u128, [] usize, + [] i8, [] i16, [] i32, [] i64, [] i128, [] isize, + [] bool, [] char, + [T: ?Sized] *const T, [T: ?Sized] *mut T, + [T: AlwaysApplicableOrd] &T, + [T: AlwaysApplicableOrd] &mut T, + [T: AlwaysApplicableOrd] Option, +} + #[doc(hidden)] // intermediate trait for specialization of slice's Ord -trait SliceOrd { - fn compare(&self, other: &[B]) -> Ordering; +trait SliceOrd: Sized { + fn compare(left: &[Self], right: &[Self]) -> Ordering; } -impl SliceOrd for [A] -where - A: Ord, -{ - default fn compare(&self, other: &[A]) -> Ordering { - let l = cmp::min(self.len(), other.len()); +impl SliceOrd for A { + default fn compare(left: &[Self], right: &[Self]) -> Ordering { + let l = cmp::min(left.len(), right.len()); // Slice to the loop iteration range to enable bound check // elimination in the compiler - let lhs = &self[..l]; - let rhs = &other[..l]; + let lhs = &left[..l]; + let rhs = &right[..l]; for i in 0..l { match lhs[i].cmp(&rhs[i]) { @@ -5645,19 +5667,19 @@ where } } - self.len().cmp(&other.len()) + left.len().cmp(&right.len()) } } // memcmp compares a sequence of unsigned bytes lexicographically. // this matches the order we want for [u8], but no others (not even [i8]). -impl SliceOrd for [u8] { +impl SliceOrd for u8 { #[inline] - fn compare(&self, other: &[u8]) -> Ordering { + fn compare(left: &[Self], right: &[Self]) -> Ordering { let order = - unsafe { memcmp(self.as_ptr(), other.as_ptr(), cmp::min(self.len(), other.len())) }; + unsafe { memcmp(left.as_ptr(), right.as_ptr(), cmp::min(left.len(), right.len())) }; if order == 0 { - self.len().cmp(&other.len()) + left.len().cmp(&right.len()) } else if order < 0 { Less } else { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 5a7cddd4041d5..734b3ba7c6bba 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -12,7 +12,7 @@ use self::pattern::{DoubleEndedSearcher, ReverseSearcher, SearchStep, Searcher}; use crate::char; use crate::fmt::{self, Write}; use crate::iter::{Chain, FlatMap, Flatten}; -use crate::iter::{Cloned, Filter, FusedIterator, Map, TrustedLen, TrustedRandomAccess}; +use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen, TrustedRandomAccess}; use crate::mem; use crate::ops::Try; use crate::option; @@ -750,7 +750,7 @@ impl<'a> CharIndices<'a> { /// [`str`]: ../../std/primitive.str.html #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] -pub struct Bytes<'a>(Cloned>); +pub struct Bytes<'a>(Copied>); #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Bytes<'_> { @@ -2778,7 +2778,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn bytes(&self) -> Bytes<'_> { - Bytes(self.as_bytes().iter().cloned()) + Bytes(self.as_bytes().iter().copied()) } /// Splits a string slice by whitespace. @@ -3895,7 +3895,7 @@ impl str { debug_assert_eq!( start, 0, "The first search step from Searcher \ - must include the first character" + must include the first character" ); // SAFETY: `Searcher` is known to return valid indices. unsafe { Some(self.get_unchecked(len..)) } @@ -3934,7 +3934,7 @@ impl str { end, self.len(), "The first search step from ReverseSearcher \ - must include the last character" + must include the last character" ); // SAFETY: `Searcher` is known to return valid indices. unsafe { Some(self.get_unchecked(..start)) } diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 8b8dc941534ee..e3fc2f54ecaad 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1954,11 +1954,19 @@ fn test_range_inclusive_exhaustion() { assert_eq!(r.next(), None); assert_eq!(r.next(), None); + assert_eq!(*r.start(), 10); + assert_eq!(*r.end(), 10); + assert_ne!(r, 10..=10); + let mut r = 10..=10; assert_eq!(r.next_back(), Some(10)); assert!(r.is_empty()); assert_eq!(r.next_back(), None); + assert_eq!(*r.start(), 10); + assert_eq!(*r.end(), 10); + assert_ne!(r, 10..=10); + let mut r = 10..=12; assert_eq!(r.next(), Some(10)); assert_eq!(r.next(), Some(11)); @@ -2076,6 +2084,9 @@ fn test_range_inclusive_nth() { assert_eq!((10..=15).nth(5), Some(15)); assert_eq!((10..=15).nth(6), None); + let mut exhausted_via_next = 10_u8..=20; + while exhausted_via_next.next().is_some() {} + let mut r = 10_u8..=20; assert_eq!(r.nth(2), Some(12)); assert_eq!(r, 13..=20); @@ -2085,6 +2096,7 @@ fn test_range_inclusive_nth() { assert_eq!(ExactSizeIterator::is_empty(&r), false); assert_eq!(r.nth(10), None); assert_eq!(r.is_empty(), true); + assert_eq!(r, exhausted_via_next); assert_eq!(ExactSizeIterator::is_empty(&r), true); } @@ -2096,6 +2108,9 @@ fn test_range_inclusive_nth_back() { assert_eq!((10..=15).nth_back(6), None); assert_eq!((-120..=80_i8).nth_back(200), Some(-120)); + let mut exhausted_via_next_back = 10_u8..=20; + while exhausted_via_next_back.next_back().is_some() {} + let mut r = 10_u8..=20; assert_eq!(r.nth_back(2), Some(18)); assert_eq!(r, 10..=17); @@ -2105,6 +2120,7 @@ fn test_range_inclusive_nth_back() { assert_eq!(ExactSizeIterator::is_empty(&r), false); assert_eq!(r.nth_back(10), None); assert_eq!(r.is_empty(), true); + assert_eq!(r, exhausted_via_next_back); assert_eq!(ExactSizeIterator::is_empty(&r), true); } diff --git a/src/test/ui/specialization/soundness/partial_eq_range_inclusive.rs b/src/test/ui/specialization/soundness/partial_eq_range_inclusive.rs new file mode 100644 index 0000000000000..923dec892e080 --- /dev/null +++ b/src/test/ui/specialization/soundness/partial_eq_range_inclusive.rs @@ -0,0 +1,35 @@ +// run-pass + +use std::cell::RefCell; +use std::cmp::Ordering; + +struct Evil<'a, 'b> { + values: RefCell>, + to_insert: &'b String, +} + +impl<'a, 'b> PartialEq for Evil<'a, 'b> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl<'a> PartialOrd for Evil<'a, 'a> { + fn partial_cmp(&self, _other: &Self) -> Option { + self.values.borrow_mut().push(self.to_insert); + None + } +} + +fn main() { + let e; + let values; + { + let to_insert = String::from("Hello, world!"); + e = Evil { values: RefCell::new(Vec::new()), to_insert: &to_insert }; + let range = &e..=&e; + let _ = range == range; + values = e.values; + } + assert_eq!(*values.borrow(), Vec::<&str>::new()); +} diff --git a/src/test/ui/specialization/soundness/partial_ord_slice.rs b/src/test/ui/specialization/soundness/partial_ord_slice.rs new file mode 100644 index 0000000000000..b9e80a48d33d3 --- /dev/null +++ b/src/test/ui/specialization/soundness/partial_ord_slice.rs @@ -0,0 +1,42 @@ +// Check that we aren't using unsound specialization in slice comparisons. + +// run-pass + +use std::cell::Cell; +use std::cmp::Ordering; + +struct Evil<'a, 'b>(Cell<(&'a [i32], &'b [i32])>); + +impl PartialEq for Evil<'_, '_> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl Eq for Evil<'_, '_> {} + +impl PartialOrd for Evil<'_, '_> { + fn partial_cmp(&self, _other: &Self) -> Option { + Some(Ordering::Equal) + } +} + +impl<'a> Ord for Evil<'a, 'a> { + fn cmp(&self, _other: &Self) -> Ordering { + let (a, b) = self.0.get(); + self.0.set((b, a)); + Ordering::Equal + } +} + +fn main() { + let x = &[1, 2, 3, 4]; + let u = { + let a = Box::new([7, 8, 9, 10]); + let y = [Evil(Cell::new((x, &*a)))]; + let _ = &y[..] <= &y[..]; + let [Evil(c)] = y; + c.get().0 + }; + assert_eq!(u, &[1, 2, 3, 4]); +} From 482c761704b9f7d08d00b6cf4c567db427da7ec7 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 23 Jan 2020 00:22:46 +0900 Subject: [PATCH 0731/1253] Use BufWriter --- .../obligation_forest/graphviz.rs | 3 +- src/librustc_incremental/assert_dep_graph.rs | 4 +-- src/librustc_interface/passes.rs | 4 +-- src/librustc_mir/borrow_check/facts.rs | 34 +++++++++++++++---- src/librustc_mir/transform/dump_mir.rs | 2 +- src/librustc_mir/util/liveness.rs | 5 +-- 6 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs index ddf89d99621ca..0fd83dad56b1a 100644 --- a/src/librustc_data_structures/obligation_forest/graphviz.rs +++ b/src/librustc_data_structures/obligation_forest/graphviz.rs @@ -2,6 +2,7 @@ use crate::obligation_forest::{ForestObligation, ObligationForest}; use graphviz as dot; use std::env::var_os; use std::fs::File; +use std::io::BufWriter; use std::path::Path; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -31,7 +32,7 @@ impl ObligationForest { let file_path = dir.as_ref().join(format!("{:010}_{}.gv", counter, description)); - let mut gv_file = File::create(file_path).unwrap(); + let mut gv_file = BufWriter::new(File::create(file_path).unwrap()); dot::render(&self, &mut gv_file).unwrap(); } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 9490128e32d6a..51cc091b6c0af 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -49,7 +49,7 @@ use syntax::ast; use std::env; use std::fs::{self, File}; -use std::io::Write; +use std::io::{BufWriter, Write}; pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { @@ -235,7 +235,7 @@ fn dump_graph(tcx: TyCtxt<'_>) { { // dump a .txt file with just the edges: let txt_path = format!("{}.txt", path); - let mut file = File::create(&txt_path).unwrap(); + let mut file = BufWriter::new(File::create(&txt_path).unwrap()); for &(ref source, ref target) in &edges { write!(file, "{:?} -> {:?}\n", source, target).unwrap(); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d62c7539d5f21..6af83a4c5abc1 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -49,7 +49,7 @@ use tempfile::Builder as TempFileBuilder; use std::any::Any; use std::cell::RefCell; use std::ffi::OsString; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::PathBuf; use std::rc::Rc; use std::{env, fs, iter, mem}; @@ -575,7 +575,7 @@ fn write_out_deps( }); } - let mut file = fs::File::create(&deps_filename)?; + let mut file = BufWriter::new(fs::File::create(&deps_filename)?); for path in out_filenames { writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; } diff --git a/src/librustc_mir/borrow_check/facts.rs b/src/librustc_mir/borrow_check/facts.rs index a16c36d749f0d..827ccb1c85733 100644 --- a/src/librustc_mir/borrow_check/facts.rs +++ b/src/librustc_mir/borrow_check/facts.rs @@ -8,7 +8,7 @@ use rustc_index::vec::Idx; use std::error::Error; use std::fmt::Debug; use std::fs::{self, File}; -use std::io::Write; +use std::io::{BufWriter, Write}; use std::path::Path; #[derive(Copy, Clone, Debug)] @@ -117,7 +117,7 @@ impl<'w> FactWriter<'w> { T: FactRow, { let file = &self.dir.join(file_name); - let mut file = File::create(file)?; + let mut file = BufWriter::new(File::create(file)?); for row in rows { row.write(&mut file, self.location_table)?; } @@ -126,11 +126,19 @@ impl<'w> FactWriter<'w> { } trait FactRow { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box>; + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box>; } impl FactRow for RegionVid { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[self]) } } @@ -140,7 +148,11 @@ where A: FactCell, B: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1]) } } @@ -151,7 +163,11 @@ where B: FactCell, C: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2]) } } @@ -163,7 +179,11 @@ where C: FactCell, D: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3]) } } diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 2cbda33ad2db1..5dec2c6df99dc 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -61,7 +61,7 @@ pub fn on_mir_pass<'tcx>( pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> { let path = outputs.path(OutputType::Mir); - let mut f = File::create(&path)?; + let mut f = io::BufWriter::new(File::create(&path)?); mir_util::write_mir_pretty(tcx, None, &mut f)?; Ok(()) } diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 1488bfe4d627a..b12ad1e4c15cc 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -36,7 +36,7 @@ use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use std::fs; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; pub type LiveVarSet = BitSet; @@ -288,7 +288,8 @@ fn dump_matched_mir_node<'tcx>( let item_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap(); let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name); file_path.push(&file_name); - let _ = fs::File::create(&file_path).and_then(|mut file| { + let _ = fs::File::create(&file_path).and_then(|file| { + let mut file = BufWriter::new(file); writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?; writeln!(file, "// source = {:?}", source)?; writeln!(file, "// pass_name = {}", pass_name)?; From cad0cfd9fdbc64dece3f38c03b15ed9aad032d5c Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 1 Feb 2020 13:29:00 +0100 Subject: [PATCH 0732/1253] Remove a comment about pretty printer in formatting tests rustc is now using rustfmt, not the old formatter. --- src/test/ui/ifmt.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/ui/ifmt.rs b/src/test/ui/ifmt.rs index 1a070843cc446..27ab3d6b7abff 100644 --- a/src/test/ui/ifmt.rs +++ b/src/test/ui/ifmt.rs @@ -99,7 +99,6 @@ pub fn main() { let a: &dyn fmt::Debug = &1; t!(format!("{:?}", a), "1"); - // Formatting strings and their arguments t!(format!("{}", "a"), "a"); t!(format!("{:4}", "a"), "a "); @@ -187,10 +186,6 @@ pub fn main() { // Ergonomic format_args! t!(format!("{0:x} {0:X}", 15), "f F"); t!(format!("{0:x} {0:X} {}", 15), "f F 15"); - // NOTE: For now the longer test cases must not be followed immediately by - // >1 empty lines, or the pretty printer will break. Since no one wants to - // touch the current pretty printer (#751), we have no choice but to work - // around it. Some of the following test cases are also affected. t!(format!("{:x}{0:X}{a:x}{:X}{1:x}{a:X}", 13, 14, a=15), "dDfEeF"); t!(format!("{a:x} {a:X}", a=15), "f F"); @@ -201,7 +196,6 @@ pub fn main() { t!(format!("{a:.*} {0} {:.*}", 4, 3, "efgh", a="abcdef"), "abcd 4 efg"); t!(format!("{:.a$} {a} {a:#x}", "aaaaaa", a=2), "aa 2 0x2"); - // Test that pointers don't get truncated. { let val = usize::MAX; From 2ce14b8a19865ed359e9df7eb5e8e6186cae1e58 Mon Sep 17 00:00:00 2001 From: Marincia Catalin <35623921+cata0309@users.noreply.github.com> Date: Sat, 1 Feb 2020 19:05:50 +0200 Subject: [PATCH 0733/1253] Update option.rs I updated the example of the `expect` examples so they won't contain depressing sentences any more ! --- src/libcore/option.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index cb4247d98745e..ad0491f888cc7 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -331,12 +331,12 @@ impl Option { /// /// ``` /// let x = Some("value"); - /// assert_eq!(x.expect("the world is ending"), "value"); + /// assert_eq!(x.expect("fruits are healthy"), "value"); /// ``` /// /// ```{.should_panic} /// let x: Option<&str> = None; - /// x.expect("the world is ending"); // panics with `the world is ending` + /// x.expect("fruits are healthy"); // panics with `fruits are healthy` /// ``` #[inline] #[track_caller] From 6f5a61b5fb66987a32c25e3877f4f99e37ff067d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 02:39:53 +0900 Subject: [PATCH 0734/1253] Use `next_point` to avoid ICE --- src/librustc_parse/parser/mod.rs | 4 ++-- src/test/ui/parser/issue-68730.rs | Bin 0 -> 170 bytes src/test/ui/parser/issue-68730.stderr | Bin 0 -> 957 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/parser/issue-68730.rs create mode 100644 src/test/ui/parser/issue-68730.stderr diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 4a9016394d258..7246bf307ac39 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -671,12 +671,12 @@ impl<'a> Parser<'a> { true } token::BinOp(token::Shl) => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); + let span = self.sess.source_map().next_point(self.token.span); self.bump_with(token::Lt, span); true } token::LArrow => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); + let span = self.sess.source_map().next_point(self.token.span); self.bump_with(token::BinOp(token::Minus), span); true } diff --git a/src/test/ui/parser/issue-68730.rs b/src/test/ui/parser/issue-68730.rs new file mode 100644 index 0000000000000000000000000000000000000000..b570e9417751b01f67db9a2e4edfa7631400b8d9 GIT binary patch literal 170 zcmZw7F%E+;3`SvQPT>O(Wv{B9B@y|9EWk#N5$($LxK!!h>Am5Lk$4g{1n2SzZkZRB zDF}|cXnl+XGqtc~cbGhAms#`>YM#wWE4j{)KM?N?qoa@telESzKxtHIeh(Ljb7j~- bYP4{L^NNA0?ouc{Q{O}OwZqz7=XHJoQ(ip7 literal 0 HcmV?d00001 diff --git a/src/test/ui/parser/issue-68730.stderr b/src/test/ui/parser/issue-68730.stderr new file mode 100644 index 0000000000000000000000000000000000000000..5f9ed56e2d7e9fe3fb822cc5a40648bf6b146dd6 GIT binary patch literal 957 zcmd5*O-sW-5bZg?;vIx4B-&Q0HH3oTMTi$aZc>salV(Y~Q})9O)=U0g{*>Ds{D7)O zJ-F;)cV^l5=DitGid6_JE6FPfZBk{x1q@dtL)_b^-m?b;!5DiNm)A!^YfHh&==8XE zsB}0Chc1h?7sptGq+N7q(P`?YZo@7GOgxW%i!%BaWk;MrHu$=pvz?IInoF85L)=M` zaZbp}RHd0Ag>F-Kv46$6D1^JlWH!;53WIYe#Hyq;Kfs*1(wK{i(2d;tn6wUV%T(e< z%;bTOsWlL8Ye+U*SViwe{;Tr)y)8%|{cJ7$4+1oG)RJ{v+V$3G^tdEvMGls<>E>jd z_((FA+PH(rNt)IhAFP}O1sSm*9|c>PBZ(6C?dKie@9!cJCioGH*I`Mgtc;K| Date: Sat, 1 Feb 2020 18:40:12 +0100 Subject: [PATCH 0735/1253] Remove `Alloc` in favor of `AllocRef` `AllocRef` was reexported as `Alloc` in order to not break toolstate in the week before the next stable release. --- src/libcore/alloc.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 1b7dfafbd704c..38df843d258d3 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -1227,10 +1227,3 @@ pub unsafe trait AllocRef { } } } - -// In order to rename `Alloc` to `AllocRef`, some submoduleshas to be updated as well. The CI fails -// if either of the submodules fails to compile. The submodules have their own CI depending on a -// specific Rust version, which don't have `AllocRef` yet. This alias is used to make the submodules -// compile and pass the CI. -#[unstable(feature = "allocator_api", issue = "32838")] -pub use self::AllocRef as Alloc; From 50f0e2e9e6e85c5ae15ffde79e34edfd284465fd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 09:48:57 +0100 Subject: [PATCH 0736/1253] {syntax -> rustc_ast_passes}::node_count --- src/librustc_ast_passes/lib.rs | 3 +++ src/{libsyntax/util => librustc_ast_passes}/node_count.rs | 4 ++-- src/librustc_interface/passes.rs | 3 +-- src/libsyntax/lib.rs | 1 - 4 files changed, 6 insertions(+), 5 deletions(-) rename src/{libsyntax/util => librustc_ast_passes}/node_count.rs (98%) diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index 5de45f4e1f365..b4d8ddccb041d 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -1,9 +1,12 @@ //! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax` //! parsed by `rustc_parse` and then lowered, after the passes in this crate, //! by `rustc_ast_lowering`. +//! +//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`. #![cfg_attr(bootstrap, feature(slice_patterns))] pub mod ast_validation; pub mod feature_gate; +pub mod node_count; pub mod show_span; diff --git a/src/libsyntax/util/node_count.rs b/src/librustc_ast_passes/node_count.rs similarity index 98% rename from src/libsyntax/util/node_count.rs rename to src/librustc_ast_passes/node_count.rs index 39f978ce98c6c..9fe7238fcfc3e 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/librustc_ast_passes/node_count.rs @@ -1,8 +1,8 @@ // Simply gives a rought count of the number of nodes in an AST. -use crate::ast::*; -use crate::visit::*; use rustc_span::Span; +use syntax::ast::*; +use syntax::visit::*; pub struct NodeCounter { pub count: usize, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d62c7539d5f21..c22c00e9154e7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -40,7 +40,6 @@ use rustc_span::FileName; use rustc_traits; use rustc_typeck as typeck; use syntax::mut_visit::MutVisitor; -use syntax::util::node_count::NodeCounter; use syntax::{self, ast, visit}; use rustc_serialize::json; @@ -83,7 +82,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { } fn count_nodes(krate: &ast::Crate) -> usize { - let mut counter = NodeCounter::new(); + let mut counter = rustc_ast_passes::node_count::NodeCounter::new(); visit::walk_crate(&mut counter, krate); counter.count } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b0c2aa3dbb28e..6c88cd738f4c9 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -67,7 +67,6 @@ pub mod util { pub mod lev_distance; pub mod literal; pub mod map_in_place; - pub mod node_count; pub mod parser; } From e03d1064f0d98961b83885ce951351ae57cc7aad Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 09:59:14 +0100 Subject: [PATCH 0737/1253] syntax: move GLOBALS to attr module --- src/librustc_expand/expand.rs | 2 +- src/librustc_interface/interface.rs | 2 +- src/librustc_interface/util.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libsyntax/attr/mod.rs | 37 ++++++++++++++++++++++++++--- src/libsyntax/lib.rs | 34 -------------------------- 6 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index ea459064b0957..910a0e52e53cf 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1671,7 +1671,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items); - *at = attr::Attribute { + *at = ast::Attribute { kind: ast::AttrKind::Normal(AttrItem { path: meta.path, args: meta.kind.mac_args(meta.span), diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 9cd9eb66cf6c1..f491d662f971d 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -65,7 +65,7 @@ impl Compiler { /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option)> { - syntax::with_default_globals(move || { + syntax::attr::with_default_globals(move || { let cfg = cfgspecs .into_iter() .map(|s| { diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 00528eca92301..6bda85ded2b7b 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -146,7 +146,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( crate::callbacks::setup_callbacks(); scoped_thread(cfg, || { - syntax::with_globals(edition, || { + syntax::attr::with_globals(edition, || { ty::tls::GCX_PTR.set(&Lock::new(0), || { if let Some(stderr) = stderr { io::set_panic(Some(box Sink(stderr.clone()))); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d89dc2adafeb3..ba36e06fd37f2 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -18,7 +18,7 @@ use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; use syntax::ast; -use syntax::with_globals; +use syntax::attr::with_globals; use tempfile::Builder as TempFileBuilder; use testing; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index ec05dab451af8..419297678d2c7 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -2,22 +2,24 @@ mod builtin; -pub use crate::ast::Attribute; pub use builtin::*; pub use IntType::*; pub use ReprAttr::*; pub use StabilityLevel::*; use crate::ast; -use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Ident, Name, Path, PathSegment}; +use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; use crate::ast::{Expr, GenericParam, Item, Lit, LitKind, Local, Stmt, StmtKind}; +use crate::ast::{Ident, Name, Path, PathSegment}; use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; use crate::mut_visit::visit_clobber; use crate::ptr::P; use crate::token::{self, Token}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; -use crate::GLOBALS; +use rustc_data_structures::sync::Lock; +use rustc_index::bit_set::GrowableBitSet; +use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::source_map::{BytePos, Spanned}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; @@ -26,6 +28,35 @@ use log::debug; use std::iter; use std::ops::DerefMut; +pub struct Globals { + used_attrs: Lock>, + known_attrs: Lock>, + rustc_span_globals: rustc_span::Globals, +} + +impl Globals { + fn new(edition: Edition) -> Globals { + Globals { + // We have no idea how many attributes there will be, so just + // initiate the vectors with 0 bits. We'll grow them as necessary. + used_attrs: Lock::new(GrowableBitSet::new_empty()), + known_attrs: Lock::new(GrowableBitSet::new_empty()), + rustc_span_globals: rustc_span::Globals::new(edition), + } + } +} + +pub fn with_globals(edition: Edition, f: impl FnOnce() -> R) -> R { + let globals = Globals::new(edition); + GLOBALS.set(&globals, || rustc_span::GLOBALS.set(&globals.rustc_span_globals, f)) +} + +pub fn with_default_globals(f: impl FnOnce() -> R) -> R { + with_globals(DEFAULT_EDITION, f) +} + +scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals); + pub fn mark_used(attr: &Attribute) { debug!("marking {:?} as used", attr); GLOBALS.with(|globals| { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 6c88cd738f4c9..9fcc7a1dfa899 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -17,11 +17,6 @@ #![feature(unicode_internals)] #![recursion_limit = "256"] -use ast::AttrId; -use rustc_data_structures::sync::Lock; -use rustc_index::bit_set::GrowableBitSet; -use rustc_span::edition::{Edition, DEFAULT_EDITION}; - #[macro_export] macro_rules! unwrap_or { ($opt:expr, $default:expr) => { @@ -32,35 +27,6 @@ macro_rules! unwrap_or { }; } -pub struct Globals { - used_attrs: Lock>, - known_attrs: Lock>, - rustc_span_globals: rustc_span::Globals, -} - -impl Globals { - fn new(edition: Edition) -> Globals { - Globals { - // We have no idea how many attributes there will be, so just - // initiate the vectors with 0 bits. We'll grow them as necessary. - used_attrs: Lock::new(GrowableBitSet::new_empty()), - known_attrs: Lock::new(GrowableBitSet::new_empty()), - rustc_span_globals: rustc_span::Globals::new(edition), - } - } -} - -pub fn with_globals(edition: Edition, f: impl FnOnce() -> R) -> R { - let globals = Globals::new(edition); - GLOBALS.set(&globals, || rustc_span::GLOBALS.set(&globals.rustc_span_globals, f)) -} - -pub fn with_default_globals(f: impl FnOnce() -> R) -> R { - with_globals(DEFAULT_EDITION, f) -} - -scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals); - pub mod util { pub mod classify; pub mod comments; From 64d0143c2c5f627e246822b4e2f501e563ec63cc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 10:33:18 +0100 Subject: [PATCH 0738/1253] pretty: remove ParseSess dependency --- src/librustc_driver/pretty.rs | 18 ++++++++---------- src/librustc_hir/print.rs | 7 ++----- src/libsyntax/print/pprust.rs | 28 +++++++++++----------------- src/libsyntax/util/comments.rs | 5 ++--- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 6ef6dcf87eddb..5cd9e9a4a5848 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -392,14 +392,16 @@ pub fn print_after_parsing( call_with_pp_support(&s, sess, None, move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); + let parse = &sess.parse_sess; *out = pprust::print_crate( sess.source_map(), - &sess.parse_sess, krate, src_name, src, annotation.pp_ann(), false, + parse.edition, + &parse.injected_crate_name, ) }) } else { @@ -432,14 +434,16 @@ pub fn print_after_hir_lowering<'tcx>( call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); + let parse = &sess.parse_sess; *out = pprust::print_crate( sess.source_map(), - &sess.parse_sess, krate, src_name, src, annotation.pp_ann(), true, + parse.edition, + &parse.injected_crate_name, ) }) } @@ -449,14 +453,8 @@ pub fn print_after_hir_lowering<'tcx>( call_with_pp_support_hir(&s, tcx, move |annotation, krate| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - *out = pprust_hir::print_crate( - sess.source_map(), - &sess.parse_sess, - krate, - src_name, - src, - annotation.pp_ann(), - ) + let cm = sess.source_map(); + *out = pprust_hir::print_crate(cm, krate, src_name, src, annotation.pp_ann()) }) } diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index b9598c9376146..7beabacecc292 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -6,7 +6,6 @@ use syntax::ast; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; use syntax::print::pp::{self, Breaks}; use syntax::print::pprust::{self, Comments, PrintState}; -use syntax::sess::ParseSess; use syntax::util::parser::{self, AssocOp, Fixity}; use crate::hir; @@ -142,13 +141,12 @@ pub const INDENT_UNIT: usize = 4; /// it can scan the input text for comments to copy forward. pub fn print_crate<'a>( cm: &'a SourceMap, - sess: &ParseSess, krate: &hir::Crate<'_>, filename: FileName, input: String, ann: &'a dyn PpAnn, ) -> String { - let mut s = State::new_from_input(cm, sess, filename, input, ann); + let mut s = State::new_from_input(cm, filename, input, ann); // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. @@ -161,12 +159,11 @@ pub fn print_crate<'a>( impl<'a> State<'a> { pub fn new_from_input( cm: &'a SourceMap, - sess: &ParseSess, filename: FileName, input: String, ann: &'a dyn PpAnn, ) -> State<'a> { - State { s: pp::mk_printer(), comments: Some(Comments::new(cm, sess, filename, input)), ann } + State { s: pp::mk_printer(), comments: Some(Comments::new(cm, filename, input)), ann } } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d6f18fda8b25c..624d1c70c158d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -5,15 +5,16 @@ use crate::attr; use crate::print::pp::Breaks::{Consistent, Inconsistent}; use crate::print::pp::{self, Breaks}; use crate::ptr::P; -use crate::sess::ParseSess; use crate::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind}; use crate::tokenstream::{self, TokenStream, TokenTree}; use crate::util::classify; use crate::util::comments; use crate::util::parser::{self, AssocOp, Fixity}; +use rustc_data_structures::sync::Once; +use rustc_span::edition::Edition; use rustc_span::source_map::{dummy_spanned, SourceMap, Spanned}; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, Span}; use std::borrow::Cow; @@ -54,13 +55,8 @@ pub struct Comments<'a> { } impl<'a> Comments<'a> { - pub fn new( - cm: &'a SourceMap, - sess: &ParseSess, - filename: FileName, - input: String, - ) -> Comments<'a> { - let comments = comments::gather_comments(sess, filename, input); + pub fn new(cm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> { + let comments = comments::gather_comments(cm, filename, input); Comments { cm, comments, current: 0 } } @@ -102,21 +98,22 @@ crate const INDENT_UNIT: usize = 4; /// it can scan the input text for comments to copy forward. pub fn print_crate<'a>( cm: &'a SourceMap, - sess: &ParseSess, krate: &ast::Crate, filename: FileName, input: String, ann: &'a dyn PpAnn, is_expanded: bool, + edition: Edition, + injected_crate_name: &Once, ) -> String { let mut s = State { s: pp::mk_printer(), - comments: Some(Comments::new(cm, sess, filename, input)), + comments: Some(Comments::new(cm, filename, input)), ann, is_expanded, }; - if is_expanded && sess.injected_crate_name.try_get().is_some() { + if is_expanded && injected_crate_name.try_get().is_some() { // We need to print `#![no_std]` (and its feature gate) so that // compiling pretty-printed source won't inject libstd again. // However, we don't want these attributes in the AST because @@ -130,7 +127,7 @@ pub fn print_crate<'a>( // Currently, in Rust 2018 we don't have `extern crate std;` at the crate // root, so this is not needed, and actually breaks things. - if sess.edition == rustc_span::edition::Edition::Edition2015 { + if edition == Edition::Edition2015 { // `#![no_std]` let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std)); let fake_attr = attr::mk_attr_inner(no_std_meta); @@ -144,10 +141,7 @@ pub fn print_crate<'a>( s.s.eof() } -pub fn to_string(f: F) -> String -where - F: FnOnce(&mut State<'_>), -{ +pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String { let mut printer = State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false }; f(&mut printer); diff --git a/src/libsyntax/util/comments.rs b/src/libsyntax/util/comments.rs index c385b498ced72..de33189884c3a 100644 --- a/src/libsyntax/util/comments.rs +++ b/src/libsyntax/util/comments.rs @@ -1,7 +1,6 @@ pub use CommentStyle::*; use crate::ast; -use crate::sess::ParseSess; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, CharPos, FileName, Pos}; @@ -191,8 +190,8 @@ fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec { // it appears this function is called only from pprust... that's // probably not a good thing. -crate fn gather_comments(sess: &ParseSess, path: FileName, src: String) -> Vec { - let cm = SourceMap::new(sess.source_map().path_mapping().clone()); +crate fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec { + let cm = SourceMap::new(sm.path_mapping().clone()); let source_file = cm.new_source_file(path, src); let text = (*source_file.src.as_ref().unwrap()).clone(); From 9be73dc63a63bc8692423bdac073c591dff80ccd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 12:33:11 +0100 Subject: [PATCH 0739/1253] syntax: simplify HasAttrs code --- src/librustc_expand/base.rs | 2 +- src/libsyntax/attr/mod.rs | 32 +++++++++++--------------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 9debae19fa57e..af02070828a0c 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -62,7 +62,7 @@ impl HasAttrs for Annotatable { } } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { match self { Annotatable::Item(item) => item.visit_attrs(f), Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f), diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 419297678d2c7..a78fbe276faf1 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -657,15 +657,15 @@ impl NestedMetaItem { } pub trait HasAttrs: Sized { - fn attrs(&self) -> &[ast::Attribute]; - fn visit_attrs)>(&mut self, f: F); + fn attrs(&self) -> &[Attribute]; + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)); } impl HasAttrs for Spanned { - fn attrs(&self) -> &[ast::Attribute] { + fn attrs(&self) -> &[Attribute] { self.node.attrs() } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { self.node.visit_attrs(f); } } @@ -674,7 +674,7 @@ impl HasAttrs for Vec { fn attrs(&self) -> &[Attribute] { self } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { f(self) } } @@ -683,7 +683,7 @@ impl HasAttrs for AttrVec { fn attrs(&self) -> &[Attribute] { self } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { visit_clobber(self, |this| { let mut vec = this.into(); f(&mut vec); @@ -696,7 +696,7 @@ impl HasAttrs for P { fn attrs(&self) -> &[Attribute] { (**self).attrs() } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { (**self).visit_attrs(f); } } @@ -714,7 +714,7 @@ impl HasAttrs for StmtKind { } } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { match self { StmtKind::Local(local) => local.visit_attrs(f), StmtKind::Item(..) => {} @@ -733,21 +733,11 @@ impl HasAttrs for Stmt { self.kind.attrs() } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { self.kind.visit_attrs(f); } } -impl HasAttrs for GenericParam { - fn attrs(&self) -> &[ast::Attribute] { - &self.attrs - } - - fn visit_attrs)>(&mut self, f: F) { - self.attrs.visit_attrs(f); - } -} - macro_rules! derive_has_attrs { ($($ty:path),*) => { $( impl HasAttrs for $ty { @@ -755,7 +745,7 @@ macro_rules! derive_has_attrs { &self.attrs } - fn visit_attrs)>(&mut self, f: F) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { self.attrs.visit_attrs(f); } } @@ -764,5 +754,5 @@ macro_rules! derive_has_attrs { derive_has_attrs! { Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::AssocItem, ast::Arm, - ast::Field, ast::FieldPat, ast::Variant, ast::Param + ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam } From 93a8283614e995a0cf7a866356609b7522cfda24 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 13:15:20 +0100 Subject: [PATCH 0740/1253] Move builtin attribute logic to new rustc_attr crate. For now, this is all the crate contains, but more attribute logic & types will be moved there over time. --- Cargo.lock | 31 +++++++++++++++++++ src/librustc/Cargo.toml | 1 + src/librustc/ich/impls_hir.rs | 2 +- src/librustc/middle/codegen_fn_attrs.rs | 2 +- src/librustc/middle/stability.rs | 2 +- src/librustc/mir/mono.rs | 2 +- src/librustc/traits/on_unimplemented.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/layout.rs | 2 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/print/pretty.rs | 2 +- src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/util.rs | 2 +- src/librustc_ast_passes/Cargo.toml | 1 + src/librustc_ast_passes/ast_validation.rs | 2 +- src/librustc_attr/Cargo.toml | 21 +++++++++++++ .../attr => librustc_attr}/builtin.rs | 8 ++--- src/librustc_attr/lib.rs | 16 ++++++++++ src/librustc_builtin_macros/Cargo.toml | 1 + src/librustc_builtin_macros/cfg.rs | 2 +- .../deriving/generic/mod.rs | 2 +- src/librustc_codegen_llvm/Cargo.toml | 1 + src/librustc_codegen_llvm/attributes.rs | 2 +- src/librustc_codegen_ssa/Cargo.toml | 1 + src/librustc_codegen_ssa/back/link.rs | 2 +- src/librustc_codegen_ssa/base.rs | 2 +- src/librustc_expand/Cargo.toml | 1 + src/librustc_expand/base.rs | 2 +- src/librustc_expand/expand.rs | 2 +- src/librustc_expand/mbe/macro_rules.rs | 2 +- src/librustc_interface/Cargo.toml | 1 + src/librustc_interface/util.rs | 4 +-- src/librustc_lint/Cargo.toml | 1 + src/librustc_lint/nonstandard_style.rs | 2 +- src/librustc_lint/types.rs | 3 +- src/librustc_metadata/Cargo.toml | 1 + src/librustc_metadata/native_libs.rs | 2 +- src/librustc_metadata/rmeta/decoder.rs | 2 +- src/librustc_metadata/rmeta/mod.rs | 3 +- src/librustc_mir/Cargo.toml | 1 + src/librustc_mir/const_eval/fn_queries.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir_build/Cargo.toml | 1 + .../build/matches/simplify.rs | 2 +- src/librustc_mir_build/build/mod.rs | 2 +- src/librustc_mir_build/hair/pattern/_match.rs | 2 +- src/librustc_mir_build/hair/pattern/mod.rs | 2 +- src/librustc_parse/Cargo.toml | 1 + src/librustc_parse/config.rs | 2 +- src/librustc_passes/Cargo.toml | 1 + src/librustc_passes/stability.rs | 2 +- src/librustc_privacy/Cargo.toml | 1 + src/librustc_privacy/lib.rs | 2 +- src/librustc_resolve/Cargo.toml | 1 + src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_typeck/Cargo.toml | 1 + src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/core.rs | 2 +- src/librustdoc/lib.rs | 1 + src/libsyntax/attr/mod.rs | 7 ----- 63 files changed, 133 insertions(+), 53 deletions(-) create mode 100644 src/librustc_attr/Cargo.toml rename src/{libsyntax/attr => librustc_attr}/builtin.rs (99%) create mode 100644 src/librustc_attr/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c081f2fbf20ea..55f7a8357b705 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3093,6 +3093,7 @@ dependencies = [ "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3374,6 +3375,7 @@ name = "rustc_ast_passes" version = "0.0.0" dependencies = [ "log", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3383,12 +3385,28 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_attr" +version = "0.0.0" +dependencies = [ + "rustc_data_structures", + "rustc_errors", + "rustc_feature", + "rustc_macros", + "rustc_session", + "rustc_span", + "serialize", + "smallvec 1.0.0", + "syntax", +] + [[package]] name = "rustc_builtin_macros" version = "0.0.0" dependencies = [ "fmt_macros", "log", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -3411,6 +3429,7 @@ dependencies = [ "log", "rustc", "rustc-demangle", + "rustc_attr", "rustc_codegen_ssa", "rustc_codegen_utils", "rustc_data_structures", @@ -3442,6 +3461,7 @@ dependencies = [ "num_cpus", "rustc", "rustc_apfloat", + "rustc_attr", "rustc_codegen_utils", "rustc_data_structures", "rustc_errors", @@ -3552,6 +3572,7 @@ version = "0.0.0" dependencies = [ "log", "rustc_ast_passes", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3628,6 +3649,7 @@ dependencies = [ "rustc-rayon", "rustc_ast_lowering", "rustc_ast_passes", + "rustc_attr", "rustc_builtin_macros", "rustc_codegen_llvm", "rustc_codegen_ssa", @@ -3672,6 +3694,7 @@ version = "0.0.0" dependencies = [ "log", "rustc", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3712,6 +3735,7 @@ dependencies = [ "log", "memmap", "rustc", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -3739,6 +3763,7 @@ dependencies = [ "polonius-engine", "rustc", "rustc_apfloat", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -3761,6 +3786,7 @@ dependencies = [ "log", "rustc", "rustc_apfloat", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -3780,6 +3806,7 @@ version = "0.0.0" dependencies = [ "bitflags", "log", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3797,6 +3824,7 @@ version = "0.0.0" dependencies = [ "log", "rustc", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3827,6 +3855,7 @@ version = "0.0.0" dependencies = [ "log", "rustc", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -3844,6 +3873,7 @@ dependencies = [ "log", "rustc", "rustc_ast_lowering", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -3961,6 +3991,7 @@ dependencies = [ "arena", "log", "rustc", + "rustc_attr", "rustc_data_structures", "rustc_errors", "rustc_hir", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index b65635be54a3f..782c6879ac58f 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -21,6 +21,7 @@ rustc-rayon = "0.3.0" rustc-rayon-core = "0.3.0" polonius-engine = "0.11.0" rustc_apfloat = { path = "../librustc_apfloat" } +rustc_attr = { path = "../librustc_attr" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 8961f7cd4bc95..061b82ebb430e 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -3,12 +3,12 @@ use crate::hir::map::DefPathHash; use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; +use rustc_attr as attr; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; use smallvec::SmallVec; use std::mem; -use syntax::attr; impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { #[inline] diff --git a/src/librustc/middle/codegen_fn_attrs.rs b/src/librustc/middle/codegen_fn_attrs.rs index 3b109f2fea687..9f8c20208616b 100644 --- a/src/librustc/middle/codegen_fn_attrs.rs +++ b/src/librustc/middle/codegen_fn_attrs.rs @@ -1,6 +1,6 @@ use crate::mir::mono::Linkage; +use rustc_attr::{InlineAttr, OptimizeAttr}; use rustc_span::symbol::Symbol; -use syntax::attr::{InlineAttr, OptimizeAttr}; #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct CodegenFnAttrs { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 1176ffc79d26d..752b0945e71cf 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -5,6 +5,7 @@ pub use self::StabilityLevel::*; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; +use rustc_attr::{self as attr, ConstStability, Deprecation, RustcDeprecation, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::GateIssue; @@ -16,7 +17,6 @@ use rustc_session::lint::{self, BuiltinLintDiagnostics, Lint, LintBuffer}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; -use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability}; use syntax::sess::feature_err_issue; use std::num::NonZeroU32; diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index d19732664635f..6da7c09c7df9e 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -3,6 +3,7 @@ use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; use crate::session::config::OptLevel; use crate::ty::print::obsolete::DefPathBasedNames; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; +use rustc_attr::InlineAttr; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -12,7 +13,6 @@ use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; use std::fmt; use std::hash::Hash; -use syntax::attr::InlineAttr; /// Describes how a monomorphization will be instantiated in object files. #[derive(PartialEq)] diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 669ec5ccc9b98..ca824d40e381a 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -3,13 +3,13 @@ use fmt_macros::{Parser, Piece, Position}; use crate::ty::{self, GenericParamDefKind, TyCtxt}; use crate::util::common::ErrorReported; +use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast::{MetaItem, NestedMetaItem}; -use syntax::attr; #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString(Symbol); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 355df86046f43..8d0b775656576 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -51,6 +51,7 @@ use rustc_session::config::CrateType; use rustc_session::config::{BorrowckMode, OutputFilenames}; use rustc_session::Session; +use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -79,7 +80,6 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; use syntax::ast; -use syntax::attr; use syntax::expand::allocator::AllocatorKind; type InternedSet<'tcx, T> = ShardedHashMap, ()>; diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index acaa4eec9410d..bda42db40b0ae 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1,9 +1,9 @@ use crate::session::{self, DataTypeKind}; use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; +use rustc_attr as attr; use rustc_span::DUMMY_SP; use syntax::ast::{self, Ident, IntTy, UintTy}; -use syntax::attr; use std::cmp; use std::fmt; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4889f751f601b..24b22d3f6821c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -26,6 +26,7 @@ use crate::ty::layout::VariantIdx; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; use crate::ty::walk::TypeWalker; +use rustc_attr as attr; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; @@ -53,7 +54,6 @@ use std::ops::Range; use std::slice; use std::{mem, ptr}; use syntax::ast::{self, Constness, Ident, Name, NodeId}; -use syntax::attr; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index db539f9195c9d..f5c14e73db2bc 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -11,10 +11,10 @@ use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; +use rustc_attr::{SignedInt, UnsignedInt}; use rustc_span::symbol::{kw, Symbol}; use rustc_target::spec::abi::Abi; use syntax::ast; -use syntax::attr::{SignedInt, UnsignedInt}; use std::cell::Cell; use std::collections::BTreeMap; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 0f09a08b199f1..973cd81014616 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -49,6 +49,7 @@ use rustc_hir::{HirIdSet, ItemLocalId, TraitCandidate}; use rustc_index::vec::IndexVec; use rustc_target::spec::PanicStrategy; +use rustc_attr as attr; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; use std::any::type_name; @@ -56,7 +57,6 @@ use std::borrow::Cow; use std::ops::Deref; use std::sync::Arc; use syntax::ast; -use syntax::attr; #[macro_use] mod plumbing; diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 8d22ac9dbbe97..4dfff85d53147 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -10,6 +10,7 @@ use crate::ty::TyKind::*; use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable}; use crate::util::common::ErrorReported; use rustc_apfloat::Float as _; +use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; @@ -19,7 +20,6 @@ use rustc_macros::HashStable; use rustc_span::Span; use std::{cmp, fmt}; use syntax::ast; -use syntax::attr::{self, SignedInt, UnsignedInt}; #[derive(Copy, Clone, Debug)] pub struct Discr<'tcx> { diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index 25b1acebd2a08..2b25f04ce9aca 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" [dependencies] log = "0.4" +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 152086bfce0ea..c6ea97be583ba 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -331,7 +331,7 @@ impl<'a> AstValidator<'a> { .flat_map(|i| i.attrs.as_ref()) .filter(|attr| { let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn]; - !arr.contains(&attr.name_or_empty()) && attr::is_builtin_attr(attr) + !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(attr) }) .for_each(|attr| { if attr.is_doc_comment() { diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml new file mode 100644 index 0000000000000..acb93e1d64070 --- /dev/null +++ b/src/librustc_attr/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_attr" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_attr" +path = "lib.rs" +doctest = false + +[dependencies] +rustc_serialize = { path = "../libserialize", package = "serialize" } +rustc_errors = { path = "../librustc_errors" } +rustc_span = { path = "../librustc_span" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_feature = { path = "../librustc_feature" } +rustc_macros = { path = "../librustc_macros" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_session = { path = "../librustc_session" } +syntax = { path = "../libsyntax" } diff --git a/src/libsyntax/attr/builtin.rs b/src/librustc_attr/builtin.rs similarity index 99% rename from src/libsyntax/attr/builtin.rs rename to src/librustc_attr/builtin.rs index 1da005d70d41b..f13f19073ea3c 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -1,16 +1,16 @@ //! Parsing and validation of builtin attributes -use super::{mark_used, MetaItemKind}; -use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; -use crate::print::pprust; -use crate::sess::{feature_err, ParseSess}; +use super::mark_used; use rustc_errors::{struct_span_err, Applicability, Handler}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; +use rustc_session::parse::{feature_err, ParseSess}; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; +use syntax::ast::{self, Attribute, MetaItem, MetaItemKind, NestedMetaItem}; +use syntax::print::pprust; pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() diff --git a/src/librustc_attr/lib.rs b/src/librustc_attr/lib.rs new file mode 100644 index 0000000000000..d2ff167db88e5 --- /dev/null +++ b/src/librustc_attr/lib.rs @@ -0,0 +1,16 @@ +//! Functions and types dealing with attributes and meta items. +//! +//! FIXME(Centril): For now being, much of the logic is still in `syntax::attr`. +//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` +//! to this crate. + +mod builtin; + +pub use builtin::*; +pub use IntType::*; +pub use ReprAttr::*; +pub use StabilityLevel::*; + +pub use syntax::attr::*; + +pub(crate) use syntax::HashStableContext; diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index 3ce7f5d770ed1..d0558a50acf64 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -12,6 +12,7 @@ doctest = false [dependencies] fmt_macros = { path = "../libfmt_macros" } log = "0.4" +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_builtin_macros/cfg.rs b/src/librustc_builtin_macros/cfg.rs index cee62a54f0088..c9a77ee0acd15 100644 --- a/src/librustc_builtin_macros/cfg.rs +++ b/src/librustc_builtin_macros/cfg.rs @@ -2,11 +2,11 @@ //! a literal `true` or `false` based on whether the given cfg matches the //! current compilation environment. +use rustc_attr as attr; use rustc_errors::DiagnosticBuilder; use rustc_expand::base::{self, *}; use rustc_span::Span; use syntax::ast; -use syntax::attr; use syntax::token; use syntax::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 9377f194dcd5e..d0208cb33a79e 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -181,13 +181,13 @@ use std::cell::RefCell; use std::iter; use std::vec; +use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; use syntax::ast::{GenericArg, GenericParamKind, VariantData}; -use syntax::attr; use syntax::ptr::P; use syntax::sess::ParseSess; use syntax::util::map_in_place::MapInPlace; diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index dd9eadde098ec..e7c0ee5ea763e 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -17,6 +17,7 @@ libc = "0.2" log = "0.4" rustc = { path = "../librustc" } rustc-demangle = "0.1" +rustc_attr = { path = "../librustc_attr" } rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index fc1b365cf90ce..e3920d99c90bc 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -21,7 +21,7 @@ use crate::attributes; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, Attribute}; use crate::llvm_util; -pub use syntax::attr::{self, InlineAttr, OptimizeAttr}; +pub use rustc_attr::{self as attr, InlineAttr, OptimizeAttr}; use crate::context::CodegenCx; use crate::value::Value; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 9f8b4e72a9cbf..8d767e5c2a04f 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -24,6 +24,7 @@ syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } rustc = { path = "../librustc" } rustc_apfloat = { path = "../librustc_apfloat" } +rustc_attr = { path = "../librustc_attr" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_data_structures = { path = "../librustc_data_structures"} rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index f56a4170c0a4b..7192002009197 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1719,7 +1719,7 @@ pub fn add_upstream_native_libraries( pub fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool { match lib.cfg { - Some(ref cfg) => syntax::attr::cfg_matches(cfg, &sess.parse_sess, None), + Some(ref cfg) => rustc_attr::cfg_matches(cfg, &sess.parse_sess, None), None => true, } } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index efd560071202c..1f43a4027c5ff 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -37,6 +37,7 @@ use rustc::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyLayout, VariantIdx}; use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc::ty::query::Providers; use rustc::ty::{self, Instance, Ty, TyCtxt}; +use rustc_attr as attr; use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::print_time_passes_entry; @@ -46,7 +47,6 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::Idx; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_span::Span; -use syntax::attr; use std::cmp; use std::ops::{Deref, DerefMut}; diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index d04dd079be75d..1310e7fbd095f 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -15,6 +15,7 @@ rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" rustc_span = { path = "../librustc_span" } rustc_ast_passes = { path = "../librustc_ast_passes" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index af02070828a0c..52e5798ec194c 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1,5 +1,6 @@ use crate::expand::{self, AstFragment, Invocation}; +use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; @@ -11,7 +12,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{FileName, MultiSpan, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use syntax::ast::{self, Attribute, Name, NodeId, PatKind}; -use syntax::attr::{self, Deprecation, HasAttrs, Stability}; use syntax::mut_visit::{self, MutVisitor}; use syntax::ptr::P; use syntax::sess::ParseSess; diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 910a0e52e53cf..35b6b96d49b39 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -5,6 +5,7 @@ use crate::mbe::macro_rules::annotate_err_with_kind; use crate::placeholders::{placeholder, PlaceholderExpander}; use crate::proc_macro::collect_derives; +use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; @@ -17,7 +18,6 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path}; use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; -use syntax::attr::{self, is_builtin_attr, HasAttrs}; use syntax::mut_visit::*; use syntax::print::pprust; use syntax::ptr::P; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index d72317af9eb67..3dbe8e7983c3d 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -8,6 +8,7 @@ use crate::mbe::macro_parser::{Error, Failure, Success}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; use crate::mbe::transcribe::transcribe; +use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder, FatalError}; @@ -19,7 +20,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast; -use syntax::attr::{self, TransparencyError}; use syntax::print::pprust; use syntax::sess::ParseSess; use syntax::token::{self, NtTT, Token, TokenKind::*}; diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 1fe5248dbf4ce..de7a9f4f5af1c 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -14,6 +14,7 @@ log = "0.4" rayon = { version = "0.3.0", package = "rustc-rayon" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } +rustc_attr = { path = "../librustc_attr" } rustc_builtin_macros = { path = "../librustc_builtin_macros" } rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 6bda85ded2b7b..56121fba2d53a 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -32,7 +32,7 @@ use syntax::ast::{AttrVec, BlockCheckMode}; use syntax::mut_visit::{visit_clobber, MutVisitor, *}; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; -use syntax::{self, ast, attr}; +use syntax::{self, ast}; /// Adds `target_feature = "..."` cfgs for a variety of platform /// specific features (SSE, NEON etc.). @@ -547,7 +547,7 @@ pub fn build_output_filenames( .opts .crate_name .clone() - .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) + .or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string())) .unwrap_or_else(|| input.filestem().to_owned()); OutputFilenames::new( diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 7e23e70577975..d32622c09c623 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" log = "0.4" unicode-security = "0.0.2" rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 394da4a5bb0c1..6fdbfea7f03b3 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,5 +1,6 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty; +use rustc_attr as attr; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -9,7 +10,6 @@ use rustc_span::symbol::sym; use rustc_span::{symbol::Ident, BytePos, Span}; use rustc_target::spec::abi::Abi; use syntax::ast; -use syntax::attr; #[derive(PartialEq)] pub enum MethodLateContext { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index d96ba59d9a353..6bc6f58f3e7fd 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -5,6 +5,7 @@ use rustc::mir::interpret::{sign_extend, truncate}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; +use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; @@ -15,7 +16,7 @@ use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi::Abi; -use syntax::{ast, attr}; +use syntax::ast; use log::debug; use std::cmp; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 6da584733aea0..a74f886043b6a 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -15,6 +15,7 @@ log = "0.4" memmap = "0.7" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index bbf6973be51a7..2fa9cb099dd51 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -2,6 +2,7 @@ use rustc::middle::cstore::{self, NativeLibrary}; use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::ty::TyCtxt; +use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -9,7 +10,6 @@ use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; -use syntax::attr; crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new() }; diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 6280121f65566..58cf142ab3a36 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -34,6 +34,7 @@ use std::u32; use log::debug; use proc_macro::bridge::client::ProcMacro; +use rustc_attr as attr; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder}; @@ -41,7 +42,6 @@ use rustc_span::source_map::{self, respan, Spanned}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP}; use syntax::ast::{self, Ident}; -use syntax::attr; pub use cstore_impl::{provide, provide_extern}; diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 426ea62b8cd4c..77ec3eb4555e3 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -10,6 +10,7 @@ use rustc::mir; use rustc::session::config::SymbolManglingVersion; use rustc::session::CrateDisambiguator; use rustc::ty::{self, ReprOptions, Ty}; +use rustc_attr as attr; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; use rustc_hir as hir; @@ -21,7 +22,7 @@ use rustc_span::edition::Edition; use rustc_span::symbol::Symbol; use rustc_span::{self, Span}; use rustc_target::spec::{PanicStrategy, TargetTriple}; -use syntax::{ast, attr}; +use syntax::ast; use std::marker::PhantomData; use std::num::NonZeroUsize; diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 00881e3ea6f19..eead88dcb0c30 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -17,6 +17,7 @@ log = "0.4" log_settings = "0.1.1" polonius-engine = "0.11.0" rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs index 5eeb92f583b98..4144bbc41d217 100644 --- a/src/librustc_mir/const_eval/fn_queries.rs +++ b/src/librustc_mir/const_eval/fn_queries.rs @@ -1,11 +1,11 @@ use rustc::hir::map::blocks::FnLikeNode; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_attr as attr; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; -use syntax::attr; /// Whether the `def_id` counts as const fn in your current crate, considering all active /// feature gates diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 56b6fa68e1841..a3cafcb576323 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -16,8 +16,8 @@ use crate::transform::{MirPass, MirSource}; use std::collections::VecDeque; use std::iter; +use rustc_attr as attr; use rustc_target::spec::abi::Abi; -use syntax::attr; const DEFAULT_THRESHOLD: usize = 50; const HINT_THRESHOLD: usize = 100; diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml index a22c4d18d516a..9ff3ed1a93588 100644 --- a/src/librustc_mir_build/Cargo.toml +++ b/src/librustc_mir_build/Cargo.toml @@ -15,6 +15,7 @@ itertools = "0.8" log = "0.4" rustc = { path = "../librustc" } rustc_apfloat = { path = "../librustc_apfloat" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index fb3babca32b95..77bbce2d37aa9 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -18,8 +18,8 @@ use crate::hair::{self, *}; use rustc::mir::interpret::truncate; use rustc::ty; use rustc::ty::layout::{Integer, IntegerExt, Size}; +use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; -use syntax::attr::{SignedInt, UnsignedInt}; use std::mem; diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index fa5f266c76b14..1f536b63a394a 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -7,6 +7,7 @@ use rustc::middle::region; use rustc::mir::*; use rustc::ty::subst::Subst; use rustc::ty::{self, Ty, TyCtxt}; +use rustc_attr::{self as attr, UnwindAttr}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{GeneratorKind, HirIdMap, Node}; @@ -16,7 +17,6 @@ use rustc_span::Span; use rustc_target::spec::abi::Abi; use rustc_target::spec::PanicStrategy; use std::u32; -use syntax::attr::{self, UnwindAttr}; use super::lints; diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 08ed6b521b502..4f0e5bb45822b 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -245,8 +245,8 @@ use rustc::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar}; use rustc::mir::Field; use rustc::util::common::ErrorReported; +use rustc_attr::{SignedInt, UnsignedInt}; use rustc_span::{Span, DUMMY_SP}; -use syntax::attr::{SignedInt, UnsignedInt}; use arena::TypedArena; diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 2657050583071..bd8a9877719e4 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -1036,7 +1036,7 @@ crate fn compare_const_vals<'tcx>( } ty::Int(ity) => { use rustc::ty::layout::{Integer, IntegerExt}; - use syntax::attr::SignedInt; + use rustc_attr::SignedInt; let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); let a = sign_extend(a, size); let b = sign_extend(b, size); diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index 8071bc6312b36..6b0b6db8ed468 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -12,6 +12,7 @@ doctest = false [dependencies] bitflags = "1.0" log = "0.4" +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index da158e17f25e6..d97fe621174a4 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -9,6 +9,7 @@ //! [#64197]: https://github.com/rust-lang/rust/issues/64197 use crate::{parse_in, validate_attr}; +use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; use rustc_feature::{Feature, Features, State as FeatureState}; @@ -19,7 +20,6 @@ use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Attribute, MetaItem}; -use syntax::attr; use syntax::attr::HasAttrs; use syntax::mut_visit::*; use syntax::ptr::P; diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 338808f6d4a0f..981ef7f8796d3 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -11,6 +11,7 @@ path = "lib.rs" [dependencies] log = "0.4" rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index db8109c285980..4009cc6d725ab 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -10,6 +10,7 @@ use rustc::session::Session; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_attr::{self as attr, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -20,7 +21,6 @@ use rustc_hir::{Generics, HirId, Item, StructField, Variant}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast::Attribute; -use syntax::attr::{self, Stability}; use std::cmp::Ordering; use std::mem::replace; diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 4f341b545156c..2f7aaf9e5cfe1 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" [dependencies] rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } rustc_typeck = { path = "../librustc_typeck" } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 60bf271d2d2a8..74bb72d6fad7f 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -11,6 +11,7 @@ use rustc::ty::fold::TypeVisitor; use rustc::ty::query::Providers; use rustc::ty::subst::InternalSubsts; use rustc::ty::{self, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable}; +use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -22,7 +23,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use syntax::ast::Ident; -use syntax::attr; use std::marker::PhantomData; use std::{cmp, fmt, mem}; diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index c4cc6b09c736e..74f0d24749208 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" } arena = { path = "../libarena" } rustc = { path = "../librustc" } rustc_ast_lowering = { path = "../librustc_ast_lowering" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_expand = { path = "../librustc_expand" } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 7ff076268ab82..c77b588d7fbc3 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -20,6 +20,7 @@ use rustc::bug; use rustc::hir::exports::Export; use rustc::middle::cstore::CrateStore; use rustc::ty; +use rustc_attr as attr; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::SyntaxExtension; @@ -34,7 +35,6 @@ use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use syntax::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use syntax::ast::{Ident, Name}; -use syntax::attr; use syntax::token::{self, Token}; use syntax::visit::{self, Visitor}; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 85b5d8ef1cb5d..966638db493b3 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -10,6 +10,7 @@ use rustc::middle::stability; use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::{lint, span_bug, ty}; +use rustc_attr::{self as attr, StabilityLevel}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::SyntaxExtension; use rustc_expand::base::{self, Indeterminate, InvocationRes}; @@ -23,7 +24,6 @@ use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, Ident, NodeId}; -use syntax::attr::{self, StabilityLevel}; use syntax::print::pprust; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 4b27d86dd02a7..748bfcc79460a 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -14,6 +14,7 @@ doctest = false arena = { path = "../libarena" } log = "0.4" rustc = { path = "../librustc" } +rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4d1f92d19ce09..0a917a1853eb5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -115,6 +115,7 @@ use rustc::ty::{ self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, UserType, WithConstness, }; +use rustc_attr as attr; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; @@ -131,7 +132,6 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{self, BytePos, MultiSpan, Span}; use rustc_target::spec::abi::Abi; use syntax::ast; -use syntax::attr; use syntax::util::parser::ExprPrecedence; use std::cell::{Cell, Ref, RefCell, RefMut}; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 843872d0ff99a..4d812d2621c61 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -33,6 +33,7 @@ use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness}; use rustc::ty::{ReprOptions, ToPredicate}; +use rustc_attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, StashKey}; @@ -46,7 +47,6 @@ use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi; use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; -use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr}; struct OnlySelfBounds(bool); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 281306cc0c591..2a35ab812a5f2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -16,6 +16,7 @@ use rustc::middle::stability; use rustc::ty::fold::TypeFolder; use rustc::ty::subst::InternalSubsts; use rustc::ty::{self, AdtKind, Lift, Ty, TyCtxt}; +use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -27,7 +28,6 @@ use rustc_span::symbol::{kw, sym}; use rustc_span::{self, Pos}; use rustc_typeck::hir_ty_to_ty; use syntax::ast::{self, Ident}; -use syntax::attr; use std::collections::hash_map::Entry; use std::default::Default; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1c0e0b3bf410b..a8baa89c6f181 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,13 +15,13 @@ use rustc_lint; use rustc_resolve as resolve; use rustc_session::lint; +use rustc_attr as attr; use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::json::JsonEmitter; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use syntax::ast::CRATE_NODE_ID; -use syntax::attr; use rustc_data_structures::sync::{self, Lrc}; use std::cell::RefCell; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 403c8d0160d8a..27a6a52c02644 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -21,6 +21,7 @@ extern crate env_logger; extern crate getopts; extern crate rustc; +extern crate rustc_attr; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index a78fbe276faf1..e4d4017a34548 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -1,12 +1,5 @@ //! Functions dealing with attributes and meta items. -mod builtin; - -pub use builtin::*; -pub use IntType::*; -pub use ReprAttr::*; -pub use StabilityLevel::*; - use crate::ast; use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; use crate::ast::{Expr, GenericParam, Item, Lit, LitKind, Local, Stmt, StmtKind}; From 097d5e1c5edea1c0bf350b709087ddf5d60d2d9f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 15:03:15 +0100 Subject: [PATCH 0741/1253] 1. move node_id to syntax 2. invert rustc_session & syntax deps 3. drop rustc_session dep in rustc_hir --- Cargo.lock | 4 +-- src/librustc/hir/map/definitions.rs | 2 +- src/librustc/middle/stability.rs | 15 ++++++----- src/librustc/ty/context.rs | 27 +++++++++---------- src/librustc/ty/mod.rs | 5 ++-- src/librustc_ast_lowering/item.rs | 2 +- src/librustc_ast_lowering/lib.rs | 8 +++--- src/librustc_ast_passes/feature_gate.rs | 2 +- src/librustc_builtin_macros/cmdline_attrs.rs | 2 +- .../deriving/generic/mod.rs | 2 +- .../proc_macro_harness.rs | 2 +- .../standard_library_imports.rs | 2 +- src/librustc_builtin_macros/test_harness.rs | 2 +- src/librustc_expand/base.rs | 2 +- src/librustc_expand/expand.rs | 2 +- src/librustc_expand/mbe/macro_parser.rs | 2 +- src/librustc_expand/mbe/macro_rules.rs | 2 +- src/librustc_expand/mbe/quoted.rs | 2 +- src/librustc_expand/proc_macro_server.rs | 2 +- src/librustc_hir/Cargo.toml | 1 - src/librustc_hir/hir.rs | 9 ++++--- src/librustc_interface/interface.rs | 6 ++--- src/librustc_interface/util.rs | 3 ++- src/librustc_lint/levels.rs | 8 +++--- src/librustc_parse/config.rs | 2 +- src/librustc_parse/lexer/mod.rs | 2 +- src/librustc_parse/lib.rs | 9 +++---- src/librustc_parse/parser/mod.rs | 2 +- src/librustc_resolve/check_unused.rs | 2 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_session/Cargo.toml | 1 + src/librustc_session/lib.rs | 1 - src/librustc_session/lint.rs | 2 +- src/librustc_session/parse.rs | 3 +-- src/librustdoc/clean/cfg.rs | 2 +- src/librustdoc/html/highlight.rs | 2 +- .../passes/check_code_block_syntax.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libsyntax/Cargo.toml | 2 -- src/libsyntax/ast.rs | 12 +-------- src/libsyntax/lib.rs | 2 +- .../node_id.rs | 8 ++++++ 42 files changed, 83 insertions(+), 89 deletions(-) rename src/{librustc_session => libsyntax}/node_id.rs (74%) diff --git a/Cargo.lock b/Cargo.lock index 55f7a8357b705..6214b56004d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3606,7 +3606,6 @@ dependencies = [ "rustc_errors", "rustc_index", "rustc_macros", - "rustc_session", "rustc_span", "rustc_target", "serialize", @@ -3917,6 +3916,7 @@ dependencies = [ "rustc_span", "rustc_target", "serialize", + "syntax", ] [[package]] @@ -4513,11 +4513,9 @@ dependencies = [ "log", "rustc_data_structures", "rustc_errors", - "rustc_feature", "rustc_index", "rustc_lexer", "rustc_macros", - "rustc_session", "rustc_span", "scoped-tls", "serialize", diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index ac2d7a9a8dc2a..048c1f026be82 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -10,12 +10,12 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_index::vec::IndexVec; -use rustc_session::node_id::NodeMap; use rustc_session::CrateDisambiguator; use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast; +use syntax::node_id::NodeMap; use std::borrow::Borrow; use std::fmt::Write; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 752b0945e71cf..7cbe77b9e82f0 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -13,11 +13,12 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_hir::{self, HirId}; -use rustc_session::lint::{self, BuiltinLintDiagnostics, Lint, LintBuffer}; +use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; +use rustc_session::lint::{BuiltinLintDiagnostics, Lint, LintBuffer}; +use rustc_session::parse::feature_err_issue; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; -use syntax::sess::feature_err_issue; use std::num::NonZeroU32; @@ -97,7 +98,7 @@ pub fn report_unstable( issue: Option, is_soft: bool, span: Span, - soft_handler: impl FnOnce(&'static lint::Lint, Span, &str), + soft_handler: impl FnOnce(&'static Lint, Span, &str), ) { let msg = match reason { Some(r) => format!("use of unstable library feature '{}': {}", feature, r), @@ -119,7 +120,7 @@ pub fn report_unstable( let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); if fresh { if is_soft { - soft_handler(lint::builtin::SOFT_UNSTABLE, span, &msg) + soft_handler(SOFT_UNSTABLE, span, &msg) } else { feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg) .emit(); @@ -175,19 +176,19 @@ fn deprecation_message_common(message: String, reason: Option) -> String pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) { let message = format!("use of deprecated item '{}'", path); - (deprecation_message_common(message, depr.note), lint::builtin::DEPRECATED) + (deprecation_message_common(message, depr.note), DEPRECATED) } pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) { let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) { - (format!("use of deprecated item '{}'", path), lint::builtin::DEPRECATED) + (format!("use of deprecated item '{}'", path), DEPRECATED) } else { ( format!( "use of item '{}' that will be deprecated in future version {}", path, depr.since ), - lint::builtin::DEPRECATED_IN_FUTURE, + DEPRECATED_IN_FUTURE, ) }; (deprecation_message_common(message, Some(depr.reason)), lint) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 8d0b775656576..f12032943f91f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -41,16 +41,6 @@ use crate::ty::{ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, Pr use crate::ty::{InferConst, ParamConst}; use crate::ty::{List, TyKind, TyS}; use crate::util::common::ErrorReported; -use rustc_data_structures::sync; -use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRATE}; -use rustc_hir::{HirId, Node, TraitCandidate}; -use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; -use rustc_session::config::CrateType; -use rustc_session::config::{BorrowckMode, OutputFilenames}; -use rustc_session::Session; - use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; @@ -58,16 +48,27 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{ hash_stable_hashmap, HashStable, StableHasher, StableVec, }; -use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal}; +use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; use rustc_errors::DiagnosticBuilder; +use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRATE}; +use rustc_hir::{HirId, Node, TraitCandidate}; +use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; +use rustc_session::config::CrateType; +use rustc_session::config::{BorrowckMode, OutputFilenames}; use rustc_session::lint::{Level, Lint}; -use rustc_session::node_id::NodeMap; +use rustc_session::Session; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use rustc_target::spec::abi; +use syntax::ast; +use syntax::expand::allocator::AllocatorKind; +use syntax::node_id::NodeMap; + use smallvec::SmallVec; use std::any::Any; use std::borrow::Borrow; @@ -79,8 +80,6 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; -use syntax::ast; -use syntax::expand::allocator::AllocatorKind; type InternedSet<'tcx, T> = ShardedHashMap, ()>; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 24b22d3f6821c..f417b907a3811 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -39,11 +39,13 @@ use rustc_hir::{GlobMap, Node, TraitMap}; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_serialize::{self, Encodable, Encoder}; -use rustc_session::node_id::{NodeMap, NodeSet}; use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use rustc_target::abi::Align; +use syntax::ast::{self, Constness, Ident, Name}; +use syntax::node_id::{NodeId, NodeMap, NodeSet}; + use smallvec; use std::cell::RefCell; use std::cmp::{self, Ordering}; @@ -53,7 +55,6 @@ use std::ops::Deref; use std::ops::Range; use std::slice; use std::{mem, ptr}; -use syntax::ast::{self, Constness, Ident, Name, NodeId}; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 2025d0c1c8e34..e27f2bdb8d25f 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -7,13 +7,13 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_session::node_id::NodeMap; use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use rustc_target::spec::abi; use syntax::ast::*; use syntax::attr; +use syntax::node_id::NodeMap; use syntax::visit::{self, Visitor}; use log::debug; diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 284ede3b4fa1a..932ca743b02c6 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -49,8 +49,8 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::IndexVec; use rustc_session::config::nightly_options; -use rustc_session::lint::{builtin, BuiltinLintDiagnostics, LintBuffer}; -use rustc_session::node_id::NodeMap; +use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::parse::ParseSess; use rustc_session::Session; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind}; @@ -59,8 +59,8 @@ use rustc_span::Span; use syntax::ast; use syntax::ast::*; use syntax::attr; +use syntax::node_id::NodeMap; use syntax::print::pprust; -use syntax::sess::ParseSess; use syntax::token::{self, Nonterminal, Token}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::visit::{self, Visitor}; @@ -2621,7 +2621,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .unwrap_or(true); if !is_macro_callsite { self.resolver.lint_buffer().buffer_lint_with_diagnostic( - builtin::BARE_TRAIT_OBJECTS, + BARE_TRAIT_OBJECTS, id, span, "trait objects without an explicit `dyn` are deprecated", diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 953127429d5aa..3b13ab354fdf9 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -1,13 +1,13 @@ use rustc_errors::{struct_span_err, Handler}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Features, GateIssue, UnstableFeatures}; +use rustc_session::parse::{feature_err, feature_err_issue, ParseSess}; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; use syntax::attr; -use syntax::sess::{feature_err, feature_err_issue, ParseSess}; use syntax::visit::{self, FnKind, Visitor}; use log::debug; diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/src/librustc_builtin_macros/cmdline_attrs.rs index 2f7f7e73ac2ce..aa373d31e0609 100644 --- a/src/librustc_builtin_macros/cmdline_attrs.rs +++ b/src/librustc_builtin_macros/cmdline_attrs.rs @@ -1,10 +1,10 @@ //! Attributes injected into the crate root from command line using `-Z crate-attr`. use rustc_expand::panictry; +use rustc_session::parse::ParseSess; use rustc_span::FileName; use syntax::ast::{self, AttrItem, AttrStyle}; use syntax::attr::mk_attr; -use syntax::sess::ParseSess; use syntax::token; pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate { diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index d0208cb33a79e..364d8ff8e2262 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -183,13 +183,13 @@ use std::vec; use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; use syntax::ast::{GenericArg, GenericParamKind, VariantData}; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::util::map_in_place::MapInPlace; use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty}; diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index ae70608505130..75bd64895b0db 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -2,6 +2,7 @@ use std::mem; use rustc_expand::base::{ExtCtxt, Resolver}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; +use rustc_session::parse::ParseSess; use rustc_span::hygiene::AstPass; use rustc_span::symbol::{kw, sym}; use rustc_span::{Span, DUMMY_SP}; @@ -11,7 +12,6 @@ use syntax::attr; use syntax::expand::is_proc_macro_attr; use syntax::print::pprust; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::visit::{self, Visitor}; struct ProcMacroDerive { diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/src/librustc_builtin_macros/standard_library_imports.rs index 0c982b21eee2c..6663eecbf5f4b 100644 --- a/src/librustc_builtin_macros/standard_library_imports.rs +++ b/src/librustc_builtin_macros/standard_library_imports.rs @@ -1,11 +1,11 @@ use rustc_expand::base::{ExtCtxt, Resolver}; use rustc_expand::expand::ExpansionConfig; +use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::AstPass; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::{ast, attr}; pub fn inject( diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index 17d180da6bfda..6a73f121c99bf 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -4,6 +4,7 @@ use log::debug; use rustc_expand::base::{ExtCtxt, Resolver}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; +use rustc_session::parse::ParseSess; use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; use rustc_span::source_map::respan; use rustc_span::symbol::{sym, Symbol}; @@ -15,7 +16,6 @@ use syntax::attr; use syntax::entry::{self, EntryPointType}; use syntax::mut_visit::{ExpectOne, *}; use syntax::ptr::P; -use syntax::sess::ParseSess; use std::{iter, mem}; diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 52e5798ec194c..536259e054718 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -5,6 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_parse::{self, parser, DirectoryOwnership, MACRO_ARGUMENTS}; +use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind}; use rustc_span::source_map::SourceMap; @@ -14,7 +15,6 @@ use smallvec::{smallvec, SmallVec}; use syntax::ast::{self, Attribute, Name, NodeId, PatKind}; use syntax::mut_visit::{self, MutVisitor}; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::token; use syntax::tokenstream::{self, TokenStream}; use syntax::visit::Visitor; diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 35b6b96d49b39..9964818c36736 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -13,6 +13,7 @@ use rustc_parse::configure; use rustc_parse::parser::Parser; use rustc_parse::validate_attr; use rustc_parse::DirectoryOwnership; +use rustc_session::parse::{feature_err, ParseSess}; use rustc_span::source_map::respan; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{FileName, Span, DUMMY_SP}; @@ -21,7 +22,6 @@ use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use syntax::mut_visit::*; use syntax::print::pprust; use syntax::ptr::P; -use syntax::sess::{feature_err, ParseSess}; use syntax::token; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::util::map_in_place::MapInPlace; diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 6e7a4a556b80c..a7d7f811c56f8 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -78,11 +78,11 @@ use crate::mbe::{self, TokenTree}; use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; use rustc_parse::Directory; +use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{Ident, Name}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::token::{self, DocComment, Nonterminal, Token}; use syntax::tokenstream::TokenStream; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 3dbe8e7983c3d..34a0616eadbe6 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -15,13 +15,13 @@ use rustc_errors::{Applicability, DiagnosticBuilder, FatalError}; use rustc_feature::Features; use rustc_parse::parser::Parser; use rustc_parse::Directory; +use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast; use syntax::print::pprust; -use syntax::sess::ParseSess; use syntax::token::{self, NtTT, Token, TokenKind::*}; use syntax::tokenstream::{DelimSpan, TokenStream}; diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs index 4a33c51d57396..8cac1fa658e04 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/src/librustc_expand/mbe/quoted.rs @@ -1,10 +1,10 @@ use crate::mbe::macro_parser; use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree}; +use rustc_session::parse::ParseSess; use rustc_span::symbol::kw; use syntax::ast; use syntax::print::pprust; -use syntax::sess::ParseSess; use syntax::token::{self, Token}; use syntax::tokenstream; diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index d441613ac58f4..0a86754b23f04 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -4,11 +4,11 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::Diagnostic; use rustc_parse::lexer::nfc_normalize; use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str}; +use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; use syntax::ast; use syntax::print::pprust; -use syntax::sess::ParseSess; use syntax::token; use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; use syntax::util::comments; diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml index f2e420dbae640..02b394b6d7980 100644 --- a/src/librustc_hir/Cargo.toml +++ b/src/librustc_hir/Cargo.toml @@ -17,6 +17,5 @@ rustc_index = { path = "../librustc_index" } rustc_span = { path = "../librustc_span" } rustc_errors = { path = "../librustc_errors" } rustc_serialize = { path = "../libserialize", package = "serialize" } -rustc_session = { path = "../librustc_session" } syntax = { path = "../libsyntax" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index b62a7e413e303..0db75454aee38 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -12,21 +12,22 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_errors::FatalError; use rustc_macros::HashStable_Generic; -use rustc_session::node_id::NodeMap; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; -use smallvec::SmallVec; -use std::collections::{BTreeMap, BTreeSet}; -use std::fmt; use syntax::ast::{self, AsmDialect, CrateSugar, Ident, Name, NodeId}; use syntax::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy}; pub use syntax::ast::{BorrowKind, ImplPolarity, IsAuto}; pub use syntax::ast::{CaptureBy, Constness, Movability, Mutability, Unsafety}; +use syntax::node_id::NodeMap; use syntax::tokenstream::TokenStream; use syntax::util::parser::ExprPrecedence; +use smallvec::SmallVec; +use std::collections::{BTreeMap, BTreeSet}; +use std::fmt; + #[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable_Generic)] pub struct Lifetime { pub hir_id: HirId, diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index f491d662f971d..ae758b5e3273a 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -14,13 +14,13 @@ use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; use rustc_lint::LintStore; use rustc_parse::new_parser_from_source_str; +use rustc_session::parse::{CrateConfig, ParseSess}; use rustc_span::edition; use rustc_span::source_map::{FileLoader, FileName, SourceMap}; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; -use syntax::ast::{self, MetaItemKind}; -use syntax::sess::ParseSess; +use syntax::ast::MetaItemKind; use syntax::token; pub type Result = result::Result; @@ -106,7 +106,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option(); + .collect::(); cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect() }) } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 56121fba2d53a..842b702be2ab9 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -14,6 +14,7 @@ use rustc_resolve::{self, Resolver}; use rustc_session as session; use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::parse::CrateConfig; use rustc_session::CrateDisambiguator; use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session}; use rustc_span::edition::Edition; @@ -40,7 +41,7 @@ use syntax::{self, ast}; /// This is performed by checking whether a whitelisted set of /// features is available on the target machine, by querying LLVM. pub fn add_configuration( - cfg: &mut ast::CrateConfig, + cfg: &mut CrateConfig, sess: &Session, codegen_backend: &dyn CodegenBackend, ) { diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index d5bbdc53160f6..ae490a1c6ddc8 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -9,15 +9,15 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_hir::hir_id::HirId; -use rustc_hir::intravisit; +use rustc_hir::{intravisit, HirId}; use rustc_session::lint::{builtin, Level, Lint}; +use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::{sym, MultiSpan, Symbol}; +use rustc_span::source_map::MultiSpan; +use rustc_span::symbol::{sym, Symbol}; use syntax::ast; use syntax::attr; use syntax::print::pprust; -use syntax::sess::feature_err; use syntax::unwrap_or; use std::cmp; diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index d97fe621174a4..0edd56680f933 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -16,6 +16,7 @@ use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, }; +use rustc_session::parse::{feature_err, ParseSess}; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -23,7 +24,6 @@ use syntax::ast::{self, AttrItem, Attribute, MetaItem}; use syntax::attr::HasAttrs; use syntax::mut_visit::*; use syntax::ptr::P; -use syntax::sess::{feature_err, ParseSess}; use syntax::util::map_in_place::MapInPlace; use smallvec::SmallVec; diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index 02e4808679f00..af56e9d344d2e 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -2,9 +2,9 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{DiagnosticBuilder, FatalError}; use rustc_lexer::unescape; use rustc_lexer::Base; +use rustc_session::parse::ParseSess; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Pos, Span}; -use syntax::sess::ParseSess; use syntax::token::{self, Token, TokenKind}; use syntax::util::comments; diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 08f4f210152dd..d25557855427d 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -4,16 +4,15 @@ #![feature(crate_visibility_modifier)] #![cfg_attr(bootstrap, feature(slice_patterns))] +use rustc_data_structures::sync::Lrc; +use rustc_errors::{Diagnostic, FatalError, Level, PResult}; +use rustc_session::parse::ParseSess; +use rustc_span::{FileName, SourceFile, Span}; use syntax::ast; use syntax::print::pprust; -use syntax::sess::ParseSess; use syntax::token::{self, Nonterminal}; use syntax::tokenstream::{self, TokenStream, TokenTree}; -use rustc_data_structures::sync::Lrc; -use rustc_errors::{Diagnostic, FatalError, Level, PResult}; -use rustc_span::{FileName, SourceFile, Span}; - use std::borrow::Cow; use std::path::Path; use std::str; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 4a9016394d258..4c7b37ff7e1f1 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -17,6 +17,7 @@ use crate::{Directory, DirectoryOwnership}; use log::debug; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult}; +use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; @@ -24,7 +25,6 @@ use syntax::ast::{self, AttrStyle, AttrVec, CrateSugar, Extern, Ident, Unsafety, use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::token::{self, DelimToken, Token, TokenKind}; use syntax::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use syntax::util::comments::{doc_comment_style, strip_doc_comment_decoration}; diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 4a6df92d82260..e8e3b68579488 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -30,9 +30,9 @@ use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; use rustc_session::lint::BuiltinLintDiagnostics; -use rustc_session::node_id::NodeMap; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use syntax::ast; +use syntax::node_id::NodeMap; use syntax::visit::{self, Visitor}; struct UnusedImport<'a> { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0b1752419b889..55d1be70ad71e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -37,7 +37,6 @@ use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::{GlobMap, TraitMap}; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; -use rustc_session::node_id::{NodeMap, NodeSet}; use rustc_session::Session; use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency}; use rustc_span::source_map::Spanned; @@ -47,6 +46,7 @@ use syntax::ast::{self, FloatTy, Ident, IntTy, Name, NodeId, UintTy}; use syntax::ast::{Crate, CRATE_NODE_ID}; use syntax::ast::{ItemKind, Path}; use syntax::attr; +use syntax::node_id::{NodeMap, NodeSet}; use syntax::print::pprust; use syntax::unwrap_or; use syntax::visit::{self, Visitor}; diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml index 47c23bc4dcf98..c74011e26aae8 100644 --- a/src/librustc_session/Cargo.toml +++ b/src/librustc_session/Cargo.toml @@ -19,3 +19,4 @@ rustc_span = { path = "../librustc_span" } rustc_index = { path = "../librustc_index" } rustc_fs_util = { path = "../librustc_fs_util" } num_cpus = "1.0" +syntax = { path = "../libsyntax" } diff --git a/src/librustc_session/lib.rs b/src/librustc_session/lib.rs index 65d6635adad00..4101c32d547aa 100644 --- a/src/librustc_session/lib.rs +++ b/src/librustc_session/lib.rs @@ -10,7 +10,6 @@ pub mod cgu_reuse_tracker; pub mod utils; #[macro_use] pub mod lint; -pub mod node_id; pub mod parse; mod code_stats; diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 2ba3932c7d97e..983dfb19919dd 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -1,8 +1,8 @@ pub use self::Level::*; -use crate::node_id::{NodeId, NodeMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_span::edition::Edition; use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol}; +use syntax::node_id::{NodeId, NodeMap}; pub mod builtin; diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 72c68fcb244c9..3264230026295 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -2,8 +2,6 @@ //! It also serves as an input to the parser itself. use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId}; -use crate::node_id::NodeId; - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc, Once}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; @@ -13,6 +11,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{MultiSpan, Span, Symbol}; +use syntax::node_id::NodeId; use std::path::PathBuf; use std::str; diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 84e6ff648a38f..da3a277dc2ac6 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -8,9 +8,9 @@ use std::mem; use std::ops; use rustc_feature::Features; +use rustc_session::parse::ParseSess; use rustc_span::symbol::{sym, Symbol}; use syntax::ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem}; -use syntax::sess::ParseSess; use rustc_span::Span; diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 2a603d9900fb9..1ea053605ec1e 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -12,10 +12,10 @@ use std::io; use std::io::prelude::*; use rustc_parse::lexer; +use rustc_session::parse::ParseSess; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym}; use rustc_span::{FileName, Span}; -use syntax::sess::ParseSess; use syntax::token::{self, Token}; /// Highlights `src`, returning the HTML output. diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 2903fd9dcd660..3b7c0db05a5e2 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -1,9 +1,9 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler}; use rustc_parse::lexer::StringReader as Lexer; +use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileName, InnerSpan}; -use syntax::sess::ParseSess; use syntax::token; use crate::clean; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index ba36e06fd37f2..381308ac6be1c 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -395,8 +395,8 @@ pub fn make_test( use rustc_errors::emitter::EmitterWriter; use rustc_errors::Handler; use rustc_parse::maybe_new_parser_from_source_str; + use rustc_session::parse::ParseSess; use rustc_span::source_map::FilePathMapping; - use syntax::sess::ParseSess; let filename = FileName::anon_source_code(s); let source = crates + &everything_else; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 2e647d2a1e081..b3e16f740fdb6 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -16,9 +16,7 @@ scoped-tls = "1.0" rustc_errors = { path = "../librustc_errors" } rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_feature = { path = "../librustc_feature" } rustc_index = { path = "../librustc_index" } rustc_lexer = { path = "../librustc_lexer" } rustc_macros = { path = "../librustc_macros" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_session = { path = "../librustc_session" } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index db4fd53fe1697..49f559de1b123 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -256,15 +256,7 @@ impl ParenthesizedArgs { } } -pub use rustc_session::node_id::NodeId; - -/// `NodeId` used to represent the root of the crate. -pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0); - -/// When parsing and doing expansions, we initially give all AST nodes this AST -/// node value. Then later, in the renumber pass, we renumber them to have -/// small, positive ids. -pub const DUMMY_NODE_ID: NodeId = NodeId::MAX; +pub use crate::node_id::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; /// A modifier on a bound, e.g., `?Sized` or `?const Trait`. /// @@ -432,8 +424,6 @@ pub struct WhereEqPredicate { pub rhs_ty: P, } -pub use rustc_session::parse::CrateConfig; - #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub module: Mod, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 9fcc7a1dfa899..a0b2d50cef3f6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -41,8 +41,8 @@ pub mod attr; pub mod entry; pub mod expand; pub mod mut_visit; +pub mod node_id; pub mod ptr; -pub use rustc_session::parse as sess; pub mod token; pub mod tokenstream; pub mod visit; diff --git a/src/librustc_session/node_id.rs b/src/libsyntax/node_id.rs similarity index 74% rename from src/librustc_session/node_id.rs rename to src/libsyntax/node_id.rs index 9fefe908e578e..58d2334a7b148 100644 --- a/src/librustc_session/node_id.rs +++ b/src/libsyntax/node_id.rs @@ -11,6 +11,14 @@ rustc_index::newtype_index! { rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeId); +/// `NodeId` used to represent the root of the crate. +pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0); + +/// When parsing and doing expansions, we initially give all AST nodes this AST +/// node value. Then later, in the renumber pass, we renumber them to have +/// small, positive ids. +pub const DUMMY_NODE_ID: NodeId = NodeId::MAX; + impl NodeId { pub fn placeholder_from_expn_id(expn_id: ExpnId) -> Self { NodeId::from_u32(expn_id.as_u32()) From 98fd6a5c88a44214f15a43a9e633e3b71876bdb3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 16:21:30 +0100 Subject: [PATCH 0742/1253] 1. move allow_internal_unstable to rustc_attr 2. as a result, drop rustc_errors dep from syntax --- Cargo.lock | 1 - src/librustc_attr/builtin.rs | 20 +++++++++++++++- .../transform/qualify_min_const_fn.rs | 3 ++- src/libsyntax/Cargo.toml | 1 - src/libsyntax/attr/mod.rs | 24 ------------------- 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6214b56004d46..b6e9738f10ec4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4512,7 +4512,6 @@ version = "0.0.0" dependencies = [ "log", "rustc_data_structures", - "rustc_errors", "rustc_index", "rustc_lexer", "rustc_macros", diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs index f13f19073ea3c..c944537048fa2 100644 --- a/src/librustc_attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -1,6 +1,6 @@ //! Parsing and validation of builtin attributes -use super::mark_used; +use super::{find_by_name, mark_used}; use rustc_errors::{struct_span_err, Applicability, Handler}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; @@ -1043,3 +1043,21 @@ pub fn find_transparency( let fallback = if is_legacy { Transparency::SemiTransparent } else { Transparency::Opaque }; (transparency.map_or(fallback, |t| t.0), error) } + +pub fn allow_internal_unstable<'a>( + attrs: &[Attribute], + diag: &'a rustc_errors::Handler, +) -> Option + 'a> { + let attr = find_by_name(attrs, sym::allow_internal_unstable)?; + let list = attr.meta_item_list().or_else(|| { + diag.span_err(attr.span, "allow_internal_unstable expects list of feature names"); + None + })?; + Some(list.into_iter().filter_map(move |it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + diag.span_err(it.span(), "`allow_internal_unstable` expects feature names"); + } + name + })) +} diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 49921badf33d9..6a68ccdddffdc 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -1,11 +1,12 @@ use rustc::mir::*; use rustc::ty::{self, adjustment::PointerCast, Predicate, Ty, TyCtxt}; +use rustc_attr as attr; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use std::borrow::Cow; -use syntax::{ast, attr}; +use syntax::ast; type McfResult = Result<(), (Span, Cow<'static, str>)>; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index b3e16f740fdb6..ff03ae3f425c4 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -13,7 +13,6 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" scoped-tls = "1.0" -rustc_errors = { path = "../librustc_errors" } rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index e4d4017a34548..313f526923564 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -406,30 +406,6 @@ pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { attrs.iter().find(|attr| attr.check_name(name)) } -pub fn allow_internal_unstable<'a>( - attrs: &[Attribute], - span_diagnostic: &'a rustc_errors::Handler, -) -> Option + 'a> { - find_by_name(attrs, sym::allow_internal_unstable).and_then(|attr| { - attr.meta_item_list() - .or_else(|| { - span_diagnostic - .span_err(attr.span, "allow_internal_unstable expects list of feature names"); - None - }) - .map(|features| { - features.into_iter().filter_map(move |it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - span_diagnostic - .span_err(it.span(), "`allow_internal_unstable` expects feature names") - } - name - }) - }) - }) -} - pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { attrs.iter().filter(move |attr| attr.check_name(name)) } From e233331a519408edf60ac1c7dee4a9cefe8c8756 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 17:02:46 +0100 Subject: [PATCH 0743/1253] syntax::print -> new crate rustc_ast_pretty --- Cargo.lock | 24 +++++++++++++++++++ src/librustc/Cargo.toml | 2 ++ src/librustc_ast_lowering/Cargo.toml | 1 + src/librustc_ast_lowering/lib.rs | 2 +- src/librustc_ast_passes/Cargo.toml | 1 + src/librustc_ast_passes/ast_validation.rs | 2 +- src/librustc_ast_pretty/Cargo.toml | 16 +++++++++++++ .../print => librustc_ast_pretty}/helpers.rs | 2 +- src/librustc_ast_pretty/lib.rs | 6 +++++ .../print => librustc_ast_pretty}/pp.rs | 0 .../print => librustc_ast_pretty}/pprust.rs | 23 +++++++++--------- .../pprust/tests.rs | 4 ++-- src/librustc_attr/Cargo.toml | 1 + src/librustc_attr/builtin.rs | 2 +- src/librustc_builtin_macros/Cargo.toml | 1 + src/librustc_builtin_macros/assert.rs | 2 +- src/librustc_builtin_macros/log_syntax.rs | 4 ++-- .../proc_macro_harness.rs | 2 +- src/librustc_builtin_macros/source_util.rs | 2 +- src/librustc_builtin_macros/test.rs | 2 +- src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/pretty.rs | 3 +-- src/librustc_expand/Cargo.toml | 1 + src/librustc_expand/expand.rs | 2 +- src/librustc_expand/mbe/macro_parser.rs | 2 +- src/librustc_expand/mbe/macro_rules.rs | 2 +- src/librustc_expand/mbe/quoted.rs | 2 +- src/librustc_expand/proc_macro_server.rs | 2 +- src/librustc_hir/Cargo.toml | 1 + src/librustc_hir/print.rs | 6 ++--- src/librustc_lint/Cargo.toml | 1 + src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/levels.rs | 5 ++-- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/Cargo.toml | 1 + src/librustc_metadata/rmeta/encoder.rs | 2 +- src/librustc_mir/Cargo.toml | 1 + src/librustc_mir/dataflow/mod.rs | 2 +- src/librustc_parse/Cargo.toml | 1 + src/librustc_parse/lexer/tokentrees.rs | 2 +- src/librustc_parse/lib.rs | 2 +- src/librustc_parse/parser/attr.rs | 2 +- src/librustc_parse/parser/diagnostics.rs | 2 +- src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/item.rs | 2 +- src/librustc_parse/parser/mod.rs | 2 +- src/librustc_parse/parser/pat.rs | 2 +- src/librustc_resolve/Cargo.toml | 1 + src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_save_analysis/Cargo.toml | 1 + src/librustc_save_analysis/dump_visitor.rs | 9 ++++--- src/librustc_save_analysis/lib.rs | 14 +++++------ src/librustc_save_analysis/sig.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/lib.rs | 1 + src/librustdoc/test.rs | 2 +- src/libsyntax/ast.rs | 4 ++-- src/libsyntax/lib.rs | 6 ----- src/libsyntax/util/comments.rs | 6 ++--- src/libsyntax/util/parser.rs | 2 +- 62 files changed, 129 insertions(+), 81 deletions(-) create mode 100644 src/librustc_ast_pretty/Cargo.toml rename src/{libsyntax/print => librustc_ast_pretty}/helpers.rs (95%) create mode 100644 src/librustc_ast_pretty/lib.rs rename src/{libsyntax/print => librustc_ast_pretty}/pp.rs (100%) rename src/{libsyntax/print => librustc_ast_pretty}/pprust.rs (99%) rename src/{libsyntax/print => librustc_ast_pretty}/pprust/tests.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index b6e9738f10ec4..62fbba7a77041 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3093,6 +3093,7 @@ dependencies = [ "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3359,6 +3360,7 @@ version = "0.0.0" dependencies = [ "log", "rustc", + "rustc_ast_pretty", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -3375,6 +3377,7 @@ name = "rustc_ast_passes" version = "0.0.0" dependencies = [ "log", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3385,10 +3388,21 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_ast_pretty" +version = "0.0.0" +dependencies = [ + "log", + "rustc_data_structures", + "rustc_span", + "syntax", +] + [[package]] name = "rustc_attr" version = "0.0.0" dependencies = [ + "rustc_ast_pretty", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3406,6 +3420,7 @@ version = "0.0.0" dependencies = [ "fmt_macros", "log", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3526,6 +3541,7 @@ dependencies = [ "lazy_static 1.4.0", "log", "rustc", + "rustc_ast_pretty", "rustc_codegen_utils", "rustc_data_structures", "rustc_error_codes", @@ -3572,6 +3588,7 @@ version = "0.0.0" dependencies = [ "log", "rustc_ast_passes", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3602,6 +3619,7 @@ version = "0.0.0" name = "rustc_hir" version = "0.0.0" dependencies = [ + "rustc_ast_pretty", "rustc_data_structures", "rustc_errors", "rustc_index", @@ -3693,6 +3711,7 @@ version = "0.0.0" dependencies = [ "log", "rustc", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3734,6 +3753,7 @@ dependencies = [ "log", "memmap", "rustc", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3762,6 +3782,7 @@ dependencies = [ "polonius-engine", "rustc", "rustc_apfloat", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3805,6 +3826,7 @@ version = "0.0.0" dependencies = [ "bitflags", "log", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3872,6 +3894,7 @@ dependencies = [ "log", "rustc", "rustc_ast_lowering", + "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -3893,6 +3916,7 @@ dependencies = [ "rls-data", "rls-span", "rustc", + "rustc_ast_pretty", "rustc_codegen_utils", "rustc_data_structures", "rustc_hir", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 782c6879ac58f..7df5185d27c40 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -21,6 +21,8 @@ rustc-rayon = "0.3.0" rustc-rayon-core = "0.3.0" polonius-engine = "0.11.0" rustc_apfloat = { path = "../librustc_apfloat" } +# FIXME(Centril): remove this dependency when stuff is moved to rustc_lint. +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml index 4b786d6245fc4..f6ab60e199f33 100644 --- a/src/librustc_ast_lowering/Cargo.toml +++ b/src/librustc_ast_lowering/Cargo.toml @@ -12,6 +12,7 @@ doctest = false [dependencies] log = { version = "0.4", features = ["release_max_level_info", "std"] } rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 932ca743b02c6..c3e96a31e4001 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -38,6 +38,7 @@ use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; use rustc::{bug, span_bug}; +use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; @@ -60,7 +61,6 @@ use syntax::ast; use syntax::ast::*; use syntax::attr; use syntax::node_id::NodeMap; -use syntax::print::pprust; use syntax::token::{self, Nonterminal, Token}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::visit::{self, Visitor}; diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index 2b25f04ce9aca..01d2ac449b590 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" [dependencies] log = "0.4" +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index c6ea97be583ba..4bb55d6acddcd 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -6,6 +6,7 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; @@ -19,7 +20,6 @@ use std::mem; use syntax::ast::*; use syntax::attr; use syntax::expand::is_proc_macro_attr; -use syntax::print::pprust; use syntax::visit::{self, Visitor}; use syntax::walk_list; diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml new file mode 100644 index 0000000000000..2f7f804b62887 --- /dev/null +++ b/src/librustc_ast_pretty/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_pretty" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_ast_pretty" +path = "lib.rs" +doctest = false + +[dependencies] +log = "0.4" +rustc_span = { path = "../librustc_span" } +rustc_data_structures = { path = "../librustc_data_structures" } +syntax = { path = "../libsyntax" } diff --git a/src/libsyntax/print/helpers.rs b/src/librustc_ast_pretty/helpers.rs similarity index 95% rename from src/libsyntax/print/helpers.rs rename to src/librustc_ast_pretty/helpers.rs index 88942cb7fd60f..dce856df9c66a 100644 --- a/src/libsyntax/print/helpers.rs +++ b/src/librustc_ast_pretty/helpers.rs @@ -1,4 +1,4 @@ -use crate::print::pp::Printer; +use crate::pp::Printer; use std::borrow::Cow; impl Printer { diff --git a/src/librustc_ast_pretty/lib.rs b/src/librustc_ast_pretty/lib.rs new file mode 100644 index 0000000000000..4c3a836e17ccf --- /dev/null +++ b/src/librustc_ast_pretty/lib.rs @@ -0,0 +1,6 @@ +#![feature(bool_to_option)] +#![feature(crate_visibility_modifier)] + +mod helpers; +pub mod pp; +pub mod pprust; diff --git a/src/libsyntax/print/pp.rs b/src/librustc_ast_pretty/pp.rs similarity index 100% rename from src/libsyntax/print/pp.rs rename to src/librustc_ast_pretty/pp.rs diff --git a/src/libsyntax/print/pprust.rs b/src/librustc_ast_pretty/pprust.rs similarity index 99% rename from src/libsyntax/print/pprust.rs rename to src/librustc_ast_pretty/pprust.rs index 624d1c70c158d..2257710147abf 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1,21 +1,20 @@ -use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; -use crate::ast::{Attribute, GenericArg, MacArgs}; -use crate::ast::{GenericBound, SelfKind, TraitBoundModifier}; -use crate::attr; -use crate::print::pp::Breaks::{Consistent, Inconsistent}; -use crate::print::pp::{self, Breaks}; -use crate::ptr::P; -use crate::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind}; -use crate::tokenstream::{self, TokenStream, TokenTree}; -use crate::util::classify; -use crate::util::comments; -use crate::util::parser::{self, AssocOp, Fixity}; +use crate::pp::Breaks::{Consistent, Inconsistent}; +use crate::pp::{self, Breaks}; use rustc_data_structures::sync::Once; use rustc_span::edition::Edition; use rustc_span::source_map::{dummy_spanned, SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, Span}; +use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; +use syntax::ast::{Attribute, GenericArg, MacArgs}; +use syntax::ast::{GenericBound, SelfKind, TraitBoundModifier}; +use syntax::attr; +use syntax::ptr::P; +use syntax::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind}; +use syntax::tokenstream::{self, TokenStream, TokenTree}; +use syntax::util::parser::{self, AssocOp, Fixity}; +use syntax::util::{classify, comments}; use std::borrow::Cow; diff --git a/src/libsyntax/print/pprust/tests.rs b/src/librustc_ast_pretty/pprust/tests.rs similarity index 96% rename from src/libsyntax/print/pprust/tests.rs rename to src/librustc_ast_pretty/pprust/tests.rs index 3091e3155805b..ec6f5096d91af 100644 --- a/src/libsyntax/print/pprust/tests.rs +++ b/src/librustc_ast_pretty/pprust/tests.rs @@ -1,9 +1,9 @@ use super::*; -use crate::ast; -use crate::with_default_globals; use rustc_span; use rustc_span::source_map::{dummy_spanned, respan}; +use syntax::ast; +use syntax::attr::with_default_globals; fn fun_to_string( decl: &ast::FnDecl, diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml index acb93e1d64070..83a5f41989b6c 100644 --- a/src/librustc_attr/Cargo.toml +++ b/src/librustc_attr/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" doctest = false [dependencies] +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_errors = { path = "../librustc_errors" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs index c944537048fa2..be7c164395b0a 100644 --- a/src/librustc_attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -2,6 +2,7 @@ use super::{find_by_name, mark_used}; +use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, Handler}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; @@ -10,7 +11,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; use syntax::ast::{self, Attribute, MetaItem, MetaItemKind, NestedMetaItem}; -use syntax::print::pprust; pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index d0558a50acf64..b424ce432148f 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -12,6 +12,7 @@ doctest = false [dependencies] fmt_macros = { path = "../libfmt_macros" } log = "0.4" +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs index a992b6e2662d2..3fc86a5469c2f 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/src/librustc_builtin_macros/assert.rs @@ -1,11 +1,11 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; +use rustc_ast_pretty::pprust; use rustc_expand::base::*; use rustc_parse::parser::Parser; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, *}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, TokenKind}; use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree}; diff --git a/src/librustc_builtin_macros/log_syntax.rs b/src/librustc_builtin_macros/log_syntax.rs index 7c7fc286e0a5e..6d9bfbfd05f0a 100644 --- a/src/librustc_builtin_macros/log_syntax.rs +++ b/src/librustc_builtin_macros/log_syntax.rs @@ -1,6 +1,6 @@ +use rustc_ast_pretty::pprust; use rustc_expand::base; use rustc_span; -use syntax::print; use syntax::tokenstream::TokenStream; pub fn expand_log_syntax<'cx>( @@ -8,7 +8,7 @@ pub fn expand_log_syntax<'cx>( sp: rustc_span::Span, tts: TokenStream, ) -> Box { - println!("{}", print::pprust::tts_to_string(tts)); + println!("{}", pprust::tts_to_string(tts)); // any so that `log_syntax` can be invoked as an expression and item. base::DummyResult::any_valid(sp) diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index 75bd64895b0db..222456d8fe0d9 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -1,5 +1,6 @@ use std::mem; +use rustc_ast_pretty::pprust; use rustc_expand::base::{ExtCtxt, Resolver}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_session::parse::ParseSess; @@ -10,7 +11,6 @@ use smallvec::smallvec; use syntax::ast::{self, Ident}; use syntax::attr; use syntax::expand::is_proc_macro_attr; -use syntax::print::pprust; use syntax::ptr::P; use syntax::visit::{self, Visitor}; diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs index dc85a92d272c4..264223bafbcf9 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/src/librustc_builtin_macros/source_util.rs @@ -1,3 +1,4 @@ +use rustc_ast_pretty::pprust; use rustc_expand::base::{self, *}; use rustc_expand::panictry; use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership}; @@ -5,7 +6,6 @@ use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_span::symbol::Symbol; use rustc_span::{self, Pos, Span}; use syntax::ast; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 07715cdbcb5e9..2d6ff81aea8b8 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -2,13 +2,13 @@ /// Ideally, this code would be in libtest but for efficiency and error messages it lives here. use crate::util::check_builtin_macro_attribute; +use rustc_ast_pretty::pprust; use rustc_expand::base::*; use rustc_span::source_map::respan; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use syntax::ast; use syntax::attr; -use syntax::print::pprust; use std::iter; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index b856e5da5a093..7a5966269b301 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -14,6 +14,7 @@ lazy_static = "1.0" log = "0.4" env_logger = { version = "0.7", default-features = false } rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_target = { path = "../librustc_target" } rustc_lint = { path = "../librustc_lint" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 5cd9e9a4a5848..65dbc59ea55b0 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -5,14 +5,13 @@ use rustc::session::config::{Input, PpMode, PpSourceMode}; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; +use rustc_ast_pretty::pprust; use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::print as pprust_hir; use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; - use rustc_span::FileName; use syntax::ast; -use syntax::print::pprust; use std::cell::Cell; use std::fs::File; diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index 1310e7fbd095f..cb7919d630ad4 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -14,6 +14,7 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" rustc_span = { path = "../librustc_span" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_ast_passes = { path = "../librustc_ast_passes" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 9964818c36736..f08bed5731530 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -5,6 +5,7 @@ use crate::mbe::macro_rules::annotate_err_with_kind; use crate::placeholders::{placeholder, PlaceholderExpander}; use crate::proc_macro::collect_derives; +use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, FatalError, PResult}; @@ -20,7 +21,6 @@ use rustc_span::{FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path}; use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use syntax::mut_visit::*; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::{TokenStream, TokenTree}; diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index a7d7f811c56f8..b14725fd731b1 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -76,12 +76,12 @@ use TokenTreeOrTokenTreeSlice::*; use crate::mbe::{self, TokenTree}; +use rustc_ast_pretty::pprust; use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; use rustc_parse::Directory; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{Ident, Name}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, DocComment, Nonterminal, Token}; use syntax::tokenstream::TokenStream; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 34a0616eadbe6..29d41543fbf8c 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -8,6 +8,7 @@ use crate::mbe::macro_parser::{Error, Failure, Success}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; use crate::mbe::transcribe::transcribe; +use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; @@ -21,7 +22,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast; -use syntax::print::pprust; use syntax::token::{self, NtTT, Token, TokenKind::*}; use syntax::tokenstream::{DelimSpan, TokenStream}; diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs index 8cac1fa658e04..9ae8ead1a724d 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/src/librustc_expand/mbe/quoted.rs @@ -1,10 +1,10 @@ use crate::mbe::macro_parser; use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree}; +use rustc_ast_pretty::pprust; use rustc_session::parse::ParseSess; use rustc_span::symbol::kw; use syntax::ast; -use syntax::print::pprust; use syntax::token::{self, Token}; use syntax::tokenstream; diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 0a86754b23f04..a7397e576b18c 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -1,5 +1,6 @@ use crate::base::ExtCtxt; +use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::Diagnostic; use rustc_parse::lexer::nfc_normalize; @@ -8,7 +9,6 @@ use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; use syntax::ast; -use syntax::print::pprust; use syntax::token; use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; use syntax::util::comments; diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml index 02b394b6d7980..3ae943a4ce08b 100644 --- a/src/librustc_hir/Cargo.toml +++ b/src/librustc_hir/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" doctest = false [dependencies] +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 7beabacecc292..b0d2f96c71a03 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -1,11 +1,11 @@ +use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; +use rustc_ast_pretty::pp::{self, Breaks}; +use rustc_ast_pretty::pprust::{self, Comments, PrintState}; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::kw; use rustc_span::{self, BytePos, FileName}; use rustc_target::spec::abi::Abi; use syntax::ast; -use syntax::print::pp::Breaks::{Consistent, Inconsistent}; -use syntax::print::pp::{self, Breaks}; -use syntax::print::pprust::{self, Comments, PrintState}; use syntax::util::parser::{self, AssocOp, Fixity}; use crate::hir; diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index d32622c09c623..27df0f904e48a 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" log = "0.4" unicode-security = "0.0.2" rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c8d3d5f9c83d8..345665de63c3c 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -25,6 +25,7 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext} use rustc::hir::map::Map; use rustc::traits::misc::can_type_implement_copy; use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt}; +use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::Stability; @@ -41,7 +42,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, Span}; use syntax::ast::{self, Expr}; use syntax::attr::{self, HasAttrs}; -use syntax::print::pprust::{self, expr_to_string}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::visit::FnKind; diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index ae490a1c6ddc8..4f30d2b222684 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,10 +1,10 @@ use crate::context::{CheckLintNameResult, LintStore}; use crate::late::unerased_lint_store; use rustc::hir::map::Map; -use rustc::lint::struct_lint_level; -use rustc::lint::{LintLevelMap, LintLevelSets, LintSet, LintSource}; +use rustc::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -17,7 +17,6 @@ use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{sym, Symbol}; use syntax::ast; use syntax::attr; -use syntax::print::pprust; use syntax::unwrap_or; use std::cmp; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index bb2c4fa1aaff6..272c4f29203d8 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,6 +1,7 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc::ty::adjustment; use rustc::ty::{self, Ty}; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, Applicability}; use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; @@ -13,7 +14,6 @@ use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; use syntax::ast; use syntax::attr; -use syntax::print::pprust; use syntax::util::parser; use log::debug; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index a74f886043b6a..a4fdcee5e1297 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -15,6 +15,7 @@ log = "0.4" memmap = "0.7" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 9d2bea28c8c2e..54fbdb14010c9 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1236,7 +1236,7 @@ impl EncodeContext<'tcx> { /// Serialize the text of exported macros fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) { - use syntax::print::pprust; + use rustc_ast_pretty::pprust; let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); record!(self.per_def.kind[def_id] <- EntryKind::MacroDef(self.lazy(MacroDef { body: pprust::tts_to_string(macro_def.body.clone()), diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index eead88dcb0c30..6b2e2bb919c13 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -17,6 +17,7 @@ log = "0.4" log_settings = "0.1.1" polonius-engine = "0.11.0" rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index e29730f267c2c..7cd7fc309b6b9 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -1,6 +1,6 @@ +use rustc_ast_pretty::pprust; use rustc_span::symbol::{sym, Symbol}; use syntax::ast::{self, MetaItem}; -use syntax::print::pprust; use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::{BitSet, HybridBitSet}; diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index 6b0b6db8ed468..176bb58ad27e6 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -12,6 +12,7 @@ doctest = false [dependencies] bitflags = "1.0" log = "0.4" +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_parse/lexer/tokentrees.rs b/src/librustc_parse/lexer/tokentrees.rs index a28bff3babfbf..c28b59a790801 100644 --- a/src/librustc_parse/lexer/tokentrees.rs +++ b/src/librustc_parse/lexer/tokentrees.rs @@ -1,9 +1,9 @@ use super::{StringReader, UnmatchedBrace}; +use rustc_ast_pretty::pprust::token_to_string; use rustc_data_structures::fx::FxHashMap; use rustc_errors::PResult; use rustc_span::Span; -use syntax::print::pprust::token_to_string; use syntax::token::{self, Token}; use syntax::tokenstream::{ DelimSpan, diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index d25557855427d..bf0f8ff0064d5 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -4,12 +4,12 @@ #![feature(crate_visibility_modifier)] #![cfg_attr(bootstrap, feature(slice_patterns))] +use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, FatalError, Level, PResult}; use rustc_session::parse::ParseSess; use rustc_span::{FileName, SourceFile, Span}; use syntax::ast; -use syntax::print::pprust; use syntax::token::{self, Nonterminal}; use syntax::tokenstream::{self, TokenStream, TokenTree}; diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 1869389dbd9e6..e58eb9ffc51e7 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,9 +1,9 @@ use super::{Parser, PathStyle, TokenType}; +use rustc_ast_pretty::pprust; use rustc_errors::PResult; use rustc_span::{Span, Symbol}; use syntax::ast; use syntax::attr; -use syntax::print::pprust; use syntax::token::{self, Nonterminal}; use syntax::util::comments; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 80bc5c158a64f..e2227f669738c 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,5 +1,6 @@ use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType}; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err}; use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult}; @@ -10,7 +11,6 @@ use syntax::ast::{ self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, Param, }; use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, token_can_begin_expr, TokenKind}; use syntax::util::parser::AssocOp; diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 098c8355ab944..0d12f8cf6c039 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -3,6 +3,7 @@ use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; +use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::{self, Span, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -12,7 +13,6 @@ use syntax::ast::{ AnonConst, BinOp, BinOpKind, FnDecl, FunctionRetTy, Mac, Param, Ty, TyKind, UnOp, }; use syntax::ast::{Arm, BlockCheckMode, Expr, ExprKind, IsAsync, Label, Movability, RangeLimits}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, Token, TokenKind}; use syntax::util::classify; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 6611661132306..7f15c403e9af9 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -3,6 +3,7 @@ use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; +use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey}; use rustc_span::source_map::{self, respan, Span}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -13,7 +14,6 @@ use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, use syntax::ast::{Constness, Defaultness, Extern, IsAsync, IsAuto, PathSegment, StrLit, Unsafety}; use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; use syntax::ast::{FnHeader, ForeignItem, ForeignItemKind, Mutability, Visibility, VisibilityKind}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree}; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 4c7b37ff7e1f1..1e28372c384f5 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -16,6 +16,7 @@ use crate::lexer::UnmatchedBrace; use crate::{Directory, DirectoryOwnership}; use log::debug; +use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult}; use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; @@ -23,7 +24,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrStyle, AttrVec, CrateSugar, Extern, Ident, Unsafety, DUMMY_NODE_ID}; use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, DelimToken, Token, TokenKind}; use syntax::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint}; diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index edb9044df9206..e07b0733739d1 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -1,12 +1,12 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; +use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult}; use rustc_span::source_map::{respan, Span, Spanned}; use rustc_span::symbol::{kw, sym}; use syntax::ast::{self, AttrVec, Attribute, FieldPat, Mac, Pat, PatKind, RangeEnd, RangeSyntax}; use syntax::ast::{BindingMode, Expr, ExprKind, Ident, Mutability, Path, QSelf}; use syntax::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor}; -use syntax::print::pprust; use syntax::ptr::P; use syntax::token; diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 74f0d24749208..f8c96ecaf9373 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" } arena = { path = "../libarena" } rustc = { path = "../librustc" } rustc_ast_lowering = { path = "../librustc_ast_lowering" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b762e0b08ac04..f8e963192c99f 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -4,6 +4,7 @@ use log::debug; use rustc::bug; use rustc::session::Session; use rustc::ty::{self, DefIdTree}; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; @@ -16,7 +17,6 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, MultiSpan, Span}; use syntax::ast::{self, Ident, Path}; -use syntax::print::pprust; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 55d1be70ad71e..402e25fcf482b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -25,6 +25,7 @@ use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::span_bug; use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, ResolverOutputs}; +use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; @@ -47,7 +48,6 @@ use syntax::ast::{Crate, CRATE_NODE_ID}; use syntax::ast::{ItemKind, Path}; use syntax::attr; use syntax::node_id::{NodeMap, NodeSet}; -use syntax::print::pprust; use syntax::unwrap_or; use syntax::visit::{self, Visitor}; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 966638db493b3..11139a3dc94fc 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -10,6 +10,7 @@ use rustc::middle::stability; use rustc::session::parse::feature_err; use rustc::session::Session; use rustc::{lint, span_bug, ty}; +use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, StabilityLevel}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::SyntaxExtension; @@ -24,7 +25,6 @@ use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use syntax::ast::{self, Ident, NodeId}; -use syntax::print::pprust; use rustc_data_structures::sync::Lrc; use rustc_span::hygiene::{AstPass, MacroKind}; diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index e7a7eefc509e1..2cbed75eaf597 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -11,6 +11,7 @@ path = "lib.rs" [dependencies] log = "0.4" rustc = { path = "../librustc" } +rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2e3e06c36f22b..09c261cdc2388 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -16,22 +16,21 @@ use rustc::session::config::Input; use rustc::span_bug; use rustc::ty::{self, DefIdTree, TyCtxt}; +use rustc_ast_pretty::pprust::{bounds_to_string, generic_params_to_string, ty_to_string}; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind as HirDefKind, Res}; use rustc_hir::def_id::DefId; - -use std::env; -use std::path::Path; - use rustc_span::source_map::{respan, DUMMY_SP}; use rustc_span::*; use syntax::ast::{self, Attribute, NodeId, PatKind}; -use syntax::print::pprust::{bounds_to_string, generic_params_to_string, ty_to_string}; use syntax::ptr::P; use syntax::token; use syntax::visit::{self, Visitor}; use syntax::walk_list; +use std::env; +use std::path::Path; + use crate::dumper::{Access, Dumper}; use crate::sig; use crate::span_utils::SpanUtils; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index f44ce6f4eac27..89054441fa3bf 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -13,11 +13,17 @@ use rustc::middle::privacy::AccessLevels; use rustc::session::config::{CrateType, Input, OutputType}; use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc::{bug, span_bug}; +use rustc_ast_pretty::pprust::{self, param_to_string, ty_to_string}; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind as HirDefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Node; +use rustc_span::source_map::Spanned; +use rustc_span::*; +use syntax::ast::{self, Attribute, NodeId, PatKind, DUMMY_NODE_ID}; +use syntax::util::comments::strip_doc_comment_decoration; +use syntax::visit::{self, Visitor}; use std::cell::Cell; use std::default::Default; @@ -26,14 +32,6 @@ use std::fs::File; use std::io::BufWriter; use std::path::{Path, PathBuf}; -use rustc_span::source_map::Spanned; -use rustc_span::*; -use syntax::ast::{self, Attribute, NodeId, PatKind, DUMMY_NODE_ID}; -use syntax::print::pprust; -use syntax::print::pprust::{param_to_string, ty_to_string}; -use syntax::util::comments::strip_doc_comment_decoration; -use syntax::visit::{self, Visitor}; - use dump_visitor::DumpVisitor; use span_utils::SpanUtils; diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index a9d2bfabb1ba6..dbf29b6531d2a 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -29,9 +29,9 @@ use crate::{id_from_def_id, id_from_node_id, SaveContext}; use rls_data::{SigElement, Signature}; +use rustc_ast_pretty::pprust; use rustc_hir::def::{DefKind, Res}; use syntax::ast::{self, Extern, NodeId}; -use syntax::print::pprust; pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option { if !scx.config.signatures { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c73960fe33b9c..c670641394267 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -44,6 +44,7 @@ use std::sync::Arc; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; +use rustc_ast_pretty::pprust; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; @@ -57,7 +58,6 @@ use rustc_span::symbol::{sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; use syntax::ast; -use syntax::print::pprust; use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy}; use crate::config::RenderOptions; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 27a6a52c02644..ed3f0f94e0ed8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -21,6 +21,7 @@ extern crate env_logger; extern crate getopts; extern crate rustc; +extern crate rustc_ast_pretty; extern crate rustc_attr; extern crate rustc_data_structures; extern crate rustc_driver; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 381308ac6be1c..52776eabdf562 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -141,7 +141,7 @@ pub fn run(options: Options) -> i32 { // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade. fn scrape_test_config(krate: &::rustc_hir::Crate) -> TestOptions { - use syntax::print::pprust; + use rustc_ast_pretty::pprust; let mut opts = TestOptions { no_crate_inject: false, display_warnings: false, attrs: Vec::new() }; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 49f559de1b123..5a8c9f76ea943 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1417,7 +1417,7 @@ pub enum MacDelimiter { } impl MacDelimiter { - crate fn to_token(self) -> DelimToken { + pub fn to_token(self) -> DelimToken { match self { MacDelimiter::Parenthesis => DelimToken::Paren, MacDelimiter::Bracket => DelimToken::Bracket, @@ -1480,7 +1480,7 @@ pub struct StrLit { } impl StrLit { - crate fn as_lit(&self) -> Lit { + pub fn as_lit(&self) -> Lit { let token_kind = match self.style { StrStyle::Cooked => token::Str, StrStyle::Raw(n) => token::StrRaw(n), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index a0b2d50cef3f6..c9800da700fc5 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -47,12 +47,6 @@ pub mod token; pub mod tokenstream; pub mod visit; -pub mod print { - mod helpers; - pub mod pp; - pub mod pprust; -} - use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// Requirements for a `StableHashingContext` to be used in this crate. diff --git a/src/libsyntax/util/comments.rs b/src/libsyntax/util/comments.rs index de33189884c3a..5a67531624d29 100644 --- a/src/libsyntax/util/comments.rs +++ b/src/libsyntax/util/comments.rs @@ -1,13 +1,11 @@ pub use CommentStyle::*; use crate::ast; - use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, CharPos, FileName, Pos}; -use std::usize; - use log::debug; +use std::usize; #[cfg(test)] mod tests; @@ -190,7 +188,7 @@ fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec { // it appears this function is called only from pprust... that's // probably not a good thing. -crate fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec { +pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec { let cm = SourceMap::new(sm.path_mapping().clone()); let source_file = cm.new_source_file(path, src); let text = (*source_file.src.as_ref().unwrap()).clone(); diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index a0ed89a9caef1..b98cc96b3c647 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -367,7 +367,7 @@ pub fn prec_let_scrutinee_needs_par() -> usize { /// /// Conversely, suppose that we have `(let _ = a) OP b` and `order` is that of `OP`. /// Can we print this as `let _ = a OP b`? -crate fn needs_par_as_let_scrutinee(order: i8) -> bool { +pub fn needs_par_as_let_scrutinee(order: i8) -> bool { order <= prec_let_scrutinee_needs_par() as i8 } From 154040097d4de3359fef3a8f7641715b3713fa8c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 17 Jan 2020 14:42:27 +0100 Subject: [PATCH 0744/1253] pacify the parallel compiler --- src/librustc/ty/query/job.rs | 4 ++-- src/librustc_interface/util.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index dd8274dcf22a5..393125f278c03 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -435,11 +435,11 @@ pub unsafe fn handle_deadlock() { let rustc_span_globals = rustc_span::GLOBALS.with(|rustc_span_globals| rustc_span_globals as *const _); let rustc_span_globals = &*rustc_span_globals; - let syntax_globals = syntax::GLOBALS.with(|syntax_globals| syntax_globals as *const _); + let syntax_globals = syntax::attr::GLOBALS.with(|syntax_globals| syntax_globals as *const _); let syntax_globals = &*syntax_globals; thread::spawn(move || { tls::GCX_PTR.set(gcx_ptr, || { - syntax::GLOBALS.set(syntax_globals, || { + syntax::attr::GLOBALS.set(syntax_globals, || { rustc_span::GLOBALS .set(rustc_span_globals, || tls::with_global(|tcx| deadlock(tcx, ®istry))) }); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 842b702be2ab9..3f59a0ca34a24 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -183,15 +183,15 @@ pub fn spawn_thread_pool R + Send, R: Send>( let with_pool = move |pool: &ThreadPool| pool.install(move || f()); - syntax::with_globals(edition, || { - syntax::GLOBALS.with(|syntax_globals| { + syntax::attr::with_globals(edition, || { + syntax::attr::GLOBALS.with(|syntax_globals| { rustc_span::GLOBALS.with(|rustc_span_globals| { // The main handler runs for each Rayon worker thread and sets up // the thread local rustc uses. syntax_globals and rustc_span_globals are // captured and set on the new threads. ty::tls::with_thread_locals sets up // thread local callbacks from libsyntax let main_handler = move |thread: ThreadBuilder| { - syntax::GLOBALS.set(syntax_globals, || { + syntax::attr::GLOBALS.set(syntax_globals, || { rustc_span::GLOBALS.set(rustc_span_globals, || { if let Some(stderr) = stderr { io::set_panic(Some(box Sink(stderr.clone()))); From f882b0797764fb22a445b22748f36f9f904166ae Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 17 Jan 2020 14:48:38 +0100 Subject: [PATCH 0745/1253] remove rustc_ast_pretty dep from rustc --- Cargo.lock | 1 - src/librustc/Cargo.toml | 2 -- 2 files changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62fbba7a77041..ec976b6901646 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3093,7 +3093,6 @@ dependencies = [ "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", - "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 7df5185d27c40..782c6879ac58f 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -21,8 +21,6 @@ rustc-rayon = "0.3.0" rustc-rayon-core = "0.3.0" polonius-engine = "0.11.0" rustc_apfloat = { path = "../librustc_apfloat" } -# FIXME(Centril): remove this dependency when stuff is moved to rustc_lint. -rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } From eadff0682365f21296df54a359be63e5483a99e8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 18 Jan 2020 18:57:06 +0100 Subject: [PATCH 0746/1253] syntax: reexport attr globals --- src/librustc_ast_pretty/pprust/tests.rs | 2 +- src/librustc_interface/interface.rs | 2 +- src/librustc_interface/util.rs | 8 ++++---- src/librustdoc/test.rs | 2 +- src/libsyntax/lib.rs | 1 + 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/src/librustc_ast_pretty/pprust/tests.rs index ec6f5096d91af..279e6f518a71d 100644 --- a/src/librustc_ast_pretty/pprust/tests.rs +++ b/src/librustc_ast_pretty/pprust/tests.rs @@ -3,7 +3,7 @@ use super::*; use rustc_span; use rustc_span::source_map::{dummy_spanned, respan}; use syntax::ast; -use syntax::attr::with_default_globals; +use syntax::with_default_globals; fn fun_to_string( decl: &ast::FnDecl, diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index ae758b5e3273a..2a667541ad3e7 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -65,7 +65,7 @@ impl Compiler { /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option)> { - syntax::attr::with_default_globals(move || { + syntax::with_default_globals(move || { let cfg = cfgspecs .into_iter() .map(|s| { diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 3f59a0ca34a24..3052c9fc26f08 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -147,7 +147,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( crate::callbacks::setup_callbacks(); scoped_thread(cfg, || { - syntax::attr::with_globals(edition, || { + syntax::with_globals(edition, || { ty::tls::GCX_PTR.set(&Lock::new(0), || { if let Some(stderr) = stderr { io::set_panic(Some(box Sink(stderr.clone()))); @@ -183,15 +183,15 @@ pub fn spawn_thread_pool R + Send, R: Send>( let with_pool = move |pool: &ThreadPool| pool.install(move || f()); - syntax::attr::with_globals(edition, || { - syntax::attr::GLOBALS.with(|syntax_globals| { + syntax::with_globals(edition, || { + syntax::GLOBALS.with(|syntax_globals| { rustc_span::GLOBALS.with(|rustc_span_globals| { // The main handler runs for each Rayon worker thread and sets up // the thread local rustc uses. syntax_globals and rustc_span_globals are // captured and set on the new threads. ty::tls::with_thread_locals sets up // thread local callbacks from libsyntax let main_handler = move |thread: ThreadBuilder| { - syntax::attr::GLOBALS.set(syntax_globals, || { + syntax::GLOBALS.set(syntax_globals, || { rustc_span::GLOBALS.set(rustc_span_globals, || { if let Some(stderr) = stderr { io::set_panic(Some(box Sink(stderr.clone()))); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 52776eabdf562..936f63975a58e 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -18,7 +18,7 @@ use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; use syntax::ast; -use syntax::attr::with_globals; +use syntax::with_globals; use tempfile::Builder as TempFileBuilder; use testing; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c9800da700fc5..66c747f2c517a 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -38,6 +38,7 @@ pub mod util { pub mod ast; pub mod attr; +pub use attr::{with_default_globals, with_globals, GLOBALS}; pub mod entry; pub mod expand; pub mod mut_visit; From a0838462cf9dc05569ee2759f47928f96f6c4831 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 18 Jan 2020 19:01:50 +0100 Subject: [PATCH 0747/1253] pretty: injected_crate_name -> has_injected_crate --- src/librustc_ast_pretty/pprust.rs | 7 +++---- src/librustc_driver/pretty.rs | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 2257710147abf..761af72f95dd6 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1,10 +1,9 @@ use crate::pp::Breaks::{Consistent, Inconsistent}; use crate::pp::{self, Breaks}; -use rustc_data_structures::sync::Once; use rustc_span::edition::Edition; use rustc_span::source_map::{dummy_spanned, SourceMap, Spanned}; -use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, FileName, Span}; use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use syntax::ast::{Attribute, GenericArg, MacArgs}; @@ -103,7 +102,7 @@ pub fn print_crate<'a>( ann: &'a dyn PpAnn, is_expanded: bool, edition: Edition, - injected_crate_name: &Once, + has_injected_crate: bool, ) -> String { let mut s = State { s: pp::mk_printer(), @@ -112,7 +111,7 @@ pub fn print_crate<'a>( is_expanded, }; - if is_expanded && injected_crate_name.try_get().is_some() { + if is_expanded && has_injected_crate { // We need to print `#![no_std]` (and its feature gate) so that // compiling pretty-printed source won't inject libstd again. // However, we don't want these attributes in the AST because diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 65dbc59ea55b0..345b03e6db243 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -400,7 +400,7 @@ pub fn print_after_parsing( annotation.pp_ann(), false, parse.edition, - &parse.injected_crate_name, + parse.injected_crate_name.try_get().is_some(), ) }) } else { @@ -442,7 +442,7 @@ pub fn print_after_hir_lowering<'tcx>( annotation.pp_ann(), true, parse.edition, - &parse.injected_crate_name, + parse.injected_crate_name.try_get().is_some(), ) }) } From aef2df1aaa2a7ee86a139d98344570d872103d8f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 18 Jan 2020 19:21:05 +0100 Subject: [PATCH 0748/1253] fix fallout in tests --- src/librustc_expand/mut_visit/tests.rs | 2 +- src/librustc_expand/parse/lexer/tests.rs | 2 +- src/librustc_expand/parse/tests.rs | 4 ++-- src/librustc_expand/tests.rs | 2 +- src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs | 3 ++- src/test/ui-fulldeps/mod_dir_path_canonicalized.rs | 3 ++- src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 6 ++++-- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/librustc_expand/mut_visit/tests.rs b/src/librustc_expand/mut_visit/tests.rs index 003ce0fcb1fd4..49b9a1b1025ab 100644 --- a/src/librustc_expand/mut_visit/tests.rs +++ b/src/librustc_expand/mut_visit/tests.rs @@ -1,8 +1,8 @@ use crate::tests::{matches_codepattern, string_to_crate}; +use rustc_ast_pretty::pprust; use syntax::ast::{self, Ident}; use syntax::mut_visit::{self, MutVisitor}; -use syntax::print::pprust; use syntax::with_default_globals; // This version doesn't care about getting comments or doc-strings in. diff --git a/src/librustc_expand/parse/lexer/tests.rs b/src/librustc_expand/parse/lexer/tests.rs index 2ef81d80a1412..c486839dad506 100644 --- a/src/librustc_expand/parse/lexer/tests.rs +++ b/src/librustc_expand/parse/lexer/tests.rs @@ -1,10 +1,10 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{emitter::EmitterWriter, Handler}; use rustc_parse::lexer::StringReader; +use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Span}; -use syntax::sess::ParseSess; use syntax::token::{self, Token, TokenKind}; use syntax::util::comments::is_doc_comment; use syntax::with_default_globals; diff --git a/src/librustc_expand/parse/tests.rs b/src/librustc_expand/parse/tests.rs index b79e2894126dd..3641f03cb30c5 100644 --- a/src/librustc_expand/parse/tests.rs +++ b/src/librustc_expand/parse/tests.rs @@ -1,14 +1,14 @@ use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; +use rustc_ast_pretty::pprust::item_to_string; use rustc_errors::PResult; use rustc_parse::new_parser_from_source_str; +use rustc_session::parse::ParseSess; use rustc_span::source_map::FilePathMapping; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, FileName, Pos, Span}; use syntax::ast::{self, Name, PatKind}; -use syntax::print::pprust::item_to_string; use syntax::ptr::P; -use syntax::sess::ParseSess; use syntax::token::{self, Token}; use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree}; use syntax::visit; diff --git a/src/librustc_expand/tests.rs b/src/librustc_expand/tests.rs index 82ab74ac15004..4ed60465f24f2 100644 --- a/src/librustc_expand/tests.rs +++ b/src/librustc_expand/tests.rs @@ -1,8 +1,8 @@ use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream}; +use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{BytePos, MultiSpan, Span}; use syntax::ast; -use syntax::sess::ParseSess; use syntax::tokenstream::TokenStream; use syntax::with_default_globals; diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index 725c350fe4e22..fbdad29d6494f 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -1,6 +1,7 @@ #![feature(box_syntax, plugin, plugin_registrar, rustc_private)] #![crate_type = "dylib"] +extern crate rustc_ast_pretty; extern crate rustc_driver; extern crate rustc_hir; #[macro_use] extern crate rustc_lint; @@ -8,13 +9,13 @@ extern crate rustc_hir; extern crate rustc_span; extern crate syntax; +use rustc_ast_pretty::pprust; use rustc_hir::intravisit; use rustc_hir as hir; use rustc_hir::Node; use rustc_lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; use rustc_driver::plugin::Registry; use rustc_span::source_map; -use syntax::print::pprust; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { diff --git a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs index 2b4a9fb21e4c7..be4b49ada02c7 100644 --- a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -6,12 +6,13 @@ extern crate syntax; extern crate rustc_parse; +extern crate rustc_session; extern crate rustc_span; use rustc_parse::new_parser_from_file; +use rustc_session::parse::ParseSess; use rustc_span::source_map::FilePathMapping; use std::path::Path; -use syntax::sess::ParseSess; #[path = "mod_dir_simple/test.rs"] mod gravy; diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index 04d1054e2877f..0f6a88b2691a8 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -19,19 +19,21 @@ #![feature(rustc_private)] +extern crate rustc_ast_pretty; extern crate rustc_data_structures; extern crate syntax; extern crate rustc_parse; +extern crate rustc_session; extern crate rustc_span; +use rustc_ast_pretty::pprust; use rustc_data_structures::thin_vec::ThinVec; use rustc_parse::new_parser_from_source_str; +use rustc_session::parse::ParseSess; use rustc_span::source_map::{Spanned, DUMMY_SP, FileName}; use rustc_span::source_map::FilePathMapping; use syntax::ast::*; -use syntax::sess::ParseSess; use syntax::mut_visit::{self, MutVisitor, visit_clobber}; -use syntax::print::pprust; use syntax::ptr::P; fn parse_expr(ps: &ParseSess, src: &str) -> Option> { From 1a3141c86e9b91d4f75117075d943b72ee7dba48 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 22 Jan 2020 00:42:29 +0100 Subject: [PATCH 0749/1253] pretty: raise recursion_limit = 256 --- src/librustc_ast_pretty/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_ast_pretty/lib.rs b/src/librustc_ast_pretty/lib.rs index 4c3a836e17ccf..bde5f4bb03d0d 100644 --- a/src/librustc_ast_pretty/lib.rs +++ b/src/librustc_ast_pretty/lib.rs @@ -1,5 +1,6 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] +#![recursion_limit = "256"] mod helpers; pub mod pp; From 847d5b4d1387a30f1798a5c3c59c3e0c31e00319 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 2 Feb 2020 02:29:28 +0800 Subject: [PATCH 0750/1253] Derive Clone + PartialEq + Eq for std::string::FromUtf8Error --- src/liballoc/string.rs | 2 +- src/liballoc/tests/string.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 96f871d889708..8c9c95eec60c6 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -319,7 +319,7 @@ pub struct String { /// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct FromUtf8Error { bytes: Vec, error: Utf8Error, diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index dd44495845961..08859b2b24bde 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -50,7 +50,11 @@ fn test_from_utf8() { let xs = b"hello\xFF".to_vec(); let err = String::from_utf8(xs).unwrap_err(); + assert_eq!(err.as_bytes(), b"hello\xff"); + let err_clone = err.clone(); + assert_eq!(err, err_clone); assert_eq!(err.into_bytes(), b"hello\xff".to_vec()); + assert_eq!(err_clone.utf8_error().valid_up_to(), 5); } #[test] From 791123d2c4c884f97c431edf6aa8daa5dd9f6062 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 31 Jan 2020 15:59:14 +0100 Subject: [PATCH 0751/1253] Deduplicate generator interior types --- .../check/generator_interior.rs | 48 +++++++++++-------- src/test/ui/generator/not-send-sync.stderr | 2 +- .../recursive-impl-trait-type-indirect.stderr | 4 +- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 75cc2c132f8a8..50692e0f10487 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -7,7 +7,7 @@ use super::FnCtxt; use rustc::hir::map::Map; use rustc::middle::region::{self, YieldData}; use rustc::ty::{self, Ty}; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -160,33 +160,39 @@ pub fn resolve_interior<'a, 'tcx>( debug!("types in generator {:?}, span = {:?}", types, body.value.span); - // Replace all regions inside the generator interior with late bound regions - // Note that each region slot in the types gets a new fresh late bound region, - // which means that none of the regions inside relate to any other, even if - // typeck had previously found constraints that would cause them to be related. let mut counter = 0; - let fold_types: Vec<_> = types.iter().map(|(t, _)| t.ty).collect(); - let folded_types = fcx.tcx.fold_regions(&fold_types, &mut false, |_, current_depth| { - counter += 1; - fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter))) - }); - - // Store the generator types and spans into the tables for this generator. - let types = types + let mut captured_tys = FxHashSet::default(); + let type_causes: Vec<_> = types .into_iter() - .zip(&folded_types) - .map(|((mut interior_cause, _), ty)| { - interior_cause.ty = ty; - interior_cause + .filter_map(|(mut cause, _)| { + // Erase regions and canonicalize late-bound regions to deduplicate as many types as we + // can. + let erased = fcx.tcx.erase_regions(&cause.ty); + if captured_tys.insert(erased) { + // Replace all regions inside the generator interior with late bound regions. + // Note that each region slot in the types gets a new fresh late bound region, + // which means that none of the regions inside relate to any other, even if + // typeck had previously found constraints that would cause them to be related. + let folded = fcx.tcx.fold_regions(&erased, &mut false, |_, current_depth| { + counter += 1; + fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter))) + }); + + cause.ty = folded; + Some(cause) + } else { + None + } }) .collect(); - visitor.fcx.inh.tables.borrow_mut().generator_interior_types = types; - - // Extract type components - let type_list = fcx.tcx.mk_type_list(folded_types.iter()); + // Extract type components to build the witness type. + let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); + // Store the generator types and spans into the tables for this generator. + visitor.fcx.inh.tables.borrow_mut().generator_interior_types = type_causes; + debug!( "types in generator after region replacement {:?}, span = {:?}", witness, body.value.span diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 18d9012b3acf6..0ac1d189b79b0 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -20,7 +20,7 @@ LL | fn assert_sync(_: T) {} LL | assert_sync(|| { | ^^^^^^^^^^^ future returned by `main` is not `Sync` | - = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, (), ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` + = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` note: future is not `Sync` as this value is used across an yield --> $DIR/not-send-sync.rs:12:9 | diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr index 15a028f60ae11..b7ba0d6ab177c 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr @@ -76,7 +76,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_capture() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {(), ()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:53:26 @@ -92,7 +92,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_hold() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, (), ()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, ()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:69:26 From 88d64a09314d7f19201eebc1b92377afed31b5c2 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 1 Feb 2020 19:06:15 +0000 Subject: [PATCH 0752/1253] Simplify span usage and avoid .eat() --- src/librustc_parse/parser/path.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 25ba571a6a494..a4541046c6c14 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -71,15 +71,15 @@ impl<'a> Parser<'a> { debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count); } - let lo_colon = self.token.span; - if self.eat(&token::Colon) { + if self.token.kind == token::Colon { // >:Qux // ^ - let span = lo_colon.to(self.prev_span); + self.bump(); + self.diagnostic() - .struct_span_err(span, "found single colon where type path was expected") + .struct_span_err(self.prev_span, "found single colon where type path was expected") .span_suggestion( - span, + self.prev_span, "use double colon", "::".to_string(), Applicability::MachineApplicable, From f5f86be1d40f30b3183ec148f443afa73d0cbe15 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 31 Jan 2020 18:58:28 -0500 Subject: [PATCH 0753/1253] Add support for enabling the LLVM time-trace feature I found this helpful while investigating an LLVM performance issue. Passing `-Z llvm-time-trace` causes a `llvm_timings.json` file to be created. This file can be inspected in either the Chrome Profiler tools or with any other compatible tool like SpeedScope. More information on the LLVM feature: - https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/ - https://reviews.llvm.org/rL357340 --- src/librustc_codegen_llvm/lib.rs | 6 ++++++ src/librustc_codegen_llvm/llvm/ffi.rs | 4 ++++ src/librustc_codegen_llvm/llvm_util.rs | 18 ++++++++++++++++++ src/librustc_session/options.rs | 2 ++ src/rustllvm/PassWrapper.cpp | 18 ++++++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 70e3874035b60..60771d385aea5 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -332,6 +332,12 @@ impl CodegenBackend for LlvmCodegenBackend { // any more, we can finalize it (which involves renaming it) rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash); + sess.time("llvm_dump_timing_file", || { + if sess.opts.debugging_opts.llvm_time_trace { + llvm_util::time_trace_profiler_finish("llvm_timings.json"); + } + }); + Ok(()) } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 875b2c47b3b36..3f37f86676c98 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1454,6 +1454,10 @@ extern "C" { pub fn LLVMInitializePasses(); + pub fn LLVMTimeTraceProfilerInitialize(); + + pub fn LLVMTimeTraceProfilerFinish(FileName: *const c_char); + pub fn LLVMAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>); pub fn LLVMPassManagerBuilderCreate() -> &'static mut PassManagerBuilder; diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 4823fe10c463f..6d3498f8b800b 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -113,6 +113,15 @@ unsafe fn configure_llvm(sess: &Session) { } } + if sess.opts.debugging_opts.llvm_time_trace && get_major_version() >= 9 { + // time-trace is not thread safe and running it in parallel will cause seg faults. + if !sess.opts.debugging_opts.no_parallel_llvm { + bug!("`-Z llvm-time-trace` requires `-Z no-parallel-llvm") + } + + llvm::LLVMTimeTraceProfilerInitialize(); + } + llvm::LLVMInitializePasses(); ::rustc_llvm::initialize_available_targets(); @@ -120,6 +129,15 @@ unsafe fn configure_llvm(sess: &Session) { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); } +pub fn time_trace_profiler_finish(file_name: &str) { + unsafe { + if get_major_version() >= 9 { + let file_name = CString::new(file_name).unwrap(); + llvm::LLVMTimeTraceProfilerFinish(file_name.as_ptr()); + } + } +} + // WARNING: the features after applying `to_llvm_feature` must be known // to LLVM or the feature detection code will walk past the end of the feature // array, leading to crashes. diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 34da2188a51d2..a18b6eb4402fb 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -718,6 +718,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "measure time of rustc processes"), time_llvm_passes: bool = (false, parse_bool, [UNTRACKED], "measure time of each LLVM pass"), + llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], + "generate JSON tracing data file from LLVM data"), input_stats: bool = (false, parse_bool, [UNTRACKED], "gather statistics about the input"), asm_comments: bool = (false, parse_bool, [TRACKED], diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index fad703698075d..4ac7e0e6e1fc0 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -26,6 +26,7 @@ #include "llvm/Transforms/Instrumentation.h" #if LLVM_VERSION_GE(9, 0) #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" +#include "llvm/Support/TimeProfiler.h" #endif #if LLVM_VERSION_GE(8, 0) #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" @@ -57,6 +58,23 @@ extern "C" void LLVMInitializePasses() { initializeTarget(Registry); } +extern "C" void LLVMTimeTraceProfilerInitialize() { +#if LLVM_VERSION_GE(9, 0) + timeTraceProfilerInitialize(); +#endif +} + +extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { +#if LLVM_VERSION_GE(9, 0) + StringRef FN(FileName); + std::error_code EC; + raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways); + + timeTraceProfilerWrite(OS); + timeTraceProfilerCleanup(); +#endif +} + enum class LLVMRustPassKind { Other, Function, From 45fb7232abc893a06272550ebcad7b39a3cb26c1 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 1 Feb 2020 19:10:42 +0000 Subject: [PATCH 0754/1253] Move colon-check to recover_colon_before_qpath_proj() --- src/librustc_parse/parser/path.rs | 38 +++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index a4541046c6c14..027380eaa2a69 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -71,21 +71,7 @@ impl<'a> Parser<'a> { debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count); } - if self.token.kind == token::Colon { - // >:Qux - // ^ - self.bump(); - - self.diagnostic() - .struct_span_err(self.prev_span, "found single colon where type path was expected") - .span_suggestion( - self.prev_span, - "use double colon", - "::".to_string(), - Applicability::MachineApplicable, - ) - .emit(); - } else { + if !self.recover_colon_before_qpath_proj() { self.expect(&token::ModSep)?; } @@ -95,6 +81,28 @@ impl<'a> Parser<'a> { Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_span) })) } + fn recover_colon_before_qpath_proj(&mut self) -> bool { + if self.token.kind != token::Colon { + return false; + } + + // >:Qux + // ^ + self.bump(); + + self.diagnostic() + .struct_span_err(self.prev_span, "found single colon where type path was expected") + .span_suggestion( + self.prev_span, + "use double colon", + "::".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + + true + } + /// Parses simple paths. /// /// `path = [::] segment+` From 991d2ee282837a0ca3ec5a730e081274d37fa8b0 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 1 Feb 2020 19:21:54 +0000 Subject: [PATCH 0755/1253] Improve wording and docs for qualified path recovery --- src/librustc_parse/parser/path.rs | 15 +++++++++++---- .../ui/parser/qualified-path-in-turbofish.fixed | 2 +- src/test/ui/parser/qualified-path-in-turbofish.rs | 2 +- .../ui/parser/qualified-path-in-turbofish.stderr | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 027380eaa2a69..5aa14c1739ff6 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -81,17 +81,24 @@ impl<'a> Parser<'a> { Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_span) })) } + /// Recover from an invalid single colon, when the user likely meant a qualified path. + /// + /// ```ignore (diagnostics) + /// >:Qux + /// ^ help: use double colon + /// ``` fn recover_colon_before_qpath_proj(&mut self) -> bool { if self.token.kind != token::Colon { return false; } - // >:Qux - // ^ - self.bump(); + self.bump(); // colon self.diagnostic() - .struct_span_err(self.prev_span, "found single colon where type path was expected") + .struct_span_err( + self.prev_span, + "found single colon before projection in qualified path", + ) .span_suggestion( self.prev_span, "use double colon", diff --git a/src/test/ui/parser/qualified-path-in-turbofish.fixed b/src/test/ui/parser/qualified-path-in-turbofish.fixed index a4213bdd3fb34..404d2f7762df4 100644 --- a/src/test/ui/parser/qualified-path-in-turbofish.fixed +++ b/src/test/ui/parser/qualified-path-in-turbofish.fixed @@ -15,5 +15,5 @@ fn template() -> i64 { fn main() { template::<::Ty>(); - //~^ ERROR found single colon where type path was expected + //~^ ERROR found single colon before projection in qualified path } diff --git a/src/test/ui/parser/qualified-path-in-turbofish.rs b/src/test/ui/parser/qualified-path-in-turbofish.rs index 75b2af2aa2e08..2f4b2ed348b9c 100644 --- a/src/test/ui/parser/qualified-path-in-turbofish.rs +++ b/src/test/ui/parser/qualified-path-in-turbofish.rs @@ -15,5 +15,5 @@ fn template() -> i64 { fn main() { template::<:Ty>(); - //~^ ERROR found single colon where type path was expected + //~^ ERROR found single colon before projection in qualified path } diff --git a/src/test/ui/parser/qualified-path-in-turbofish.stderr b/src/test/ui/parser/qualified-path-in-turbofish.stderr index 1fe6353b7a013..8857d2ef30cfc 100644 --- a/src/test/ui/parser/qualified-path-in-turbofish.stderr +++ b/src/test/ui/parser/qualified-path-in-turbofish.stderr @@ -1,4 +1,4 @@ -error: found single colon where type path was expected +error: found single colon before projection in qualified path --> $DIR/qualified-path-in-turbofish.rs:17:27 | LL | template::<:Ty>(); From 07ee472cd18925be45d424d9cfd59c441ea9c9a7 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 1 Feb 2020 19:24:51 +0000 Subject: [PATCH 0756/1253] Avoid qualified path recovery when not followed by identifier --- src/librustc_parse/parser/path.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 5aa14c1739ff6..a09eb42dcfe6a 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -82,13 +82,17 @@ impl<'a> Parser<'a> { } /// Recover from an invalid single colon, when the user likely meant a qualified path. + /// We avoid emitting this if not followed by an identifier, as our assumption that the user + /// intended this to be a qualified path may not be correct. /// /// ```ignore (diagnostics) /// >:Qux /// ^ help: use double colon /// ``` fn recover_colon_before_qpath_proj(&mut self) -> bool { - if self.token.kind != token::Colon { + if self.token.kind != token::Colon + || self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident()) + { return false; } From 726568bd1b4ac9af4dc84816eae1957c3d2bfc32 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 04:40:55 +0900 Subject: [PATCH 0757/1253] Do not suggest things named underscore --- src/librustc_resolve/diagnostics.rs | 5 +++++ .../resolve/typo-suggestion-named-underscore.rs | 14 ++++++++++++++ .../typo-suggestion-named-underscore.stderr | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 src/test/ui/resolve/typo-suggestion-named-underscore.rs create mode 100644 src/test/ui/resolve/typo-suggestion-named-underscore.stderr diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b762e0b08ac04..1705736a67c43 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -769,6 +769,11 @@ impl<'a> Resolver<'a> { span: Span, ) -> bool { if let Some(suggestion) = suggestion { + // We shouldn't suggest underscore. + if suggestion.candidate == kw::Underscore { + return false; + } + let msg = format!( "{} {} with a similar name exists", suggestion.res.article(), diff --git a/src/test/ui/resolve/typo-suggestion-named-underscore.rs b/src/test/ui/resolve/typo-suggestion-named-underscore.rs new file mode 100644 index 0000000000000..a2b05db035150 --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-named-underscore.rs @@ -0,0 +1,14 @@ +const _: () = (); + +fn main() { + a // Shouldn't suggest underscore + //~^ ERROR: cannot find value `a` in this scope +} + +trait Unknown {} + +#[allow(unused_imports)] +use Unknown as _; + +fn foo(x: T) {} // Shouldn't suggest underscore +//~^ ERROR: cannot find trait `A` in this scope diff --git a/src/test/ui/resolve/typo-suggestion-named-underscore.stderr b/src/test/ui/resolve/typo-suggestion-named-underscore.stderr new file mode 100644 index 0000000000000..65d1b084a3a7b --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-named-underscore.stderr @@ -0,0 +1,16 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/typo-suggestion-named-underscore.rs:4:5 + | +LL | a // Shouldn't suggest underscore + | ^ not found in this scope + +error[E0405]: cannot find trait `A` in this scope + --> $DIR/typo-suggestion-named-underscore.rs:13:11 + | +LL | fn foo(x: T) {} // Shouldn't suggest underscore + | ^ not found in this scope + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0405, E0425. +For more information about an error, try `rustc --explain E0405`. From fd2282388140ea0f370ee25c82f00be81c2f822c Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Sat, 1 Feb 2020 22:19:28 +0100 Subject: [PATCH 0758/1253] implement AsMut for String --- src/liballoc/string.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 96f871d889708..99725917b5d87 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2208,6 +2208,14 @@ impl AsRef for String { } } +#[stable(feature = "string_as_mut", since = "1.43.0")] +impl AsMut for String { + #[inline] + fn as_mut(&mut self) -> &mut str { + self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<[u8]> for String { #[inline] From 9d8058fb423ff21a6c05945ef83f0d5eb4b33fb8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 06:39:50 +0900 Subject: [PATCH 0759/1253] Do not ICE in `type-alias-impl-trait` with save-analysis --- src/librustc_typeck/check/mod.rs | 7 +++++-- src/test/ui/save-analysis/issue-68621.rs | 17 +++++++++++++++++ src/test/ui/save-analysis/issue-68621.stderr | 8 ++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/save-analysis/issue-68621.rs create mode 100644 src/test/ui/save-analysis/issue-68621.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4d1f92d19ce09..c87ef250dcfce 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -837,8 +837,11 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool { return tcx.has_typeck_tables(outer_def_id); } - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - primary_body_of(tcx, id).is_some() + if let Some(id) = tcx.hir().as_local_hir_id(def_id) { + primary_body_of(tcx, id).is_some() + } else { + false + } } fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet { diff --git a/src/test/ui/save-analysis/issue-68621.rs b/src/test/ui/save-analysis/issue-68621.rs new file mode 100644 index 0000000000000..96af085c5b6b8 --- /dev/null +++ b/src/test/ui/save-analysis/issue-68621.rs @@ -0,0 +1,17 @@ +// compile-flags: -Zsave-analysis + +#![feature(type_alias_impl_trait)] + +trait Trait {} + +trait Service { + type Future: Trait; +} + +struct Struct; + +impl Service for Struct { + type Future = impl Trait; //~ ERROR: could not find defining uses +} + +fn main() {} diff --git a/src/test/ui/save-analysis/issue-68621.stderr b/src/test/ui/save-analysis/issue-68621.stderr new file mode 100644 index 0000000000000..2c5bbd7782b35 --- /dev/null +++ b/src/test/ui/save-analysis/issue-68621.stderr @@ -0,0 +1,8 @@ +error: could not find defining uses + --> $DIR/issue-68621.rs:14:5 + | +LL | type Future = impl Trait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 425e494fceb2f88bec344ef07d0f2db4c74dd2d1 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 12:03:03 +0000 Subject: [PATCH 0760/1253] Remove or_patterns from INCOMPLETE_FEATURES --- src/librustc_feature/active.rs | 1 - .../ui/lint/issue-54538-unused-parens-lint.rs | 1 - .../issue-54538-unused-parens-lint.stderr | 58 ++++++++---------- src/test/ui/or-patterns/already-bound-name.rs | 1 - .../ui/or-patterns/already-bound-name.stderr | 38 +++++------- .../ui/or-patterns/consistent-bindings.rs | 1 - .../ui/or-patterns/consistent-bindings.stderr | 10 +--- .../exhaustiveness-non-exhaustive.rs | 7 +-- .../exhaustiveness-non-exhaustive.stderr | 8 +-- .../ui/or-patterns/exhaustiveness-pass.rs | 11 ++-- .../ui/or-patterns/exhaustiveness-pass.stderr | 2 +- .../exhaustiveness-unreachable-pattern.rs | 22 +++---- .../exhaustiveness-unreachable-pattern.stderr | 36 +++++------ .../ui/or-patterns/feature-gate-const-fn.rs | 1 - .../or-patterns/feature-gate-const-fn.stderr | 12 ++-- src/test/ui/or-patterns/inconsistent-modes.rs | 2 - .../ui/or-patterns/inconsistent-modes.stderr | 26 +++----- src/test/ui/or-patterns/missing-bindings.rs | 2 - .../ui/or-patterns/missing-bindings.stderr | 60 ++++++++----------- .../ui/or-patterns/multiple-pattern-typo.rs | 1 - .../or-patterns/multiple-pattern-typo.stderr | 22 +++---- .../or-patterns/or-patterns-syntactic-fail.rs | 1 - .../or-patterns-syntactic-fail.stderr | 40 +++++-------- .../or-patterns/or-patterns-syntactic-pass.rs | 2 +- .../or-patterns-syntactic-pass.stderr | 8 --- .../pat-at-same-name-both.rs | 1 - .../pat-at-same-name-both.stderr | 28 ++++----- 27 files changed, 154 insertions(+), 248 deletions(-) delete mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index f20a57ea61c42..0252d88e73889 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -556,7 +556,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::impl_trait_in_bindings, sym::generic_associated_types, sym::const_generics, - sym::or_patterns, sym::let_chains, sym::raw_dylib, sym::const_trait_impl, diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs index 7dcbdd0863cbd..f3d2d1bb58d8f 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs @@ -1,7 +1,6 @@ #![feature(box_patterns, stmt_expr_attributes)] #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete #![allow(ellipsis_inclusive_range_patterns)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr index b6d532c31017c..b31ad95b191c9 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr @@ -1,157 +1,149 @@ -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/issue-54538-unused-parens-lint.rs:3:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:12:9 + --> $DIR/issue-54538-unused-parens-lint.rs:11:9 | LL | let (a) = 0; | ^^^ help: remove these parentheses | note: the lint level is defined here - --> $DIR/issue-54538-unused-parens-lint.rs:9:9 + --> $DIR/issue-54538-unused-parens-lint.rs:8:9 | LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:13:9 + --> $DIR/issue-54538-unused-parens-lint.rs:12:9 | LL | for (a) in 0..1 {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:14:12 + --> $DIR/issue-54538-unused-parens-lint.rs:13:12 | LL | if let (a) = 0 {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:15:15 + --> $DIR/issue-54538-unused-parens-lint.rs:14:15 | LL | while let (a) = 0 {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:16:12 + --> $DIR/issue-54538-unused-parens-lint.rs:15:12 | LL | fn foo((a): u8) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:17:14 + --> $DIR/issue-54538-unused-parens-lint.rs:16:14 | LL | let _ = |(a): u8| 0; | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:45:12 + --> $DIR/issue-54538-unused-parens-lint.rs:44:12 | LL | if let (0 | 1) = 0 {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:46:13 + --> $DIR/issue-54538-unused-parens-lint.rs:45:13 | LL | if let ((0 | 1),) = (0,) {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:47:13 + --> $DIR/issue-54538-unused-parens-lint.rs:46:13 | LL | if let [(0 | 1)] = [0] {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:48:16 + --> $DIR/issue-54538-unused-parens-lint.rs:47:16 | LL | if let 0 | (1 | 2) = 0 {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:50:15 + --> $DIR/issue-54538-unused-parens-lint.rs:49:15 | LL | if let TS((0 | 1)) = TS(0) {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:52:20 + --> $DIR/issue-54538-unused-parens-lint.rs:51:20 | LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:62:9 + --> $DIR/issue-54538-unused-parens-lint.rs:61:9 | LL | (_) => {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:63:9 + --> $DIR/issue-54538-unused-parens-lint.rs:62:9 | LL | (y) => {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:64:9 + --> $DIR/issue-54538-unused-parens-lint.rs:63:9 | LL | (ref r) => {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:65:9 + --> $DIR/issue-54538-unused-parens-lint.rs:64:9 | LL | (e @ 1...2) => {} | ^^^^^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:71:9 + --> $DIR/issue-54538-unused-parens-lint.rs:70:9 | LL | (e @ &(1...2)) => {} | ^^^^^^^^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:72:10 + --> $DIR/issue-54538-unused-parens-lint.rs:71:10 | LL | &(_) => {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:83:9 + --> $DIR/issue-54538-unused-parens-lint.rs:82:9 | LL | (_) => {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:84:9 + --> $DIR/issue-54538-unused-parens-lint.rs:83:9 | LL | (y) => {} | ^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:85:9 + --> $DIR/issue-54538-unused-parens-lint.rs:84:9 | LL | (ref r) => {} | ^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:86:9 + --> $DIR/issue-54538-unused-parens-lint.rs:85:9 | LL | (e @ 1..=2) => {} | ^^^^^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:92:9 + --> $DIR/issue-54538-unused-parens-lint.rs:91:9 | LL | (e @ &(1..=2)) => {} | ^^^^^^^^^^^^^^ help: remove these parentheses error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:93:10 + --> $DIR/issue-54538-unused-parens-lint.rs:92:10 | LL | &(_) => {} | ^^^ help: remove these parentheses diff --git a/src/test/ui/or-patterns/already-bound-name.rs b/src/test/ui/or-patterns/already-bound-name.rs index 3ebf59c643735..726e17b7ec226 100644 --- a/src/test/ui/or-patterns/already-bound-name.rs +++ b/src/test/ui/or-patterns/already-bound-name.rs @@ -2,7 +2,6 @@ // correctly accounts for or-patterns. #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete enum E { A(T, T), B(T) } diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr index 948c91370d0d4..9924b0d7f72eb 100644 --- a/src/test/ui/or-patterns/already-bound-name.stderr +++ b/src/test/ui/or-patterns/already-bound-name.stderr @@ -1,97 +1,89 @@ error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:12:13 + --> $DIR/already-bound-name.rs:11:13 | LL | let (a, a) = (0, 1); // Standard duplication without an or-pattern. | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:15:15 + --> $DIR/already-bound-name.rs:14:15 | LL | let (a, A(a, _) | B(a)) = (0, A(1, 2)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:15:25 + --> $DIR/already-bound-name.rs:14:25 | LL | let (a, A(a, _) | B(a)) = (0, A(1, 2)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:19:26 + --> $DIR/already-bound-name.rs:18:26 | LL | let (A(a, _) | B(a), a) = (A(0, 1), 2); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:22:14 + --> $DIR/already-bound-name.rs:21:14 | LL | let A(a, a) | B(a) = A(0, 1); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:25:21 + --> $DIR/already-bound-name.rs:24:21 | LL | let B(a) | A(a, a) = A(0, 1); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:29:21 + --> $DIR/already-bound-name.rs:28:21 | LL | B(a) | A(a, a) => {} // Let's ensure `match` has no funny business. | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:33:36 + --> $DIR/already-bound-name.rs:32:36 | LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:33:46 + --> $DIR/already-bound-name.rs:32:46 | LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:38:36 + --> $DIR/already-bound-name.rs:37:36 | LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:38:46 + --> $DIR/already-bound-name.rs:37:46 | LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once error[E0408]: variable `a` is not bound in all patterns - --> $DIR/already-bound-name.rs:38:9 + --> $DIR/already-bound-name.rs:37:9 | LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); | ^^^^ pattern doesn't bind `a` - variable not in all patterns error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:43:49 + --> $DIR/already-bound-name.rs:42:49 | LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/already-bound-name.rs:43:59 + --> $DIR/already-bound-name.rs:42:59 | LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); | ^ used in a pattern more than once -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/already-bound-name.rs:4:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/already-bound-name.rs:33:31 + --> $DIR/already-bound-name.rs:32:31 | LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); | ^ ------- this expression has type `E>` diff --git a/src/test/ui/or-patterns/consistent-bindings.rs b/src/test/ui/or-patterns/consistent-bindings.rs index 0eb539dca4cba..ec71afed872ba 100644 --- a/src/test/ui/or-patterns/consistent-bindings.rs +++ b/src/test/ui/or-patterns/consistent-bindings.rs @@ -3,7 +3,6 @@ // edition:2018 #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete fn main() { // One level: diff --git a/src/test/ui/or-patterns/consistent-bindings.stderr b/src/test/ui/or-patterns/consistent-bindings.stderr index 433a02dfb3139..bb8e90af5f202 100644 --- a/src/test/ui/or-patterns/consistent-bindings.stderr +++ b/src/test/ui/or-patterns/consistent-bindings.stderr @@ -1,13 +1,5 @@ -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/consistent-bindings.rs:5:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/consistent-bindings.rs:44:9 + --> $DIR/consistent-bindings.rs:43:9 | LL | let () = 0; | ^^ expected integer, found `()` diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs index 8b0be2e7a66b4..2e8baf978e251 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs @@ -1,14 +1,11 @@ #![feature(or_patterns)] - -#![allow(incomplete_features)] #![deny(unreachable_patterns)] // We wrap patterns in a tuple because top-level or-patterns are special-cased for now. fn main() { // Get the fatal error out of the way match (0u8,) { - (0 | _,) => {} - //~^ ERROR or-patterns are not fully implemented yet + (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet } match (0u8, 0u8) { @@ -17,7 +14,7 @@ fn main() { } match ((0u8,),) { //~^ ERROR non-exhaustive patterns: `((4u8..=std::u8::MAX))` - ((0 | 1,) | (2 | 3,),) => {}, + ((0 | 1,) | (2 | 3,),) => {} } match (Some(0u8),) { //~^ ERROR non-exhaustive patterns: `(Some(2u8..=std::u8::MAX))` diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr index e6aa157d278c8..7fbd846a22f2b 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `(2u8..=std::u8::MAX, _)` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:14:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:13:11 | LL | match (0u8, 0u8) { | ^^^^^^^^^^ pattern `(2u8..=std::u8::MAX, _)` not covered @@ -7,7 +7,7 @@ LL | match (0u8, 0u8) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((4u8..=std::u8::MAX))` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:18:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:17:11 | LL | match ((0u8,),) { | ^^^^^^^^^ pattern `((4u8..=std::u8::MAX))` not covered @@ -15,7 +15,7 @@ LL | match ((0u8,),) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(Some(2u8..=std::u8::MAX))` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:22:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:21:11 | LL | match (Some(0u8),) { | ^^^^^^^^^^^^ pattern `(Some(2u8..=std::u8::MAX))` not covered @@ -23,7 +23,7 @@ LL | match (Some(0u8),) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-non-exhaustive.rs:10:10 + --> $DIR/exhaustiveness-non-exhaustive.rs:9:10 | LL | (0 | _,) => {} | ^^^^^ diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.rs b/src/test/ui/or-patterns/exhaustiveness-pass.rs index f0dc3447f3154..9b62810d29db9 100644 --- a/src/test/ui/or-patterns/exhaustiveness-pass.rs +++ b/src/test/ui/or-patterns/exhaustiveness-pass.rs @@ -1,14 +1,11 @@ #![feature(or_patterns)] - -#![allow(incomplete_features)] #![deny(unreachable_patterns)] // We wrap patterns in a tuple because top-level or-patterns are special-cased for now. fn main() { // Get the fatal error out of the way match (0,) { - (0 | _,) => {} - //~^ ERROR or-patterns are not fully implemented yet + (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet } match (0,) { @@ -27,11 +24,11 @@ fn main() { (Some(2..=255),) => {} } match ((0,),) { - ((0 | 1,) | (2 | 3,),) => {}, - ((_,),) => {}, + ((0 | 1,) | (2 | 3,),) => {} + ((_,),) => {} } match (&[0u8][..],) { - ([] | [0 | 1..=255] | [_, ..],) => {}, + ([] | [0 | 1..=255] | [_, ..],) => {} } match ((0, 0),) { diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.stderr b/src/test/ui/or-patterns/exhaustiveness-pass.stderr index 1f4278c4b8098..dc5a4186ac700 100644 --- a/src/test/ui/or-patterns/exhaustiveness-pass.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-pass.stderr @@ -1,5 +1,5 @@ error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-pass.rs:10:10 + --> $DIR/exhaustiveness-pass.rs:9:10 | LL | (0 | _,) => {} | ^^^^^ diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 81bc1176f572e..dd1c16f500028 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -1,14 +1,11 @@ #![feature(or_patterns)] - -#![allow(incomplete_features)] #![deny(unreachable_patterns)] // We wrap patterns in a tuple because top-level or-patterns are special-cased for now. fn main() { // Get the fatal error out of the way match (0u8,) { - (0 | _,) => {} - //~^ ERROR or-patterns are not fully implemented yet + (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet } match (0u8,) { @@ -29,9 +26,9 @@ fn main() { } match (0u8, 0u8) { (1 | 2, 3 | 4) => {} - (1, 3) => {} //~ ERROR unreachable pattern - (1, 4) => {} //~ ERROR unreachable pattern - (2, 4) => {} //~ ERROR unreachable pattern + (1, 3) => {} //~ ERROR unreachable pattern + (1, 4) => {} //~ ERROR unreachable pattern + (2, 4) => {} //~ ERROR unreachable pattern (2 | 1, 4) => {} //~ ERROR unreachable pattern (1, 5 | 6) => {} (1, 4 | 5) => {} //~ ERROR unreachable pattern @@ -40,18 +37,17 @@ fn main() { match (Some(0u8),) { (None | Some(1 | 2),) => {} (Some(1),) => {} //~ ERROR unreachable pattern - (None,) => {} //~ ERROR unreachable pattern + (None,) => {} //~ ERROR unreachable pattern _ => {} } match ((0u8,),) { - ((1 | 2,) | (3 | 4,),) => {}, - ((1..=4,),) => {}, //~ ERROR unreachable pattern - _ => {}, + ((1 | 2,) | (3 | 4,),) => {} + ((1..=4,),) => {} //~ ERROR unreachable pattern + _ => {} } match (0,) { - (1 - | 1,) => {} //~ ERROR unreachable + (1 | 1,) => {} //~ ERROR unreachable _ => {} } match [0; 2] { diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 7f7bb929a0d27..1f07c27afad9c 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -1,107 +1,107 @@ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:16:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:15:9 | LL | (1,) => {} | ^^^^ | note: the lint level is defined here - --> $DIR/exhaustiveness-unreachable-pattern.rs:4:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:21:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:20:9 | LL | (2,) => {} | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:27:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:26:9 | LL | (1 | 2,) => {} | ^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:32:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:31:9 | LL | (1, 3) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:33:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:32:9 | LL | (1, 4) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:34:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:33:9 | LL | (2, 4) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:35:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:34:9 | LL | (2 | 1, 4) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:37:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:36:9 | LL | (1, 4 | 5) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:42:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:41:9 | LL | (Some(1),) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:43:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:42:9 | LL | (None,) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:48:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:47:9 | LL | ((1..=4,),) => {}, | ^^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:54:12 + --> $DIR/exhaustiveness-unreachable-pattern.rs:53:12 | LL | | 1,) => {} | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:61:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:60:15 | LL | | 0] => {} | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:59:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:58:15 | LL | | 0 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:69:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:68:10 | LL | [1 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:75:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:74:14 | LL | Some(0 | ^ error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-unreachable-pattern.rs:10:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:9:10 | LL | (0 | _,) => {} | ^^^^^ diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.rs b/src/test/ui/or-patterns/feature-gate-const-fn.rs index d73dcf2666648..d21cf3dc72c99 100644 --- a/src/test/ui/or-patterns/feature-gate-const-fn.rs +++ b/src/test/ui/or-patterns/feature-gate-const-fn.rs @@ -1,5 +1,4 @@ #![feature(or_patterns)] -#![allow(incomplete_features)] const fn foo((Ok(a) | Err(a)): Result) { //~^ ERROR or-pattern is not allowed in a `const fn` diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.stderr b/src/test/ui/or-patterns/feature-gate-const-fn.stderr index 26143d2f19d33..112bc62517260 100644 --- a/src/test/ui/or-patterns/feature-gate-const-fn.stderr +++ b/src/test/ui/or-patterns/feature-gate-const-fn.stderr @@ -1,5 +1,5 @@ error[E0658]: or-pattern is not allowed in a `const fn` - --> $DIR/feature-gate-const-fn.rs:4:15 + --> $DIR/feature-gate-const-fn.rs:3:15 | LL | const fn foo((Ok(a) | Err(a)): Result) { | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | const fn foo((Ok(a) | Err(a)): Result) { = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: or-pattern is not allowed in a `const fn` - --> $DIR/feature-gate-const-fn.rs:7:9 + --> $DIR/feature-gate-const-fn.rs:6:9 | LL | let Ok(y) | Err(y) = x; | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let Ok(y) | Err(y) = x; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: or-pattern is not allowed in a `const` - --> $DIR/feature-gate-const-fn.rs:13:9 + --> $DIR/feature-gate-const-fn.rs:12:9 | LL | let Ok(y) | Err(y) = x; | ^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let Ok(y) | Err(y) = x; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: or-pattern is not allowed in a `static` - --> $DIR/feature-gate-const-fn.rs:19:9 + --> $DIR/feature-gate-const-fn.rs:18:9 | LL | let Ok(y) | Err(y) = x; | ^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | let Ok(y) | Err(y) = x; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: or-pattern is not allowed in a `static mut` - --> $DIR/feature-gate-const-fn.rs:25:9 + --> $DIR/feature-gate-const-fn.rs:24:9 | LL | let Ok(y) | Err(y) = x; | ^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let Ok(y) | Err(y) = x; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0658]: or-pattern is not allowed in a `const` - --> $DIR/feature-gate-const-fn.rs:32:13 + --> $DIR/feature-gate-const-fn.rs:31:13 | LL | let Ok(y) | Err(y) = x; | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/or-patterns/inconsistent-modes.rs b/src/test/ui/or-patterns/inconsistent-modes.rs index 44836893ea2b2..28b5f0c02fef4 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.rs +++ b/src/test/ui/or-patterns/inconsistent-modes.rs @@ -1,8 +1,6 @@ // This test ensures that or patterns require binding mode consistency across arms. #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete - #![allow(non_camel_case_types)] fn main() { // One level: diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index 7c1638ff94d0f..c329f90596091 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -1,5 +1,5 @@ error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:9:25 + --> $DIR/inconsistent-modes.rs:7:25 | LL | let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0); | - ^ bound in different ways @@ -7,7 +7,7 @@ LL | let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0); | first binding error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:11:29 + --> $DIR/inconsistent-modes.rs:9:29 | LL | let Ok(ref mut a) | Err(a): Result = Ok(0); | - ^ bound in different ways @@ -15,25 +15,25 @@ LL | let Ok(ref mut a) | Err(a): Result = Ok(0); | first binding error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:13:33 + --> $DIR/inconsistent-modes.rs:11:33 | LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); | - first binding ^ bound in different ways error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:16:39 + --> $DIR/inconsistent-modes.rs:14:39 | LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); | - first binding ^ bound in different ways error[E0409]: variable `b` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:16:46 + --> $DIR/inconsistent-modes.rs:14:46 | LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); | - first binding ^ bound in different ways error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:22:38 + --> $DIR/inconsistent-modes.rs:20:38 | LL | let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0); | - ^ bound in different ways @@ -41,23 +41,15 @@ LL | let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0); | first binding error[E0409]: variable `a` is bound in inconsistent ways within the same match arm - --> $DIR/inconsistent-modes.rs:26:34 + --> $DIR/inconsistent-modes.rs:24:34 | LL | let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1); | - ^ bound in different ways | | | first binding -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/inconsistent-modes.rs:3:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/inconsistent-modes.rs:13:25 + --> $DIR/inconsistent-modes.rs:11:25 | LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); | ^^^^^^^^^ -------------------- expected due to this @@ -68,7 +60,7 @@ LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); found type `&mut &mut u8` error[E0308]: mismatched types - --> $DIR/inconsistent-modes.rs:16:31 + --> $DIR/inconsistent-modes.rs:14:31 | LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); | ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>` diff --git a/src/test/ui/or-patterns/missing-bindings.rs b/src/test/ui/or-patterns/missing-bindings.rs index b065028e7a5a4..67cf52fa8c418 100644 --- a/src/test/ui/or-patterns/missing-bindings.rs +++ b/src/test/ui/or-patterns/missing-bindings.rs @@ -3,8 +3,6 @@ // edition:2018 #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete - #![allow(non_camel_case_types)] fn main() {} diff --git a/src/test/ui/or-patterns/missing-bindings.stderr b/src/test/ui/or-patterns/missing-bindings.stderr index c73af7a42eec0..57270e4412351 100644 --- a/src/test/ui/or-patterns/missing-bindings.stderr +++ b/src/test/ui/or-patterns/missing-bindings.stderr @@ -1,5 +1,5 @@ error[E0408]: variable `beta` is not bound in all patterns - --> $DIR/missing-bindings.rs:22:9 + --> $DIR/missing-bindings.rs:20:9 | LL | let alpha | beta | charlie = alpha; | ^^^^^ ---- ^^^^^^^ pattern doesn't bind `beta` @@ -8,7 +8,7 @@ LL | let alpha | beta | charlie = alpha; | pattern doesn't bind `beta` error[E0408]: variable `beta` is not bound in all patterns - --> $DIR/missing-bindings.rs:24:14 + --> $DIR/missing-bindings.rs:22:14 | LL | Some(alpha | beta) => {} | ^^^^^ ---- variable not in all patterns @@ -16,7 +16,7 @@ LL | Some(alpha | beta) => {} | pattern doesn't bind `beta` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:36:19 + --> $DIR/missing-bindings.rs:34:19 | LL | let A(a, _) | _ = X; | - ^ pattern doesn't bind `a` @@ -24,7 +24,7 @@ LL | let A(a, _) | _ = X; | variable not in all patterns error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:37:9 + --> $DIR/missing-bindings.rs:35:9 | LL | let _ | B(a) = X; | ^ - variable not in all patterns @@ -32,7 +32,7 @@ LL | let _ | B(a) = X; | pattern doesn't bind `a` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:38:9 + --> $DIR/missing-bindings.rs:36:9 | LL | let A(..) | B(a) = X; | ^^^^^ - variable not in all patterns @@ -40,7 +40,7 @@ LL | let A(..) | B(a) = X; | pattern doesn't bind `a` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:39:19 + --> $DIR/missing-bindings.rs:37:19 | LL | let A(a, _) | B(_) = X; | - ^^^^ pattern doesn't bind `a` @@ -48,7 +48,7 @@ LL | let A(a, _) | B(_) = X; | variable not in all patterns error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:40:19 + --> $DIR/missing-bindings.rs:38:19 | LL | let A(_, a) | B(_) = X; | - ^^^^ pattern doesn't bind `a` @@ -56,7 +56,7 @@ LL | let A(_, a) | B(_) = X; | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:41:19 + --> $DIR/missing-bindings.rs:39:19 | LL | let A(a, b) | B(a) = X; | - ^^^^ pattern doesn't bind `b` @@ -64,7 +64,7 @@ LL | let A(a, b) | B(a) = X; | variable not in all patterns error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:9 + --> $DIR/missing-bindings.rs:43:9 | LL | let A(A(..) | B(_), _) | B(a) = Y; | ^^^^^^^^^^^^^^^^^^ - variable not in all patterns @@ -72,7 +72,7 @@ LL | let A(A(..) | B(_), _) | B(a) = Y; | pattern doesn't bind `a` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:46:11 + --> $DIR/missing-bindings.rs:44:11 | LL | let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y; | ^^^^^ - variable not in all patterns @@ -80,7 +80,7 @@ LL | let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y; | pattern doesn't bind `a` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:21 + --> $DIR/missing-bindings.rs:46:21 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `a` @@ -88,7 +88,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:21 + --> $DIR/missing-bindings.rs:46:21 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `b` @@ -96,7 +96,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `c` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:11 + --> $DIR/missing-bindings.rs:46:11 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | ^^^^^^^ - variable not in all patterns @@ -104,7 +104,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | pattern doesn't bind `c` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:32 + --> $DIR/missing-bindings.rs:46:32 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `a` @@ -112,7 +112,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:32 + --> $DIR/missing-bindings.rs:46:32 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `b` @@ -120,7 +120,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `c` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:32 + --> $DIR/missing-bindings.rs:46:32 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `c` @@ -128,7 +128,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `d` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:32 + --> $DIR/missing-bindings.rs:46:32 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | - ^^^^ pattern doesn't bind `d` @@ -136,7 +136,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | variable not in all patterns error[E0408]: variable `e` is not bound in all patterns - --> $DIR/missing-bindings.rs:48:9 + --> $DIR/missing-bindings.rs:46:9 | LL | let A(A(a, b) | B(c), d) | B(e) = Y; | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns @@ -144,7 +144,7 @@ LL | let A(A(a, b) | B(c), d) | B(e) = Y; | pattern doesn't bind `e` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:64:29 + --> $DIR/missing-bindings.rs:62:29 | LL | Ok(a) | Err(_), | - ^^^^^^ pattern doesn't bind `a` @@ -152,7 +152,7 @@ LL | Ok(a) | Err(_), | variable not in all patterns error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:72:21 + --> $DIR/missing-bindings.rs:70:21 | LL | A(_, a) | | - variable not in all patterns @@ -160,7 +160,7 @@ LL | B(b), | ^^^^ pattern doesn't bind `a` error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:71:21 + --> $DIR/missing-bindings.rs:69:21 | LL | A(_, a) | | ^^^^^^^ pattern doesn't bind `b` @@ -168,7 +168,7 @@ LL | B(b), | - variable not in all patterns error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:75:17 + --> $DIR/missing-bindings.rs:73:17 | LL | A(_, a) | | - variable not in all patterns @@ -177,7 +177,7 @@ LL | B(_) | ^^^^ pattern doesn't bind `a` error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:75:17 + --> $DIR/missing-bindings.rs:73:17 | LL | B(b), | - variable not in all patterns @@ -186,7 +186,7 @@ LL | B(_) | ^^^^ pattern doesn't bind `b` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:79:13 + --> $DIR/missing-bindings.rs:77:13 | LL | B(Ok(a) | Err(a)) | - variable not in all patterns @@ -198,7 +198,7 @@ LL | V3(c), | ^^^^^ pattern doesn't bind `a` error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:60:13 + --> $DIR/missing-bindings.rs:58:13 | LL | / V1( LL | | @@ -216,7 +216,7 @@ LL | V3(c), | ^^^^^ pattern doesn't bind `b` error[E0408]: variable `c` is not bound in all patterns - --> $DIR/missing-bindings.rs:60:13 + --> $DIR/missing-bindings.rs:58:13 | LL | / V1( LL | | @@ -237,14 +237,6 @@ LL | | ) | LL | V3(c), | - variable not in all patterns -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/missing-bindings.rs:5:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error: aborting due to 26 previous errors For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.rs b/src/test/ui/or-patterns/multiple-pattern-typo.rs index e308c0adb4eb8..702c9573741e7 100644 --- a/src/test/ui/or-patterns/multiple-pattern-typo.rs +++ b/src/test/ui/or-patterns/multiple-pattern-typo.rs @@ -1,5 +1,4 @@ #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash fn main() { let x = 3; diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.stderr b/src/test/ui/or-patterns/multiple-pattern-typo.stderr index c71c760b1e303..cb32068ec0d5e 100644 --- a/src/test/ui/or-patterns/multiple-pattern-typo.stderr +++ b/src/test/ui/or-patterns/multiple-pattern-typo.stderr @@ -1,5 +1,5 @@ error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:8:15 + --> $DIR/multiple-pattern-typo.rs:7:15 | LL | 1 | 2 || 3 => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -7,7 +7,7 @@ LL | 1 | 2 || 3 => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:13:16 + --> $DIR/multiple-pattern-typo.rs:12:16 | LL | (1 | 2 || 3) => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -15,7 +15,7 @@ LL | (1 | 2 || 3) => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:18:16 + --> $DIR/multiple-pattern-typo.rs:17:16 | LL | (1 | 2 || 3,) => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -23,7 +23,7 @@ LL | (1 | 2 || 3,) => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:25:18 + --> $DIR/multiple-pattern-typo.rs:24:18 | LL | TS(1 | 2 || 3) => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -31,7 +31,7 @@ LL | TS(1 | 2 || 3) => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:32:23 + --> $DIR/multiple-pattern-typo.rs:31:23 | LL | NS { f: 1 | 2 || 3 } => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -39,7 +39,7 @@ LL | NS { f: 1 | 2 || 3 } => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:37:16 + --> $DIR/multiple-pattern-typo.rs:36:16 | LL | [1 | 2 || 3] => (), | - ^^ help: use a single `|` to separate multiple alternative patterns: `|` @@ -47,18 +47,10 @@ LL | [1 | 2 || 3] => (), | while parsing this or-pattern starting here error: unexpected token `||` after pattern - --> $DIR/multiple-pattern-typo.rs:42:9 + --> $DIR/multiple-pattern-typo.rs:41:9 | LL | || 1 | 2 | 3 => (), | ^^ help: use a single `|` to separate multiple alternative patterns: `|` -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/multiple-pattern-typo.rs:1:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error: aborting due to 7 previous errors diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs index ce6836f30f946..d23220056524b 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -2,7 +2,6 @@ // This is not a semantic test. We only test parsing. #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash fn main() {} diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr index e77d92e8b07d9..6cbb59dc22031 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -1,53 +1,53 @@ error: an or-pattern parameter must be wrapped in parenthesis - --> $DIR/or-patterns-syntactic-fail.rs:28:13 + --> $DIR/or-patterns-syntactic-fail.rs:27:13 | LL | fn fun1(A | B: E) {} | ^^^^^ help: wrap the pattern in parenthesis: `(A | B)` error: a leading `|` is not allowed in a parameter pattern - --> $DIR/or-patterns-syntactic-fail.rs:30:13 + --> $DIR/or-patterns-syntactic-fail.rs:29:13 | LL | fn fun2(| A | B: E) {} | ^ help: remove the `|` error: an or-pattern parameter must be wrapped in parenthesis - --> $DIR/or-patterns-syntactic-fail.rs:30:15 + --> $DIR/or-patterns-syntactic-fail.rs:29:15 | LL | fn fun2(| A | B: E) {} | ^^^^^ help: wrap the pattern in parenthesis: `(A | B)` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:41:11 + --> $DIR/or-patterns-syntactic-fail.rs:40:11 | LL | let ( | A | B) = E::A; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:42:11 + --> $DIR/or-patterns-syntactic-fail.rs:41:11 | LL | let ( | A | B,) = (E::B,); | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:43:11 + --> $DIR/or-patterns-syntactic-fail.rs:42:11 | LL | let [ | A | B ] = [E::A]; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:44:13 + --> $DIR/or-patterns-syntactic-fail.rs:43:13 | LL | let TS( | A | B ); | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:45:17 + --> $DIR/or-patterns-syntactic-fail.rs:44:17 | LL | let NS { f: | A | B }; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:47:11 + --> $DIR/or-patterns-syntactic-fail.rs:46:11 | LL | let ( || A | B) = E::A; | ^^ help: remove the `||` @@ -55,7 +55,7 @@ LL | let ( || A | B) = E::A; = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:48:11 + --> $DIR/or-patterns-syntactic-fail.rs:47:11 | LL | let [ || A | B ] = [E::A]; | ^^ help: remove the `||` @@ -63,7 +63,7 @@ LL | let [ || A | B ] = [E::A]; = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:49:13 + --> $DIR/or-patterns-syntactic-fail.rs:48:13 | LL | let TS( || A | B ); | ^^ help: remove the `||` @@ -71,7 +71,7 @@ LL | let TS( || A | B ); = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:50:17 + --> $DIR/or-patterns-syntactic-fail.rs:49:17 | LL | let NS { f: || A | B }; | ^^ help: remove the `||` @@ -79,7 +79,7 @@ LL | let NS { f: || A | B }; = note: alternatives in or-patterns are separated with `|`, not `||` error: no rules expected the token `|` - --> $DIR/or-patterns-syntactic-fail.rs:14:15 + --> $DIR/or-patterns-syntactic-fail.rs:13:15 | LL | macro_rules! accept_pat { | ----------------------- when calling this macro @@ -88,7 +88,7 @@ LL | accept_pat!(p | q); | ^ no rules expected this token in macro call error: no rules expected the token `|` - --> $DIR/or-patterns-syntactic-fail.rs:15:13 + --> $DIR/or-patterns-syntactic-fail.rs:14:13 | LL | macro_rules! accept_pat { | ----------------------- when calling this macro @@ -96,16 +96,8 @@ LL | macro_rules! accept_pat { LL | accept_pat!(| p | q); | ^ no rules expected this token in macro call -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/or-patterns-syntactic-fail.rs:4:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error[E0369]: no implementation for `E | ()` - --> $DIR/or-patterns-syntactic-fail.rs:24:22 + --> $DIR/or-patterns-syntactic-fail.rs:23:22 | LL | let _ = |A | B: E| (); | ----^ -- () @@ -115,7 +107,7 @@ LL | let _ = |A | B: E| (); = note: an implementation of `std::ops::BitOr` might be missing for `E` error[E0308]: mismatched types - --> $DIR/or-patterns-syntactic-fail.rs:52:36 + --> $DIR/or-patterns-syntactic-fail.rs:51:36 | LL | let recovery_witness: String = 0; | ------ ^ diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs index 73c1477c281a8..5fe72caf9c1ff 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs @@ -3,7 +3,7 @@ // check-pass -#![feature(or_patterns)] //~ WARNING the feature `or_patterns` is incomplete +#![feature(or_patterns)] fn main() {} diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr deleted file mode 100644 index 3145a2e9f2a6e..0000000000000 --- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/or-patterns-syntactic-pass.rs:6:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs index 89ea2d5181945..e8b5b492b7738 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.rs @@ -3,7 +3,6 @@ #![feature(bindings_after_at)] #![feature(or_patterns)] -//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash fn main() { fn f(a @ a @ a: ()) {} diff --git a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr index c568d2a3aa2b8..cba17d82e93c5 100644 --- a/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr +++ b/src/test/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr @@ -1,71 +1,63 @@ error[E0415]: identifier `a` is bound more than once in this parameter list - --> $DIR/pat-at-same-name-both.rs:9:14 + --> $DIR/pat-at-same-name-both.rs:8:14 | LL | fn f(a @ a @ a: ()) {} | ^ used as parameter more than once error[E0415]: identifier `a` is bound more than once in this parameter list - --> $DIR/pat-at-same-name-both.rs:9:18 + --> $DIR/pat-at-same-name-both.rs:8:18 | LL | fn f(a @ a @ a: ()) {} | ^ used as parameter more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:14:20 + --> $DIR/pat-at-same-name-both.rs:13:20 | LL | Ok(a @ b @ a) | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:16:23 + --> $DIR/pat-at-same-name-both.rs:15:23 | LL | | Err(a @ b @ a) | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:21:13 + --> $DIR/pat-at-same-name-both.rs:20:13 | LL | let a @ a @ a = (); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:21:17 + --> $DIR/pat-at-same-name-both.rs:20:17 | LL | let a @ a @ a = (); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:24:21 + --> $DIR/pat-at-same-name-both.rs:23:21 | LL | let ref a @ ref a = (); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:26:29 + --> $DIR/pat-at-same-name-both.rs:25:29 | LL | let ref mut a @ ref mut a = (); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:29:17 + --> $DIR/pat-at-same-name-both.rs:28:17 | LL | let a @ (Ok(a) | Err(a)) = Ok(()); | ^ used in a pattern more than once error[E0416]: identifier `a` is bound more than once in the same pattern - --> $DIR/pat-at-same-name-both.rs:29:26 + --> $DIR/pat-at-same-name-both.rs:28:26 | LL | let a @ (Ok(a) | Err(a)) = Ok(()); | ^ used in a pattern more than once -warning: the feature `or_patterns` is incomplete and may cause the compiler to crash - --> $DIR/pat-at-same-name-both.rs:5:12 - | -LL | #![feature(or_patterns)] - | ^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - error: aborting due to 10 previous errors Some errors have detailed explanations: E0415, E0416. From eecee76652dafe25f2cd6453f33bf4c298e84463 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 12:25:53 +0000 Subject: [PATCH 0761/1253] Generate prebinding blocks lazily --- src/librustc_mir_build/build/matches/mod.rs | 217 +++++++++----------- 1 file changed, 100 insertions(+), 117 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index ad55a9fb7b81a..1eb0c2cb3e65e 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -26,7 +26,6 @@ mod simplify; mod test; mod util; -use itertools::Itertools; use std::convert::TryFrom; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -66,12 +65,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// We generate MIR in the following steps: /// /// 1. Evaluate the scrutinee and add the fake read of it ([Builder::lower_scrutinee]). - /// 2. Create the prebinding and otherwise blocks ([Builder::create_match_candidates]). - /// 3. Create the decision tree ([Builder::lower_match_tree]). - /// 4. Determine the fake borrows that are needed from the places that were + /// 2. Create the decision tree ([Builder::lower_match_tree]). + /// 3. Determine the fake borrows that are needed from the places that were /// matched against and create the required temporaries for them /// ([Builder::calculate_fake_borrows]). - /// 5. Create everything else: the guards and the arms ([Builder::lower_match_arms]). + /// 4. Create everything else: the guards and the arms ([Builder::lower_match_arms]). /// /// ## False edges /// @@ -148,13 +146,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee: &Place<'tcx>, arms: &'pat [Arm<'tcx>], ) -> Vec<(&'pat Arm<'tcx>, Vec>)> { - let candidate_count = arms.iter().map(|c| c.top_pats_hack().len()).sum::(); - let pre_binding_blocks: Vec<_> = - (0..candidate_count).map(|_| self.cfg.start_new_block()).collect(); - - let mut candidate_pre_binding_blocks = pre_binding_blocks.iter(); - let mut next_candidate_pre_binding_blocks = pre_binding_blocks.iter().skip(1); - // Assemble a list of candidates: there is one candidate per pattern, // which means there may be more than one candidate *per arm*. arms.iter() @@ -163,21 +154,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arm_candidates: Vec<_> = arm .top_pats_hack() .iter() - .zip(candidate_pre_binding_blocks.by_ref()) - .map(|(pattern, pre_binding_block)| Candidate { + .map(|pattern| Candidate { span: pattern.span, + has_guard: arm_has_guard, match_pairs: smallvec![MatchPair::new(*scrutinee, pattern)], bindings: vec![], ascriptions: vec![], - otherwise_block: if arm_has_guard { - Some(self.cfg.start_new_block()) - } else { - None - }, - pre_binding_block: *pre_binding_block, - next_candidate_pre_binding_block: next_candidate_pre_binding_blocks - .next() - .copied(), + otherwise_block: None, + pre_binding_block: None, + next_candidate_pre_binding_block: None, }) .collect(); (arm, arm_candidates) @@ -203,16 +188,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // them. let mut fake_borrows = if match_has_guard { Some(FxHashSet::default()) } else { None }; + let mut otherwise = None; + // This will generate code to test scrutinee_place and // branch to the appropriate arm block self.match_candidates( scrutinee_span, - &mut Some(block), - None, + block, + &mut otherwise, &mut candidates, &mut fake_borrows, ); + if let Some(otherwise_block) = otherwise { + let source_info = self.source_info(scrutinee_span); + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + } + + let mut next_prebinding_block = None; + + for candidate in candidates.iter_mut().rev() { + candidate.next_candidate_pre_binding_block = next_prebinding_block; + next_prebinding_block = candidate.pre_binding_block; + } + if let Some(ref borrows) = fake_borrows { self.calculate_fake_borrows(borrows, scrutinee_span) } else { @@ -427,13 +426,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // create a dummy candidate let mut candidate = Candidate { span: irrefutable_pat.span, + has_guard: false, match_pairs: smallvec![MatchPair::new(*initializer, &irrefutable_pat)], bindings: vec![], ascriptions: vec![], // since we don't call `match_candidates`, next fields are unused otherwise_block: None, - pre_binding_block: block, + pre_binding_block: None, next_candidate_pre_binding_block: None, }; @@ -645,6 +645,8 @@ crate struct Candidate<'pat, 'tcx> { // span of the original pattern that gave rise to this candidate span: Span, + has_guard: bool, + // all of these must be satisfied... match_pairs: SmallVec<[MatchPair<'pat, 'tcx>; 1]>, @@ -658,7 +660,7 @@ crate struct Candidate<'pat, 'tcx> { otherwise_block: Option, // ...and the blocks for add false edges between candidates - pre_binding_block: BasicBlock, + pre_binding_block: Option, next_candidate_pre_binding_block: Option, } @@ -758,13 +760,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// which of these candidates, if any, is the correct one. The /// candidates are sorted such that the first item in the list /// has the highest priority. When a candidate is found to match - /// the value, we will generate a branch to the appropriate + /// the value, we will set and generate a branch to the appropriate /// prebinding block. /// /// If we find that *NONE* of the candidates apply, we branch to the - /// `otherwise_block`. In principle, this means that the input list was not - /// exhaustive, though at present we sometimes are not smart enough to - /// recognize all exhaustive inputs. + /// `otherwise_block`, setting it to `Some` if required. In principle, this + /// means that the input list was not exhaustive, though at present we + /// sometimes are not smart enough to recognize all exhaustive inputs. /// /// It might be surprising that the input can be inexhaustive. /// Indeed, initially, it is not, because all matches are @@ -778,8 +780,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn match_candidates<'pat>( &mut self, span: Span, - start_block: &mut Option, - otherwise_block: Option, + start_block: BasicBlock, + otherwise_block: &mut Option, candidates: &mut [&mut Candidate<'pat, 'tcx>], fake_borrows: &mut Option>>, ) { @@ -802,7 +804,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("match_candidates: {:?} candidates fully matched", fully_matched); let (matched_candidates, unmatched_candidates) = candidates.split_at_mut(fully_matched); - let block: BasicBlock = if !matched_candidates.is_empty() { + let block = if !matched_candidates.is_empty() { let otherwise_block = self.select_matched_candidates(matched_candidates, start_block, fake_borrows); @@ -816,7 +818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.start_new_block() } } else { - *start_block.get_or_insert_with(|| self.cfg.start_new_block()) + start_block }; // If there are no candidates that still need testing, we're @@ -824,9 +826,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // never reach this point. if unmatched_candidates.is_empty() { let source_info = self.source_info(span); - match otherwise_block { - Some(otherwise) => self.cfg.goto(block, source_info, otherwise), - None => self.cfg.terminate(block, source_info, TerminatorKind::Unreachable), + if let Some(otherwise) = *otherwise_block { + self.cfg.goto(block, source_info, otherwise); + } else { + *otherwise_block = Some(block); } return; } @@ -856,7 +859,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn select_matched_candidates( &mut self, matched_candidates: &mut [&mut Candidate<'_, 'tcx>], - start_block: &mut Option, + start_block: BasicBlock, fake_borrows: &mut Option>>, ) -> Option { debug_assert!( @@ -899,66 +902,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fully_matched_with_guard = matched_candidates .iter() - .position(|c| c.otherwise_block.is_none()) + .position(|c| !c.has_guard) .unwrap_or(matched_candidates.len() - 1); let (reachable_candidates, unreachable_candidates) = matched_candidates.split_at_mut(fully_matched_with_guard + 1); - let first_candidate = &reachable_candidates[0]; - let first_prebinding_block = first_candidate.pre_binding_block; + let mut next_prebinding = start_block; - // `goto -> first_prebinding_block` from the `start_block` if there is one. - if let Some(start_block) = *start_block { - let source_info = self.source_info(first_candidate.span); - self.cfg.goto(start_block, source_info, first_prebinding_block); - } else { - *start_block = Some(first_prebinding_block); - } - - for (first_candidate, second_candidate) in reachable_candidates.iter().tuple_windows() { - let source_info = self.source_info(first_candidate.span); - if let Some(otherwise_block) = first_candidate.otherwise_block { - self.false_edges( - otherwise_block, - second_candidate.pre_binding_block, - first_candidate.next_candidate_pre_binding_block, - source_info, - ); - } else { - bug!("candidate other than the last has no guard"); + for candidate in reachable_candidates.iter_mut() { + assert!(candidate.otherwise_block.is_none()); + assert!(candidate.pre_binding_block.is_none()); + candidate.pre_binding_block = Some(next_prebinding); + if candidate.has_guard { + next_prebinding = self.cfg.start_new_block(); + candidate.otherwise_block = Some(next_prebinding); } } - debug!("match_candidates: add false edges for unreachable {:?}", unreachable_candidates); + debug!( + "match_candidates: add pre_binding_blocks for unreachable {:?}", + unreachable_candidates, + ); for candidate in unreachable_candidates { - if let Some(otherwise) = candidate.otherwise_block { - let source_info = self.source_info(candidate.span); - let unreachable = self.cfg.start_new_block(); - self.false_edges( - otherwise, - unreachable, - candidate.next_candidate_pre_binding_block, - source_info, - ); - self.cfg.terminate(unreachable, source_info, TerminatorKind::Unreachable); - } + assert!(candidate.pre_binding_block.is_none()); + candidate.pre_binding_block = Some(self.cfg.start_new_block()); } - let last_candidate = reachable_candidates.last().unwrap(); - if let Some(otherwise) = last_candidate.otherwise_block { - let source_info = self.source_info(last_candidate.span); - let block = self.cfg.start_new_block(); - self.false_edges( - otherwise, - block, - last_candidate.next_candidate_pre_binding_block, - source_info, - ); - Some(block) - } else { - None - } + reachable_candidates.last_mut().unwrap().otherwise_block } /// This is the most subtle part of the matching algorithm. At @@ -1078,7 +1049,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, mut candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], block: BasicBlock, - mut otherwise_block: Option, + otherwise_block: &mut Option, fake_borrows: &mut Option>>, ) { // extract the match-pair from the highest priority candidate @@ -1150,49 +1121,49 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // improves the speed of llvm when optimizing long string literal // matches let make_target_blocks = move |this: &mut Self| -> Vec { + // The block that we should branch to if none of the + // `target_candidates` match. This is either the block where we + // start matching the untested candidates if there are any, + // otherwise it's the `otherwise_block`. + let remainder_start = &mut None; + let remainder_start = + if candidates.is_empty() { &mut *otherwise_block } else { remainder_start }; + // For each outcome of test, process the candidates that still // apply. Collect a list of blocks where control flow will // branch if one of the `target_candidate` sets is not // exhaustive. - if !candidates.is_empty() { - let remainder_start = &mut None; - this.match_candidates( - span, - remainder_start, - otherwise_block, - candidates, - fake_borrows, - ); - otherwise_block = Some(remainder_start.unwrap()); - }; - - target_candidates + let target_blocks: Vec<_> = target_candidates .into_iter() .map(|mut candidates| { if candidates.len() != 0 { - let candidate_start = &mut None; + let candidate_start = this.cfg.start_new_block(); this.match_candidates( span, candidate_start, - otherwise_block, + remainder_start, &mut *candidates, fake_borrows, ); - candidate_start.unwrap() + candidate_start } else { - *otherwise_block.get_or_insert_with(|| { - let unreachable = this.cfg.start_new_block(); - let source_info = this.source_info(span); - this.cfg.terminate( - unreachable, - source_info, - TerminatorKind::Unreachable, - ); - unreachable - }) + *remainder_start.get_or_insert_with(|| this.cfg.start_new_block()) } }) - .collect() + .collect(); + + if !candidates.is_empty() { + let remainder_start = remainder_start.unwrap_or_else(|| this.cfg.start_new_block()); + this.match_candidates( + span, + remainder_start, + otherwise_block, + candidates, + fake_borrows, + ); + }; + + target_blocks }; self.perform_test(block, &match_place, &test, make_target_blocks); @@ -1297,7 +1268,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let candidate_source_info = self.source_info(candidate.span); - let mut block = candidate.pre_binding_block; + let mut block = candidate.pre_binding_block.unwrap(); // If we are adding our own statements, then we need a fresh block. let create_fresh_block = candidate.next_candidate_pre_binding_block.is_some() @@ -1437,11 +1408,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(temp)); } + let otherwise_block = candidate.otherwise_block.unwrap_or_else(|| { + let unreachable = self.cfg.start_new_block(); + self.cfg.terminate(unreachable, source_info, TerminatorKind::Unreachable); + unreachable + }); + let outside_scope = self.cfg.start_new_block(); self.exit_scope( source_info.span, region_scope, otherwise_post_guard_block, - candidate.otherwise_block.unwrap(), + outside_scope, + ); + self.false_edges( + outside_scope, + otherwise_block, + candidate.next_candidate_pre_binding_block, + source_info, ); // We want to ensure that the matched candidates are bound From 64eab7750bed3d692c90b215c5a3c65030ece3b7 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 12:42:52 +0000 Subject: [PATCH 0762/1253] Don't create unnecessary block --- src/librustc_mir_build/build/matches/mod.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 1eb0c2cb3e65e..a060c8fd2a215 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -1270,13 +1270,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut block = candidate.pre_binding_block.unwrap(); - // If we are adding our own statements, then we need a fresh block. - let create_fresh_block = candidate.next_candidate_pre_binding_block.is_some() - || !candidate.bindings.is_empty() - || !candidate.ascriptions.is_empty() - || guard.is_some(); - - if create_fresh_block { + if candidate.next_candidate_pre_binding_block.is_some() { let fresh_block = self.cfg.start_new_block(); self.false_edges( block, @@ -1285,11 +1279,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate_source_info, ); block = fresh_block; - self.ascribe_types(block, &candidate.ascriptions); - } else { - return block; } + self.ascribe_types(block, &candidate.ascriptions); + // rust-lang/rust#27282: The `autoref` business deserves some // explanation here. // From 5cc4352bc4f9789d7243e79684b2943d3d9ad450 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 13:39:43 +0000 Subject: [PATCH 0763/1253] Implement general or-patterns in `match` expressions --- src/librustc_mir_build/build/matches/mod.rs | 394 ++++++++++++++---- .../build/matches/simplify.rs | 58 ++- src/librustc_mir_build/build/matches/test.rs | 6 +- src/librustc_mir_build/hair/mod.rs | 11 - 4 files changed, 381 insertions(+), 88 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index a060c8fd2a215..4ac3ced17dbb1 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -26,7 +26,9 @@ mod simplify; mod test; mod util; +use std::borrow::Borrow; use std::convert::TryFrom; +use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Generates MIR for a `match` expression. @@ -95,7 +97,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let match_has_guard = arms.iter().any(|arm| arm.guard.is_some()); let candidates = - arm_candidates.iter_mut().flat_map(|(_, candidates)| candidates).collect::>(); + arm_candidates.iter_mut().map(|(_, candidate)| candidate).collect::>(); let fake_borrow_temps = self.lower_match_tree(block, scrutinee_span, match_has_guard, candidates); @@ -145,27 +147,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, scrutinee: &Place<'tcx>, arms: &'pat [Arm<'tcx>], - ) -> Vec<(&'pat Arm<'tcx>, Vec>)> { + ) -> Vec<(&'pat Arm<'tcx>, Candidate<'pat, 'tcx>)> { // Assemble a list of candidates: there is one candidate per pattern, // which means there may be more than one candidate *per arm*. arms.iter() .map(|arm| { let arm_has_guard = arm.guard.is_some(); - let arm_candidates: Vec<_> = arm - .top_pats_hack() - .iter() - .map(|pattern| Candidate { - span: pattern.span, - has_guard: arm_has_guard, - match_pairs: smallvec![MatchPair::new(*scrutinee, pattern)], - bindings: vec![], - ascriptions: vec![], - otherwise_block: None, - pre_binding_block: None, - next_candidate_pre_binding_block: None, - }) - .collect(); - (arm, arm_candidates) + let arm_candidate = Candidate { + span: arm.pattern.span, + match_pairs: smallvec![MatchPair::new(*scrutinee, &arm.pattern),], + bindings: vec![], + ascriptions: vec![], + has_guard: arm_has_guard, + needs_otherwise_block: arm_has_guard, + otherwise_block: None, + pre_binding_block: None, + next_candidate_pre_binding_block: None, + subcandidates: vec![], + }; + (arm, arm_candidate) }) .collect() } @@ -205,11 +205,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); } - let mut next_prebinding_block = None; + let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; - for candidate in candidates.iter_mut().rev() { - candidate.next_candidate_pre_binding_block = next_prebinding_block; - next_prebinding_block = candidate.pre_binding_block; + for candidate in candidates.into_iter() { + candidate.visit_leaves(|leaf_candidate| { + if let Some(ref mut prev) = previous_candidate { + prev.next_candidate_pre_binding_block = leaf_candidate.pre_binding_block; + } + previous_candidate = Some(leaf_candidate); + }); } if let Some(ref borrows) = fake_borrows { @@ -230,7 +234,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: &Place<'tcx>, scrutinee_place: Place<'tcx>, scrutinee_span: Span, - arm_candidates: Vec<(&'_ Arm<'tcx>, Vec>)>, + arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>, outer_source_info: SourceInfo, fake_borrow_temps: Vec<(Place<'tcx>, Local)>, ) -> BlockAnd<()> { @@ -238,8 +242,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arm_end_blocks: Vec<_> = arm_candidates .into_iter() - .map(|(arm, candidates)| { - debug!("lowering arm {:?}\ncanidates = {:?}", arm, candidates); + .map(|(arm, candidate)| { + debug!("lowering arm {:?}\ncanidate = {:?}", arm, candidate); let arm_source_info = self.source_info(arm.span); let arm_scope = (arm.scope, arm_source_info); @@ -248,14 +252,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scope = this.declare_bindings( None, arm.span, - &arm.top_pats_hack()[0], + &arm.pattern, ArmHasGuard(arm.guard.is_some()), Some((Some(&scrutinee_place), scrutinee_span)), ); let arm_block = this.bind_pattern( outer_source_info, - candidates, + candidate, arm.guard.as_ref().map(|g| (g, match_scope)), &fake_borrow_temps, scrutinee_span, @@ -289,35 +293,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_pattern( &mut self, outer_source_info: SourceInfo, - mut candidates: Vec>, + candidate: Candidate<'_, 'tcx>, guard: Option<(&Guard<'tcx>, region::Scope)>, fake_borrow_temps: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, arm_scope: region::Scope, ) -> BasicBlock { - if candidates.len() == 1 { + if candidate.subcandidates.is_empty() { // Avoid generating another `BasicBlock` when we only have one // candidate. self.bind_and_guard_matched_candidate( - candidates.pop().unwrap(), + candidate, + &[], guard, fake_borrow_temps, scrutinee_span, ) } else { - let arm_block = self.cfg.start_new_block(); - for candidate in candidates { - // Avoid scheduling drops multiple times. - self.clear_top_scope(arm_scope); - let binding_end = self.bind_and_guard_matched_candidate( - candidate, - guard, - fake_borrow_temps, - scrutinee_span, - ); - self.cfg.goto(binding_end, outer_source_info, arm_block); - } - arm_block + let target_block = self.cfg.start_new_block(); + + // We keep a stack of all of the bindings and type asciptions + // from the the parent candidates that we visit, that also need to + // be bound for each candidate. + traverse_candidate( + candidate, + &mut Vec::new(), + &mut |leaf_candidate, parent_bindings| { + self.clear_top_scope(arm_scope); + let binding_end = self.bind_and_guard_matched_candidate( + leaf_candidate, + parent_bindings, + guard, + &fake_borrow_temps, + scrutinee_span, + ); + self.cfg.goto(binding_end, outer_source_info, target_block); + }, + |inner_candidate, parent_bindings| { + parent_bindings.push((inner_candidate.bindings, inner_candidate.ascriptions)); + inner_candidate.subcandidates.into_iter() + }, + |parent_bindings| { + parent_bindings.pop(); + }, + ); + + target_block } } @@ -427,6 +448,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut candidate = Candidate { span: irrefutable_pat.span, has_guard: false, + needs_otherwise_block: false, match_pairs: smallvec![MatchPair::new(*initializer, &irrefutable_pat)], bindings: vec![], ascriptions: vec![], @@ -435,6 +457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { otherwise_block: None, pre_binding_block: None, next_candidate_pre_binding_block: None, + subcandidates: vec![], }; // Simplify the candidate. Since the pattern is irrefutable, this should @@ -632,9 +655,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } PatKind::Or { ref pats } => { - for pat in pats { - self.visit_bindings(&pat, pattern_user_ty.clone(), f); - } + self.visit_bindings(&pats[0], pattern_user_ty.clone(), f); } } } @@ -642,28 +663,72 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { #[derive(Debug)] crate struct Candidate<'pat, 'tcx> { - // span of the original pattern that gave rise to this candidate + /// `Span` of the original pattern that gave rise to this candidate span: Span, + /// This `Candidate` has a guard. has_guard: bool, - // all of these must be satisfied... + /// This `Candidate` needs and otherwise block, either because it has a + /// guard or it has subcandidates. + needs_otherwise_block: bool, + + /// All of these must be satisfied... match_pairs: SmallVec<[MatchPair<'pat, 'tcx>; 1]>, - // ...these bindings established... + /// ...these bindings established... bindings: Vec>, - // ...and these types asserted... + /// ...and these types asserted... ascriptions: Vec>, - // ...and the guard must be evaluated, if false branch to Block... + /// ... and if this is non-empty, one of these subcandidates also has to match ... + subcandidates: Vec>, + + /// ...and the guard must be evaluated, if false branch to Block... otherwise_block: Option, - // ...and the blocks for add false edges between candidates + /// ...and the blocks for add false edges between candidates pre_binding_block: Option, next_candidate_pre_binding_block: Option, } +impl Candidate<'_, '_> { + /// Visit the leaf candidates (those with no subcandidates) contained in + /// this candidate. + fn visit_leaves<'a>(&'a mut self, mut visit_leaf: impl FnMut(&'a mut Self)) { + traverse_candidate( + self, + &mut (), + &mut move |c, _| visit_leaf(c), + move |c, _| c.subcandidates.iter_mut(), + |_| {}, + ); + } +} + +/// A depth-first traversal of the `Candidate` and all of its recursive +/// subcandidates. +fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>( + candidate: C, + context: &mut T, + visit_leaf: &mut impl FnMut(C, &mut T), + get_children: impl Copy + Fn(C, &mut T) -> I, + complete_children: impl Copy + Fn(&mut T), +) where + C: Borrow>, + I: Iterator, +{ + if candidate.borrow().subcandidates.is_empty() { + visit_leaf(candidate, context) + } else { + for child in get_children(candidate, context) { + traverse_candidate(child, context, visit_leaf, get_children, complete_children); + } + complete_children(context) + } +} + #[derive(Clone, Debug)] struct Binding<'tcx> { span: Span, @@ -793,10 +858,45 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Start by simplifying candidates. Once this process is complete, all // the match pairs which remain require some form of test, whether it // be a switch or pattern comparison. + let mut split_or_candidate = false; for candidate in &mut *candidates { - self.simplify_candidate(candidate); + split_or_candidate |= self.simplify_candidate(candidate); } + if split_or_candidate { + // At least one of the candidates has been split into subcandidates. + // We need to change the candidate list to include those. + let mut new_candidates = Vec::new(); + + for candidate in candidates { + candidate.visit_leaves(|leaf_candidate| new_candidates.push(leaf_candidate)); + } + self.match_simplified_candidates( + span, + start_block, + otherwise_block, + &mut *new_candidates, + fake_borrows, + ); + } else { + self.match_simplified_candidates( + span, + start_block, + otherwise_block, + candidates, + fake_borrows, + ); + }; + } + + fn match_simplified_candidates( + &mut self, + span: Span, + start_block: BasicBlock, + otherwise_block: &mut Option, + candidates: &mut [&mut Candidate<_, 'tcx>], + fake_borrows: &mut Option>>, + ) { // The candidates are sorted by priority. Check to see whether the // higher priority candidates (and hence at the front of the slice) // have satisfied all their match pairs. @@ -835,7 +935,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Test for the remaining candidates. - self.test_candidates(span, unmatched_candidates, block, otherwise_block, fake_borrows); + self.test_candidates_with_or( + span, + unmatched_candidates, + block, + otherwise_block, + fake_borrows, + ); } /// Link up matched candidates. For example, if we have something like @@ -866,6 +972,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { !matched_candidates.is_empty(), "select_matched_candidates called with no candidates", ); + debug_assert!( + matched_candidates.iter().all(|c| c.subcandidates.is_empty()), + "subcandidates should be empty in select_matched_candidates", + ); // Insert a borrows of prefixes of places that are bound and are // behind a dereference projection. @@ -902,7 +1012,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fully_matched_with_guard = matched_candidates .iter() - .position(|c| !c.has_guard) + .position(|c| !c.needs_otherwise_block) .unwrap_or(matched_candidates.len() - 1); let (reachable_candidates, unreachable_candidates) = @@ -914,7 +1024,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert!(candidate.otherwise_block.is_none()); assert!(candidate.pre_binding_block.is_none()); candidate.pre_binding_block = Some(next_prebinding); - if candidate.has_guard { + if candidate.needs_otherwise_block { next_prebinding = self.cfg.start_new_block(); candidate.otherwise_block = Some(next_prebinding); } @@ -932,6 +1042,120 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { reachable_candidates.last_mut().unwrap().otherwise_block } + fn test_candidates_with_or( + &mut self, + span: Span, + candidates: &mut [&mut Candidate<'_, 'tcx>], + block: BasicBlock, + otherwise_block: &mut Option, + fake_borrows: &mut Option>>, + ) { + let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap(); + + if let PatKind::Or { .. } = *first_candidate.match_pairs[0].pattern.kind { + let match_pairs = mem::take(&mut first_candidate.match_pairs); + first_candidate.needs_otherwise_block = true; + first_candidate.pre_binding_block = Some(block); + + // We sort or-patterns to the end in `simplify_candidate`, so all + // the remaining match pairs are or-patterns. + for match_pair in match_pairs { + if let PatKind::Or { ref pats } = *match_pair.pattern.kind { + let or_span = match_pair.pattern.span; + let place = &match_pair.place; + + first_candidate.visit_leaves(|leaf_candidate| { + self.test_or_pattern(leaf_candidate, pats, or_span, place, fake_borrows); + }); + } else { + bug!("Or patterns should have been sorted to the end"); + } + } + let remainder_start = + first_candidate.otherwise_block.unwrap_or_else(|| self.cfg.start_new_block()); + self.match_candidates( + span, + remainder_start, + otherwise_block, + remaining_candidates, + fake_borrows, + ) + } else { + self.test_candidates(span, candidates, block, otherwise_block, fake_borrows) + } + } + + fn test_or_pattern<'pat>( + &mut self, + candidate: &mut Candidate<'pat, 'tcx>, + pats: &'pat [Pat<'tcx>], + or_span: Span, + place: &Place<'tcx>, + fake_borrows: &mut Option>>, + ) { + debug!("test_or_pattern:\ncandidate={:#?}\npats={:#?}", candidate, pats); + let mut or_candidates: Vec<_> = pats + .iter() + .map(|pat| { + let new_match_pair = smallvec![MatchPair { pattern: pat, place: place.clone() }]; + Candidate { + span: pat.span, + has_guard: candidate.has_guard, + needs_otherwise_block: candidate.needs_otherwise_block, + match_pairs: new_match_pair, + bindings: Vec::new(), + ascriptions: Vec::new(), + otherwise_block: None, + pre_binding_block: None, + next_candidate_pre_binding_block: None, + subcandidates: Vec::new(), + } + }) + .collect(); + let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect(); + self.match_candidates( + or_span, + candidate.pre_binding_block.unwrap(), + &mut candidate.otherwise_block, + &mut or_candidate_refs, + fake_borrows, + ); + candidate.subcandidates = or_candidates; + self.merge_trivial_subcandidates(candidate, self.source_info(or_span)); + } + + /// Try to merge all of the subcandidates of the given candidate into one. + /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. + fn merge_trivial_subcandidates( + &mut self, + candidate: &mut Candidate<'_, 'tcx>, + source_info: SourceInfo, + ) { + if candidate.subcandidates.is_empty() { + return; + } + let mut can_merge = !candidate.has_guard; + + // Not `Iterator::all` because we don't want to short-circuit. + for subcandidate in &mut candidate.subcandidates { + self.merge_trivial_subcandidates(subcandidate, source_info); + + // FIXME(or_patterns; matthewjasper) Try to be more aggressive here. + can_merge &= subcandidate.subcandidates.is_empty() + && subcandidate.bindings.is_empty() + && subcandidate.ascriptions.is_empty(); + } + + if can_merge { + let any_matches = self.cfg.start_new_block(); + for subcandidate in mem::take(&mut candidate.subcandidates) { + let or_block = subcandidate.pre_binding_block.unwrap(); + self.cfg.goto(or_block, source_info, any_matches); + } + candidate.pre_binding_block = Some(any_matches); + } + } + /// This is the most subtle part of the matching algorithm. At /// this point, the input candidates have been fully simplified, /// and so we know that all remaining match-pairs require some @@ -1258,6 +1482,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_and_guard_matched_candidate<'pat>( &mut self, candidate: Candidate<'pat, 'tcx>, + parent_bindings: &[(Vec>, Vec>)], guard: Option<(&Guard<'tcx>, region::Scope)>, fake_borrows: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, @@ -1281,7 +1506,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block = fresh_block; } - self.ascribe_types(block, &candidate.ascriptions); + self.ascribe_types( + block, + parent_bindings + .iter() + .flat_map(|(_, ascriptions)| ascriptions) + .chain(&candidate.ascriptions), + ); // rust-lang/rust#27282: The `autoref` business deserves some // explanation here. @@ -1365,14 +1596,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // reference to that. if let Some((guard, region_scope)) = guard { let tcx = self.hir.tcx(); + let bindings = parent_bindings + .iter() + .flat_map(|(bindings, _)| bindings) + .chain(&candidate.bindings); - self.bind_matched_candidate_for_guard(block, &candidate.bindings); + self.bind_matched_candidate_for_guard(block, bindings.clone()); let guard_frame = GuardFrame { - locals: candidate - .bindings - .iter() - .map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode)) - .collect(), + locals: bindings.map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode)).collect(), }; debug!("entering guard building context: {:?}", guard_frame); self.guard_context.push(guard_frame); @@ -1446,9 +1677,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``` // // and that is clearly not correct. - let by_value_bindings = candidate.bindings.iter().filter(|binding| { - if let BindingMode::ByValue = binding.binding_mode { true } else { false } - }); + let by_value_bindings = + parent_bindings + .iter() + .flat_map(|(bindings, _)| bindings) + .chain(&candidate.bindings) + .filter(|binding| { + if let BindingMode::ByValue = binding.binding_mode { true } else { false } + }); // Read all of the by reference bindings to ensure that the // place they refer to can't be modified by the guard. for binding in by_value_bindings.clone() { @@ -1460,18 +1696,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { post_guard_block } else { - assert!(candidate.otherwise_block.is_none()); // (Here, it is not too early to bind the matched // candidate on `block`, because there is no guard result // that we have to inspect before we bind them.) - self.bind_matched_candidate_for_arm_body(block, &candidate.bindings); + self.bind_matched_candidate_for_arm_body( + block, + parent_bindings + .iter() + .flat_map(|(bindings, _)| bindings) + .chain(&candidate.bindings), + ); block } } /// Append `AscribeUserType` statements onto the end of `block` /// for each ascription - fn ascribe_types(&mut self, block: BasicBlock, ascriptions: &[Ascription<'tcx>]) { + fn ascribe_types<'b>( + &mut self, + block: BasicBlock, + ascriptions: impl IntoIterator>, + ) where + 'tcx: 'b, + { for ascription in ascriptions { let source_info = self.source_info(ascription.span); @@ -1498,14 +1745,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - fn bind_matched_candidate_for_guard(&mut self, block: BasicBlock, bindings: &[Binding<'tcx>]) { - debug!("bind_matched_candidate_for_guard(block={:?}, bindings={:?})", block, bindings); + fn bind_matched_candidate_for_guard<'b>( + &mut self, + block: BasicBlock, + bindings: impl IntoIterator>, + ) where + 'tcx: 'b, + { + debug!("bind_matched_candidate_for_guard(block={:?})", block); // Assign each of the bindings. Since we are binding for a // guard expression, this will never trigger moves out of the // candidate. let re_erased = self.hir.tcx().lifetimes.re_erased; for binding in bindings { + debug!("bind_matched_candidate_for_guard(binding={:?})", binding); let source_info = self.source_info(binding.span); // For each pattern ident P of type T, `ref_for_guard` is diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 77bbce2d37aa9..3a806ab6bff0a 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -16,18 +16,40 @@ use crate::build::matches::{Ascription, Binding, Candidate, MatchPair}; use crate::build::Builder; use crate::hair::{self, *}; use rustc::mir::interpret::truncate; +use rustc::mir::Place; use rustc::ty; use rustc::ty::layout::{Integer, IntegerExt, Size}; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; +use smallvec::smallvec; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { - crate fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) { + /// Simplify a candidate so that all match pairs require a test. + /// + /// This method will also split a candidate where the only match-pair is an + /// or-pattern into multiple candidates. This is so that + /// + /// match x { + /// 0 | 1 => { ... }, + /// 2 | 3 => { ... }, + /// } + /// + /// only generates a single switch. If this happens this method returns + /// `true`. + crate fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) -> bool { // repeatedly simplify match pairs until fixed point is reached loop { let match_pairs = mem::take(&mut candidate.match_pairs); + + if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, ref place }] = + *match_pairs + { + candidate.subcandidates = self.create_or_subcanidates(candidate, place, pats); + return true; + } + let mut changed = false; for match_pair in match_pairs { match self.simplify_match_pair(match_pair, candidate) { @@ -40,11 +62,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } if !changed { - return; // if we were not able to simplify any, done. + // Move or-patterns to the end, because they can result in us + // creating additional candidates, so we want to test them as + // late as possible. + candidate + .match_pairs + .sort_by_key(|pair| matches!(*pair.pattern.kind, PatKind::Or { .. })); + return false; // if we were not able to simplify any, done. } } } + fn create_or_subcanidates<'pat>( + &mut self, + candidate: &Candidate<'pat, 'tcx>, + place: &Place<'tcx>, + pats: &'pat [Pat<'tcx>], + ) -> Vec> { + pats.iter() + .map(|pat| { + let mut candidate = Candidate { + span: pat.span, + has_guard: candidate.has_guard, + needs_otherwise_block: candidate.needs_otherwise_block, + match_pairs: smallvec![MatchPair { place: place.clone(), pattern: pat }], + bindings: vec![], + ascriptions: vec![], + subcandidates: vec![], + otherwise_block: None, + pre_binding_block: None, + next_candidate_pre_binding_block: None, + }; + self.simplify_candidate(&mut candidate); + candidate + }) + .collect() + } + /// Tries to simplify `match_pair`, returning `Ok(())` if /// successful. If successful, new match pairs and bindings will /// have been pushed into the candidate. If no simplification is diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index 1f97f5f1b7281..ff95f16225751 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -70,11 +70,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - PatKind::Or { .. } => self - .hir - .tcx() - .sess - .span_fatal(match_pair.pattern.span, "or-patterns are not fully implemented yet"), + PatKind::Or { .. } => bug!("or-patterns should have already been handled"), PatKind::AscribeUserType { .. } | PatKind::Array { .. } diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs index 0f2c76152edae..cb93ba7c9250f 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -315,17 +315,6 @@ crate struct Arm<'tcx> { crate span: Span, } -impl<'tcx> Arm<'tcx> { - // HACK(or_patterns; Centril | dlrobertson): Remove this and - // correctly handle each case in which this method is used. - crate fn top_pats_hack(&self) -> &[Pat<'tcx>] { - match &*self.pattern.kind { - PatKind::Or { pats } => pats, - _ => std::slice::from_ref(&self.pattern), - } - } -} - #[derive(Clone, Debug)] crate enum Guard<'tcx> { If(ExprRef<'tcx>), From a20969c489d7f415f8073aacef1d480de6459ce8 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 17:31:21 +0000 Subject: [PATCH 0764/1253] Implement general or-patterns in `let` statements --- src/librustc_mir_build/build/matches/mod.rs | 107 ++++++++++---------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 4ac3ced17dbb1..928363246c2c0 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -96,11 +96,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut arm_candidates = self.create_match_candidates(&scrutinee_place, &arms); let match_has_guard = arms.iter().any(|arm| arm.guard.is_some()); - let candidates = + let mut candidates = arm_candidates.iter_mut().map(|(_, candidate)| candidate).collect::>(); let fake_borrow_temps = - self.lower_match_tree(block, scrutinee_span, match_has_guard, candidates); + self.lower_match_tree(block, scrutinee_span, match_has_guard, &mut candidates); self.lower_match_arms( &destination, @@ -181,7 +181,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block: BasicBlock, scrutinee_span: Span, match_has_guard: bool, - mut candidates: Vec<&mut Candidate<'pat, 'tcx>>, + candidates: &mut [&mut Candidate<'pat, 'tcx>], ) -> Vec<(Place<'tcx>, Local)> { // The set of places that we are creating fake borrows of. If there are // no match guards then we don't need any fake borrows, so don't track @@ -192,13 +192,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // This will generate code to test scrutinee_place and // branch to the appropriate arm block - self.match_candidates( - scrutinee_span, - block, - &mut otherwise, - &mut candidates, - &mut fake_borrows, - ); + self.match_candidates(scrutinee_span, block, &mut otherwise, candidates, &mut fake_borrows); if let Some(otherwise_block) = otherwise { let source_info = self.source_info(scrutinee_span); @@ -207,7 +201,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; - for candidate in candidates.into_iter() { + for candidate in candidates { candidate.visit_leaves(|leaf_candidate| { if let Some(ref mut prev) = previous_candidate { prev.next_candidate_pre_binding_block = leaf_candidate.pre_binding_block; @@ -263,7 +257,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arm.guard.as_ref().map(|g| (g, match_scope)), &fake_borrow_temps, scrutinee_span, - arm.scope, + Some(arm.scope), ); if let Some(source_scope) = scope { @@ -297,7 +291,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard: Option<(&Guard<'tcx>, region::Scope)>, fake_borrow_temps: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, - arm_scope: region::Scope, + arm_scope: Option, ) -> BasicBlock { if candidate.subcandidates.is_empty() { // Avoid generating another `BasicBlock` when we only have one @@ -308,10 +302,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard, fake_borrow_temps, scrutinee_span, + true, ) } else { let target_block = self.cfg.start_new_block(); - + let mut schedule_drops = true; // We keep a stack of all of the bindings and type asciptions // from the the parent candidates that we visit, that also need to // be bound for each candidate. @@ -319,14 +314,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate, &mut Vec::new(), &mut |leaf_candidate, parent_bindings| { - self.clear_top_scope(arm_scope); + if let Some(arm_scope) = arm_scope { + // Avoid scheduling drops multiple times by unscheduling drops. + self.clear_top_scope(arm_scope); + } let binding_end = self.bind_and_guard_matched_candidate( leaf_candidate, parent_bindings, guard, &fake_borrow_temps, scrutinee_span, + schedule_drops, ); + if arm_scope.is_none() { + // If we aren't in a match, then our bindings may not be + // the only thing in the top scope, so only schedule + // them to drop for the first pattern instead. + schedule_drops = false; + } self.cfg.goto(binding_end, outer_source_info, target_block); }, |inner_candidate, parent_bindings| { @@ -460,51 +465,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { subcandidates: vec![], }; - // Simplify the candidate. Since the pattern is irrefutable, this should - // always convert all match-pairs into bindings. - self.simplify_candidate(&mut candidate); - - if !candidate.match_pairs.is_empty() { - // ICE if no other errors have been emitted. This used to be a hard error that wouldn't - // be reached because `hair::pattern::check_match::check_match` wouldn't have let the - // compiler continue. In our tests this is only ever hit by - // `ui/consts/const-match-check.rs` with `--cfg eval1`, and that file already generates - // a different error before hand. - self.hir.tcx().sess.delay_span_bug( - candidate.match_pairs[0].pattern.span, - &format!( - "match pairs {:?} remaining after simplifying irrefutable pattern", - candidate.match_pairs, - ), - ); - } + let fake_borrow_temps = + self.lower_match_tree(block, irrefutable_pat.span, false, &mut [&mut candidate]); // for matches and function arguments, the place that is being matched // can be set when creating the variables. But the place for // let PATTERN = ... might not even exist until we do the assignment. // so we set it here instead if set_match_place { - for binding in &candidate.bindings { - let local = self.var_local_id(binding.var_id, OutsideGuard); - - if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - opt_match_place: Some((ref mut match_place, _)), - .. - }))) = self.local_decls[local].local_info - { - *match_place = Some(*initializer); - } else { - bug!("Let binding to non-user variable.") + let mut candidate_ref = &candidate; + while let Some(next) = { + for binding in &candidate_ref.bindings { + let local = self.var_local_id(binding.var_id, OutsideGuard); + + if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( + VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. }, + ))) = self.local_decls[local].local_info + { + *match_place = Some(*initializer); + } else { + bug!("Let binding to non-user variable.") + } } + candidate_ref.subcandidates.get(0) + } { + candidate_ref = next; } } - self.ascribe_types(block, &candidate.ascriptions); - - // now apply the bindings, which will also declare the variables - self.bind_matched_candidate_for_arm_body(block, &candidate.bindings); - - block.unit() + self.bind_pattern( + self.source_info(irrefutable_pat.span), + candidate, + None, + &fake_borrow_temps, + irrefutable_pat.span, + None, + ) + .unit() } /// Declares the bindings of the given patterns and returns the visibility @@ -1486,6 +1483,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard: Option<(&Guard<'tcx>, region::Scope)>, fake_borrows: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, + schedule_drops: bool, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -1692,7 +1690,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause = FakeReadCause::ForGuardBinding; self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id)); } - self.bind_matched_candidate_for_arm_body(post_guard_block, by_value_bindings); + assert!(schedule_drops, "patterns with guards must schedule drops"); + self.bind_matched_candidate_for_arm_body(post_guard_block, true, by_value_bindings); post_guard_block } else { @@ -1701,6 +1700,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // that we have to inspect before we bind them.) self.bind_matched_candidate_for_arm_body( block, + schedule_drops, parent_bindings .iter() .flat_map(|(bindings, _)| bindings) @@ -1793,6 +1793,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_arm_body<'b>( &mut self, block: BasicBlock, + schedule_drops: bool, bindings: impl IntoIterator>, ) where 'tcx: 'b, @@ -1805,7 +1806,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = self.source_info(binding.span); let local = self.storage_live_binding(block, binding.var_id, binding.span, OutsideGuard); - self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); + if schedule_drops { + self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); + } let rvalue = match binding.binding_mode { BindingMode::ByValue => { Rvalue::Use(self.consume_by_copy_or_move(binding.source.clone())) From 30058df867fbe5c43f90707d6fb644fba6201c2a Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 17:53:00 +0000 Subject: [PATCH 0765/1253] Update existing tests for or-patterns --- src/test/mir-opt/const_prop/discriminant.rs | 20 +-- src/test/mir-opt/issue-62289.rs | 38 +++--- src/test/mir-opt/match-arm-scopes.rs | 110 ++++++++-------- src/test/mir-opt/match_false_edges.rs | 118 +++++++++--------- src/test/mir-opt/match_test.rs | 28 ++--- src/test/mir-opt/remove_fake_borrows.rs | 24 ++-- src/test/mir-opt/simplify_try.rs | 40 +++--- src/test/ui/consts/const_let_refutable.rs | 8 +- src/test/ui/consts/const_let_refutable.stderr | 28 ++--- src/test/ui/empty/empty-never-array.rs | 1 - src/test/ui/empty/empty-never-array.stderr | 11 +- src/test/ui/issues/issue-12567.stderr | 4 +- src/test/ui/issues/issue-15381.rs | 1 - src/test/ui/issues/issue-15381.stderr | 11 +- .../ui/or-patterns/consistent-bindings.rs | 46 ++++--- .../ui/or-patterns/consistent-bindings.stderr | 9 -- .../exhaustiveness-non-exhaustive.rs | 7 +- .../exhaustiveness-non-exhaustive.stderr | 14 +-- .../ui/or-patterns/exhaustiveness-pass.rs | 9 +- .../ui/or-patterns/exhaustiveness-pass.stderr | 8 -- .../exhaustiveness-unreachable-pattern.rs | 7 +- .../exhaustiveness-unreachable-pattern.stderr | 48 ++++--- .../ui/or-patterns/feature-gate-const-fn.rs | 2 + .../or-patterns/feature-gate-const-fn.stderr | 17 ++- .../recursive-types-are-not-uninhabited.rs | 1 - ...recursive-types-are-not-uninhabited.stderr | 11 +- .../duplicate-suggestions.stderr | 30 +++-- .../dont-suggest-ref/simple.stderr | 51 +++++--- 28 files changed, 332 insertions(+), 370 deletions(-) delete mode 100644 src/test/ui/or-patterns/consistent-bindings.stderr delete mode 100644 src/test/ui/or-patterns/exhaustiveness-pass.stderr diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs index 07bbd9202b940..667d21fc14ee4 100644 --- a/src/test/mir-opt/const_prop/discriminant.rs +++ b/src/test/mir-opt/const_prop/discriminant.rs @@ -10,18 +10,18 @@ fn main() { // ... // _3 = std::option::Option::::Some(const true,); // _4 = discriminant(_3); -// switchInt(move _4) -> [1isize: bb3, otherwise: bb2]; +// switchInt(move _4) -> [1isize: bb2, otherwise: bb1]; // } // bb1: { -// _2 = const 42i32; +// _2 = const 10i32; // goto -> bb4; // } // bb2: { -// _2 = const 10i32; -// goto -> bb4; +// switchInt(((_3 as Some).0: bool)) -> [false: bb1, otherwise: bb3]; // } // bb3: { -// switchInt(((_3 as Some).0: bool)) -> [false: bb2, otherwise: bb1]; +// _2 = const 42i32; +// goto -> bb4; // } // bb4: { // _1 = Add(move _2, const 0i32); @@ -33,18 +33,18 @@ fn main() { // ... // _3 = const Scalar(0x01) : std::option::Option; // _4 = const 1isize; -// switchInt(const 1isize) -> [1isize: bb3, otherwise: bb2]; +// switchInt(const 1isize) -> [1isize: bb2, otherwise: bb1]; // } // bb1: { -// _2 = const 42i32; +// _2 = const 10i32; // goto -> bb4; // } // bb2: { -// _2 = const 10i32; -// goto -> bb4; +// switchInt(const true) -> [false: bb1, otherwise: bb3]; // } // bb3: { -// switchInt(const true) -> [false: bb2, otherwise: bb1]; +// _2 = const 42i32; +// goto -> bb4; // } // bb4: { // _1 = Add(move _2, const 0i32); diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs index a3b517e9bca87..8e619ffdf8b96 100644 --- a/src/test/mir-opt/issue-62289.rs +++ b/src/test/mir-opt/issue-62289.rs @@ -32,47 +32,47 @@ fn main() { // bb2: { // StorageDead(_4); // _5 = discriminant(_3); -// switchInt(move _5) -> [0isize: bb10, 1isize: bb5, otherwise: bb4]; +// switchInt(move _5) -> [0isize: bb4, 1isize: bb6, otherwise: bb5]; // } // bb3 (cleanup): { // drop(_2) -> bb1; // } // bb4: { -// unreachable; +// StorageLive(_10); +// _10 = ((_3 as Ok).0: u32); +// (*_2) = _10; +// StorageDead(_10); +// _1 = move _2; +// drop(_2) -> [return: bb12, unwind: bb11]; // } // bb5: { +// unreachable; +// } +// bb6: { // StorageLive(_6); // _6 = ((_3 as Err).0: std::option::NoneError); // StorageLive(_8); // StorageLive(_9); // _9 = _6; -// _8 = const >::from(move _9) -> [return: bb7, unwind: bb3]; +// _8 = const >::from(move _9) -> [return: bb8, unwind: bb3]; // } -// bb6: { +// bb7: { // return; // } -// bb7: { +// bb8: { // StorageDead(_9); -// _0 = const > as std::ops::Try>::from_error(move _8) -> [return: bb8, unwind: bb3]; +// _0 = const > as std::ops::Try>::from_error(move _8) -> [return: bb9, unwind: bb3]; // } -// bb8: { +// bb9: { // StorageDead(_8); // StorageDead(_6); -// drop(_2) -> bb9; +// drop(_2) -> bb10; // } -// bb9: { +// bb10: { // StorageDead(_2); // StorageDead(_1); // StorageDead(_3); -// goto -> bb6; -// } -// bb10: { -// StorageLive(_10); -// _10 = ((_3 as Ok).0: u32); -// (*_2) = _10; -// StorageDead(_10); -// _1 = move _2; -// drop(_2) -> [return: bb12, unwind: bb11]; +// goto -> bb7; // } // bb11 (cleanup): { // drop(_1) -> bb1; @@ -85,7 +85,7 @@ fn main() { // bb13: { // StorageDead(_1); // StorageDead(_3); -// goto -> bb6; +// goto -> bb7; // } // } // END rustc.test.ElaborateDrops.before.mir diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match-arm-scopes.rs index 4412a16e74d5e..7afc3bbd6fae8 100644 --- a/src/test/mir-opt/match-arm-scopes.rs +++ b/src/test/mir-opt/match-arm-scopes.rs @@ -28,10 +28,7 @@ const CASES: &[(bool, bool, bool, i32)] = &[ fn main() { for &(cond, items_1, items_2, result) in CASES { - assert_eq!( - complicated_match(cond, (items_1, items_2, String::new())), - result, - ); + assert_eq!(complicated_match(cond, (items_1, items_2, String::new())), result,); } } @@ -64,31 +61,38 @@ fn main() { // } // bb0: { // FakeRead(ForMatchedPlace, _2); -// switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb5]; +// switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb3]; // } // bb1 (cleanup): { // resume; // } -// bb2: { -// falseEdges -> [real: bb8, imaginary: bb3]; +// bb2: { // pre-binding for arm 1 first pattern +// falseEdges -> [real: bb9, imaginary: bb4]; // } // bb3: { -// falseEdges -> [real: bb17, imaginary: bb4]; +// switchInt((_2.1: bool)) -> [false: bb4, otherwise: bb5]; // } -// bb4: { -// falseEdges -> [real: bb25, imaginary: bb26]; +// bb4: { // pre-binding for arm 1 second pattern +// falseEdges -> [real: bb18, imaginary: bb6]; // } // bb5: { -// switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb6]; +// switchInt((_2.0: bool)) -> [false: bb7, otherwise: bb6]; // } -// bb6: { -// switchInt((_2.0: bool)) -> [false: bb26, otherwise: bb4]; +// bb6: { // pre-binding for arm 2 first pattern +// falseEdges -> [real: bb26, imaginary: bb7]; // } -// bb7: { // arm 1 +// bb7: { // bindings for arm 2 - second pattern +// StorageLive(_15); +// _15 = (_2.1: bool); +// StorageLive(_16); +// _16 = move (_2.2: std::string::String); +// goto -> bb25; +// } +// bb8: { // arm 1 // _0 = const 1i32; -// drop(_7) -> [return: bb23, unwind: bb13]; +// drop(_7) -> [return: bb24, unwind: bb14]; // } -// bb8: { // guard - first time +// bb9: { // guard - first time // StorageLive(_6); // _6 = &(_2.1: bool); // StorageLive(_8); @@ -99,34 +103,34 @@ fn main() { // StorageLive(_10); // _10 = _1; // FakeRead(ForMatchedPlace, _10); -// switchInt(_10) -> [false: bb10, otherwise: bb9]; +// switchInt(_10) -> [false: bb11, otherwise: bb10]; // } -// bb9: { -// falseEdges -> [real: bb11, imaginary: bb10]; +// bb10: { +// falseEdges -> [real: bb12, imaginary: bb11]; // } -// bb10: { // `else` block - first time +// bb11: { // `else` block - first time // _9 = (*_6); // StorageDead(_10); -// switchInt(move _9) -> [false: bb16, otherwise: bb15]; +// switchInt(move _9) -> [false: bb17, otherwise: bb16]; // } -// bb11: { // `return 3` - first time +// bb12: { // `return 3` - first time // _0 = const 3i32; // StorageDead(_10); // StorageDead(_9); // StorageDead(_8); // StorageDead(_6); -// goto -> bb14; +// goto -> bb15; // } -// bb12: { +// bb13: { // return; // } -// bb13 (cleanup): { +// bb14 (cleanup): { // drop(_2) -> bb1; // } -// bb14: { -// drop(_2) -> [return: bb12, unwind: bb1]; -// } // bb15: { +// drop(_2) -> [return: bb13, unwind: bb1]; +// } +// bb16: { // StorageDead(_9); // FakeRead(ForMatchGuard, _3); // FakeRead(ForMatchGuard, _4); @@ -136,15 +140,15 @@ fn main() { // _5 = (_2.1: bool); // StorageLive(_7); // _7 = move (_2.2: std::string::String); -// goto -> bb7; +// goto -> bb8; // } -// bb16: { // guard otherwise case - first time +// bb17: { // guard otherwise case - first time // StorageDead(_9); // StorageDead(_8); // StorageDead(_6); -// falseEdges -> [real: bb5, imaginary: bb3]; +// falseEdges -> [real: bb3, imaginary: bb4]; // } -// bb17: { // guard - second time +// bb18: { // guard - second time // StorageLive(_6); // _6 = &(_2.0: bool); // StorageLive(_8); @@ -155,25 +159,25 @@ fn main() { // StorageLive(_13); // _13 = _1; // FakeRead(ForMatchedPlace, _13); -// switchInt(_13) -> [false: bb19, otherwise: bb18]; +// switchInt(_13) -> [false: bb20, otherwise: bb19]; // } -// bb18: { -// falseEdges -> [real: bb20, imaginary: bb19]; +// bb19: { +// falseEdges -> [real: bb21, imaginary: bb20]; // } -// bb19: { // `else` block - second time +// bb20: { // `else` block - second time // _12 = (*_6); // StorageDead(_13); -// switchInt(move _12) -> [false: bb22, otherwise: bb21]; +// switchInt(move _12) -> [false: bb23, otherwise: bb22]; // } -// bb20: { +// bb21: { // _0 = const 3i32; // StorageDead(_13); // StorageDead(_12); // StorageDead(_8); // StorageDead(_6); -// goto -> bb14; +// goto -> bb15; // } -// bb21: { // bindings for arm 1 +// bb22: { // bindings for arm 1 // StorageDead(_12); // FakeRead(ForMatchGuard, _3); // FakeRead(ForMatchGuard, _4); @@ -183,46 +187,40 @@ fn main() { // _5 = (_2.0: bool); // StorageLive(_7); // _7 = move (_2.2: std::string::String); -// goto -> bb7; +// goto -> bb8; // } -// bb22: { // Guard otherwise case - second time +// bb23: { // Guard otherwise case - second time // StorageDead(_12); // StorageDead(_8); // StorageDead(_6); -// falseEdges -> [real: bb6, imaginary: bb4]; +// falseEdges -> [real: bb5, imaginary: bb6]; // } -// bb23: { // rest of arm 1 +// bb24: { // rest of arm 1 // StorageDead(_7); // StorageDead(_5); // StorageDead(_8); // StorageDead(_6); // goto -> bb28; // } -// bb24: { // arm 2 +// bb25: { // arm 2 // _0 = const 2i32; -// drop(_16) -> [return: bb27, unwind: bb13]; +// drop(_16) -> [return: bb27, unwind: bb14]; // } -// bb25: { // bindings for arm 2 - first pattern +// bb26: { // bindings for arm 2 - first pattern // StorageLive(_15); // _15 = (_2.1: bool); // StorageLive(_16); // _16 = move (_2.2: std::string::String); -// goto -> bb24; -// } -// bb26: { // bindings for arm 2 - second pattern -// StorageLive(_15); -// _15 = (_2.1: bool); -// StorageLive(_16); -// _16 = move (_2.2: std::string::String); -// goto -> bb24; +// goto -> bb25; // } + // bb27: { // rest of arm 2 // StorageDead(_16); // StorageDead(_15); // goto -> bb28; // } // bb28: { -// drop(_2) -> [return: bb12, unwind: bb1]; +// drop(_2) -> [return: bb13, unwind: bb1]; // } // END rustc.complicated_match.SimplifyCfg-initial.after.mir // START rustc.complicated_match.ElaborateDrops.after.mir diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 2c20c35e4a491..237828d9020db 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -4,7 +4,7 @@ fn guard() -> bool { false } -fn guard2(_:i32) -> bool { +fn guard2(_: i32) -> bool { true } @@ -45,20 +45,20 @@ fn main() { // _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); -// switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb5]; +// switchInt(move _3) -> [0isize: bb2, 1isize: bb3, otherwise: bb5]; // } // bb1 (cleanup): { // resume; // } -// bb2: { -// falseEdges -> [real: bb6, imaginary: bb3]; //pre_binding1 +// bb2: { // pre_binding3 and arm3 +// _1 = (const 3i32, const 3i32); +// goto -> bb11; // } // bb3: { -// falseEdges -> [real: bb10, imaginary: bb4]; //pre_binding2 +// falseEdges -> [real: bb6, imaginary: bb4]; //pre_binding1 // } -// bb4: { //pre_binding3 and arm3 -// _1 = (const 3i32, const 3i32); -// goto -> bb11; +// bb4: { +// falseEdges -> [real: bb10, imaginary: bb2]; //pre_binding2 // } // bb5: { // unreachable; @@ -91,7 +91,7 @@ fn main() { // bb9: { // to pre_binding2 // StorageDead(_7); // StorageDead(_6); -// goto -> bb3; +// goto -> bb4; // } // bb10: { // arm2 // StorageLive(_9); @@ -103,7 +103,7 @@ fn main() { // StorageDead(_9); // goto -> bb11; // } -// bb11: { // arm3 +// bb11: { // StorageDead(_2); // StorageDead(_1); // _0 = (); @@ -117,31 +117,41 @@ fn main() { // _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); -// switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb4]; +// switchInt(move _3) -> [0isize: bb2, 1isize: bb3, otherwise: bb5]; // } // bb1 (cleanup): { // resume; // } -// bb2: { -// falseEdges -> [real: bb5, imaginary: bb3]; +// bb2: { // pre_binding2 +// falseEdges -> [real: bb10, imaginary: bb4]; // } -// bb3: { -// falseEdges -> [real: bb9, imaginary: bb10]; +// bb3: { // pre_binding1 +// falseEdges -> [real: bb6, imaginary: bb2]; // } -// bb4: { // to arm3 (can skip 2 since this is `Some`) +// bb4: { // binding3 and arm3 +// StorageLive(_9); +// _9 = ((_2 as Some).0: i32); +// StorageLive(_10); +// _10 = _9; +// _1 = (const 2i32, move _10); +// StorageDead(_10); +// StorageDead(_9); +// goto -> bb11; +// } +// bb5: { // unreachable; // } -// bb5: { // binding1 and guard +// bb6: { // StorageLive(_6); // _6 = &((_2 as Some).0: i32); // _4 = &shallow _2; // StorageLive(_7); -// _7 = const guard() -> [return: bb6, unwind: bb1]; +// _7 = const guard() -> [return: bb7, unwind: bb1]; // } -// bb6: { // end of guard -// switchInt(move _7) -> [false: bb8, otherwise: bb7]; +// bb7: { // end of guard +// switchInt(move _7) -> [false: bb9, otherwise: bb8]; // } -// bb7: { +// bb8: { // StorageDead(_7); // FakeRead(ForMatchGuard, _4); // FakeRead(ForGuardBinding, _6); @@ -155,25 +165,15 @@ fn main() { // StorageDead(_6); // goto -> bb11; // } -// bb8: { // to pre_binding3 (can skip 2 since this is `Some`) +// bb9: { // to pre_binding3 (can skip 2 since this is `Some`) // StorageDead(_7); // StorageDead(_6); -// falseEdges -> [real: bb10, imaginary: bb3]; +// falseEdges -> [real: bb4, imaginary: bb2]; // } -// bb9: { // arm2 +// bb10: { // arm2 // _1 = (const 3i32, const 3i32); // goto -> bb11; // } -// bb10: { // binding3 and arm3 -// StorageLive(_9); -// _9 = ((_2 as Some).0: i32); -// StorageLive(_10); -// _10 = _9; -// _1 = (const 2i32, move _10); -// StorageDead(_10); -// StorageDead(_9); -// goto -> bb11; -// } // bb11: { // StorageDead(_2); // StorageDead(_1); @@ -188,31 +188,38 @@ fn main() { // _2 = std::option::Option::::Some(const 1i32,); // FakeRead(ForMatchedPlace, _2); // _4 = discriminant(_2); -// switchInt(move _4) -> [1isize: bb2, otherwise: bb3]; +// switchInt(move _4) -> [1isize: bb3, otherwise: bb2]; // } // bb1 (cleanup): { // resume; // } // bb2: { -// falseEdges -> [real: bb5, imaginary: bb3]; +// falseEdges -> [real: bb10, imaginary: bb5]; // } // bb3: { -// falseEdges -> [real: bb9, imaginary: bb4]; +// falseEdges -> [real: bb6, imaginary: bb2]; // } // bb4: { -// falseEdges -> [real: bb10, imaginary: bb14]; +// StorageLive(_14); +// _14 = _2; +// _1 = const 4i32; +// StorageDead(_14); +// goto -> bb15; // } // bb5: { +// falseEdges -> [real: bb11, imaginary: bb4]; +// } +// bb6: { //end of guard1 // StorageLive(_7); // _7 = &((_2 as Some).0: i32); // _5 = &shallow _2; // StorageLive(_8); -// _8 = const guard() -> [return: bb6, unwind: bb1]; -// } -// bb6: { //end of guard1 -// switchInt(move _8) -> [false: bb8, otherwise: bb7]; +// _8 = const guard() -> [return: bb7, unwind: bb1]; // } // bb7: { +// switchInt(move _8) -> [false: bb9, otherwise: bb8]; +// } +// bb8: { // StorageDead(_8); // FakeRead(ForMatchGuard, _5); // FakeRead(ForGuardBinding, _7); @@ -223,32 +230,32 @@ fn main() { // StorageDead(_7); // goto -> bb15; // } -// bb8: { +// bb9: { // StorageDead(_8); // StorageDead(_7); -// falseEdges -> [real: bb3, imaginary: bb3]; +// falseEdges -> [real: bb2, imaginary: bb2]; // } -// bb9: { // binding2 & arm2 +// bb10: { // binding2 & arm2 // StorageLive(_9); // _9 = _2; // _1 = const 2i32; // StorageDead(_9); // goto -> bb15; // } -// bb10: { // binding3: Some(y) if guard2(y) +// bb11: { // binding3: Some(y) if guard2(y) // StorageLive(_11); // _11 = &((_2 as Some).0: i32); // _5 = &shallow _2; // StorageLive(_12); // StorageLive(_13); // _13 = (*_11); -// _12 = const guard2(move _13) -> [return: bb11, unwind: bb1]; +// _12 = const guard2(move _13) -> [return: bb12, unwind: bb1]; // } -// bb11: { // end of guard2 +// bb12: { // end of guard2 // StorageDead(_13); -// switchInt(move _12) -> [false: bb13, otherwise: bb12]; +// switchInt(move _12) -> [false: bb14, otherwise: bb13]; // } -// bb12: { // binding4 & arm4 +// bb13: { // binding4 & arm4 // StorageDead(_12); // FakeRead(ForMatchGuard, _5); // FakeRead(ForGuardBinding, _11); @@ -259,17 +266,10 @@ fn main() { // StorageDead(_11); // goto -> bb15; // } -// bb13: { +// bb14: { // StorageDead(_12); // StorageDead(_11); -// falseEdges -> [real: bb14, imaginary: bb14]; -// } -// bb14: { -// StorageLive(_14); -// _14 = _2; -// _1 = const 4i32; -// StorageDead(_14); -// goto -> bb15; +// falseEdges -> [real: bb4, imaginary: bb4]; // } // bb15: { // StorageDead(_2); diff --git a/src/test/mir-opt/match_test.rs b/src/test/mir-opt/match_test.rs index 1ca75b100410b..5ee3e1447d832 100644 --- a/src/test/mir-opt/match_test.rs +++ b/src/test/mir-opt/match_test.rs @@ -20,35 +20,35 @@ fn main() { // START rustc.main.SimplifyCfg-initial.after.mir // bb0: { // ... -// switchInt(move _6) -> [false: bb6, otherwise: bb5]; +// switchInt(move _6) -> [false: bb4, otherwise: bb1]; // } // bb1: { -// falseEdges -> [real: bb9, imaginary: bb2]; +// _7 = Lt(_1, const 10i32); +// switchInt(move _7) -> [false: bb4, otherwise: bb2]; // } // bb2: { -// falseEdges -> [real: bb12, imaginary: bb3]; +// falseEdges -> [real: bb9, imaginary: bb6]; // } // bb3: { -// falseEdges -> [real: bb13, imaginary: bb4]; -// } -// bb4: { // _3 = const 3i32; // goto -> bb14; // } +// bb4: { +// _4 = Le(const 10i32, _1); +// switchInt(move _4) -> [false: bb7, otherwise: bb5]; +// } // bb5: { -// _7 = Lt(_1, const 10i32); -// switchInt(move _7) -> [false: bb6, otherwise: bb1]; +// _5 = Le(_1, const 20i32); +// switchInt(move _5) -> [false: bb7, otherwise: bb6]; // } // bb6: { -// _4 = Le(const 10i32, _1); -// switchInt(move _4) -> [false: bb8, otherwise: bb7]; +// falseEdges -> [real: bb12, imaginary: bb8]; // } // bb7: { -// _5 = Le(_1, const 20i32); -// switchInt(move _5) -> [false: bb8, otherwise: bb2]; +// switchInt(_1) -> [-1i32: bb8, otherwise: bb3]; // } // bb8: { -// switchInt(_1) -> [-1i32: bb3, otherwise: bb4]; +// falseEdges -> [real: bb13, imaginary: bb3]; // } // bb9: { // _8 = &shallow _1; @@ -64,7 +64,7 @@ fn main() { // } // bb11: { // StorageDead(_9); -// falseEdges -> [real: bb4, imaginary: bb2]; +// falseEdges -> [real: bb3, imaginary: bb6]; // } // bb12: { // _3 = const 1i32; diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs index 965897ad541e7..294fe247c38be 100644 --- a/src/test/mir-opt/remove_fake_borrows.rs +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -19,17 +19,17 @@ fn main() { // bb0: { // FakeRead(ForMatchedPlace, _1); // _3 = discriminant(_1); -// switchInt(move _3) -> [1isize: bb3, otherwise: bb2]; +// switchInt(move _3) -> [1isize: bb2, otherwise: bb1]; // } // bb1: { -// goto -> bb4; -// } -// bb2: { // _0 = const 1i32; // goto -> bb7; // } +// bb2: { +// switchInt((*(*((_1 as Some).0: &' &' i32)))) -> [0i32: bb3, otherwise: bb1]; +// } // bb3: { -// switchInt((*(*((_1 as Some).0: &' &' i32)))) -> [0i32: bb1, otherwise: bb2]; +// goto -> bb4; // } // bb4: { // _4 = &shallow _1; @@ -51,7 +51,7 @@ fn main() { // } // bb6: { // StorageDead(_8); -// goto -> bb2; +// goto -> bb1; // } // bb7: { // return; @@ -65,17 +65,17 @@ fn main() { // bb0: { // nop; // _3 = discriminant(_1); -// switchInt(move _3) -> [1isize: bb3, otherwise: bb2]; +// switchInt(move _3) -> [1isize: bb2, otherwise: bb1]; // } // bb1: { -// goto -> bb4; -// } -// bb2: { // _0 = const 1i32; // goto -> bb7; // } +// bb2: { +// switchInt((*(*((_1 as Some).0: &' &' i32)))) -> [0i32: bb3, otherwise: bb1]; +// } // bb3: { -// switchInt((*(*((_1 as Some).0: &' &' i32)))) -> [0i32: bb1, otherwise: bb2]; +// goto -> bb4; // } // bb4: { // nop; @@ -97,7 +97,7 @@ fn main() { // } // bb6: { // StorageDead(_8); -// goto -> bb2; +// goto -> bb1; // } // bb7: { // return; diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs index d85eff45b4989..abac66d95c548 100644 --- a/src/test/mir-opt/simplify_try.rs +++ b/src/test/mir-opt/simplify_try.rs @@ -47,22 +47,22 @@ fn main() { // } // bb0: { // _5 = discriminant(_1); -// switchInt(move _5) -> [0isize: bb3, otherwise: bb1]; +// switchInt(move _5) -> [0isize: bb1, otherwise: bb2]; // } // bb1: { +// _10 = ((_1 as Ok).0: u32); +// ((_0 as Ok).0: u32) = move _10; +// discriminant(_0) = 0; +// goto -> bb3; +// } +// bb2: { // _6 = ((_1 as Err).0: i32); // ((_0 as Err).0: i32) = move _6; // discriminant(_0) = 1; -// goto -> bb2; -// } -// bb2: { -// return; +// goto -> bb3; // } // bb3: { -// _10 = ((_1 as Ok).0: u32); -// ((_0 as Ok).0: u32) = move _10; -// discriminant(_0) = 0; -// goto -> bb2; +// return; // } // } // END rustc.try_identity.SimplifyArmIdentity.before.mir @@ -106,22 +106,22 @@ fn main() { // } // bb0: { // _5 = discriminant(_1); -// switchInt(move _5) -> [0isize: bb3, otherwise: bb1]; +// switchInt(move _5) -> [0isize: bb1, otherwise: bb2]; // } // bb1: { // _0 = move _1; // nop; // nop; -// goto -> bb2; +// goto -> bb3; // } // bb2: { -// return; -// } -// bb3: { // _0 = move _1; // nop; // nop; -// goto -> bb2; +// goto -> bb3; +// } +// bb3: { +// return; // } // } // END rustc.try_identity.SimplifyArmIdentity.after.mir @@ -165,16 +165,16 @@ fn main() { // } // bb0: { // _5 = discriminant(_1); -// goto -> bb2; +// goto -> bb1; // } // bb1: { -// return; -// } -// bb2: { // _0 = move _1; // nop; // nop; -// goto -> bb1; +// goto -> bb2; +// } +// bb2: { +// return; // } // } // END rustc.try_identity.SimplifyBranchSame.after.mir diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs index d48d5945e7da9..e49d47673912a 100644 --- a/src/test/ui/consts/const_let_refutable.rs +++ b/src/test/ui/consts/const_let_refutable.rs @@ -1,7 +1,7 @@ fn main() {} -const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument - a + b //~ ERROR can only call other `const fn` within a `const fn` - //~^ ERROR use of possibly-uninitialized variable: `a` - //~| ERROR use of possibly-uninitialized variable: `b` +const fn slice(&[a, b]: &[i32]) -> i32 { + //~^ ERROR refutable pattern in function argument + //~| ERROR loops and conditional expressions are not stable in const fn + a + b } diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr index 9acb4ad9cbbe5..719e14005ffa4 100644 --- a/src/test/ui/consts/const_let_refutable.stderr +++ b/src/test/ui/consts/const_let_refutable.stderr @@ -1,31 +1,19 @@ error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered --> $DIR/const_let_refutable.rs:3:16 | -LL | const fn slice([a, b]: &[i32]) -> i32 { - | ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered +LL | const fn slice(&[a, b]: &[i32]) -> i32 { + | ^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered -error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn` - --> $DIR/const_let_refutable.rs:4:5 +error[E0723]: loops and conditional expressions are not stable in const fn + --> $DIR/const_let_refutable.rs:3:17 | -LL | a + b - | ^^^^^ +LL | const fn slice(&[a, b]: &[i32]) -> i32 { + | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add `#![feature(const_fn)]` to the crate attributes to enable -error[E0381]: use of possibly-uninitialized variable: `a` - --> $DIR/const_let_refutable.rs:4:5 - | -LL | a + b - | ^ use of possibly-uninitialized `a` - -error[E0381]: use of possibly-uninitialized variable: `b` - --> $DIR/const_let_refutable.rs:4:9 - | -LL | a + b - | ^ use of possibly-uninitialized `b` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0005, E0381, E0723. +Some errors have detailed explanations: E0005, E0723. For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs index f0ecea42f39c8..01b99134a445f 100644 --- a/src/test/ui/empty/empty-never-array.rs +++ b/src/test/ui/empty/empty-never-array.rs @@ -10,7 +10,6 @@ fn transmute(t: T) -> U { let Helper::U(u) = Helper::T(t, []); //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered u - //~^ ERROR use of possibly-uninitialized variable: `u` } fn main() { diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index d865b59f0b945..a4ffceea4c97f 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -19,13 +19,6 @@ help: you might want to use `if let` to ignore the variant that isn't matched LL | if let Helper::U(u) = Helper::T(t, []) { /* */ } | -error[E0381]: use of possibly-uninitialized variable: `u` - --> $DIR/empty-never-array.rs:12:5 - | -LL | u - | ^ use of possibly-uninitialized `u` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/issues/issue-12567.stderr b/src/test/ui/issues/issue-12567.stderr index 2a88d8f0524ac..3ce659ccd14da 100644 --- a/src/test/ui/issues/issue-12567.stderr +++ b/src/test/ui/issues/issue-12567.stderr @@ -8,7 +8,7 @@ LL | (&[], &[hd, ..]) | (&[hd, ..], &[]) | -- data moved here LL | => println!("one empty"), LL | (&[hd1, ..], &[hd2, ..]) - | --- ...and here + | --- ...and here | = note: move occurs because these variables have types that don't implement the `Copy` trait @@ -22,7 +22,7 @@ LL | (&[], &[hd, ..]) | (&[hd, ..], &[]) | -- data moved here LL | => println!("one empty"), LL | (&[hd1, ..], &[hd2, ..]) - | --- ...and here + | --- ...and here | = note: move occurs because these variables have types that don't implement the `Copy` trait diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs index 5307153cb4403..392fb1b24ddc4 100644 --- a/src/test/ui/issues/issue-15381.rs +++ b/src/test/ui/issues/issue-15381.rs @@ -4,6 +4,5 @@ fn main() { for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { //~^ ERROR refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` and 1 more not println!("y={}", y); - //~^ ERROR borrow of possibly-uninitialized variable: `y` } } diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr index 47a0d514ad873..35f46ab57279c 100644 --- a/src/test/ui/issues/issue-15381.stderr +++ b/src/test/ui/issues/issue-15381.stderr @@ -4,13 +4,6 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { | ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered -error[E0381]: borrow of possibly-uninitialized variable: `y` - --> $DIR/issue-15381.rs:6:26 - | -LL | println!("y={}", y); - | ^ use of possibly-uninitialized `y` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/or-patterns/consistent-bindings.rs b/src/test/ui/or-patterns/consistent-bindings.rs index ec71afed872ba..3ee57978bb009 100644 --- a/src/test/ui/or-patterns/consistent-bindings.rs +++ b/src/test/ui/or-patterns/consistent-bindings.rs @@ -2,6 +2,8 @@ // edition:2018 +// check-pass + #![feature(or_patterns)] fn main() { @@ -11,35 +13,29 @@ fn main() { let Ok(ref mut a) | Err(ref mut a) = Ok(0); // Two levels: - enum Tri { V1(S), V2(T), V3(U) } + enum Tri { + V1(S), + V2(T), + V3(U), + } use Tri::*; - let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))) - : Result<_, Result<_, _>> - = Ok((V1(1), 1)); + let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))): Result<_, Result<_, _>> = + Ok((V1(1), 1)); - let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))) - : Result<_, Result<_, _>> - = Ok((V1(1), 1)); + let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))): Result< + _, + Result<_, _>, + > = Ok((V1(1), 1)); // Three levels: let ( - a, - Err((ref mut b, ref c, d)) | - Ok(( - Ok( - V1((ref c, d)) | - V2((d, ref c)) | - V3((ref c, Ok((_, d)) | Err((d, _)))) - ) | - Err((ref c, d)), - ref mut b - )) - ) = - (1, Ok((Ok(V3((1, Ok((1, 1))))), 1))); - - // FIXME(or_patterns; Centril | dlrobertson): remove this line below and - // change this test to check-pass once MIR can handle or-patterns with bindings. - let () = 0; - //~^ ERROR mismatched types + a, + Err((ref mut b, ref c, d)) + | Ok(( + Ok(V1((ref c, d)) | V2((d, ref c)) | V3((ref c, Ok((_, d)) | Err((d, _))))) + | Err((ref c, d)), + ref mut b, + )), + ): (_, Result<_, _>) = (1, Ok((Ok(V3((1, Ok::<_, (i32, i32)>((1, 1))))), 1))); } diff --git a/src/test/ui/or-patterns/consistent-bindings.stderr b/src/test/ui/or-patterns/consistent-bindings.stderr deleted file mode 100644 index bb8e90af5f202..0000000000000 --- a/src/test/ui/or-patterns/consistent-bindings.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/consistent-bindings.rs:43:9 - | -LL | let () = 0; - | ^^ expected integer, found `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs index 2e8baf978e251..c8bc4a2a8d51b 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs @@ -1,13 +1,8 @@ #![feature(or_patterns)] #![deny(unreachable_patterns)] -// We wrap patterns in a tuple because top-level or-patterns are special-cased for now. +// We wrap patterns in a tuple because top-level or-patterns were special-cased. fn main() { - // Get the fatal error out of the way - match (0u8,) { - (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet - } - match (0u8, 0u8) { //~^ ERROR non-exhaustive patterns: `(2u8..=std::u8::MAX, _)` (0 | 1, 2 | 3) => {} diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr index 7fbd846a22f2b..3ba26de10d3d5 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `(2u8..=std::u8::MAX, _)` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:13:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:6:11 | LL | match (0u8, 0u8) { | ^^^^^^^^^^ pattern `(2u8..=std::u8::MAX, _)` not covered @@ -7,7 +7,7 @@ LL | match (0u8, 0u8) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((4u8..=std::u8::MAX))` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:17:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:10:11 | LL | match ((0u8,),) { | ^^^^^^^^^ pattern `((4u8..=std::u8::MAX))` not covered @@ -15,19 +15,13 @@ LL | match ((0u8,),) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(Some(2u8..=std::u8::MAX))` not covered - --> $DIR/exhaustiveness-non-exhaustive.rs:21:11 + --> $DIR/exhaustiveness-non-exhaustive.rs:14:11 | LL | match (Some(0u8),) { | ^^^^^^^^^^^^ pattern `(Some(2u8..=std::u8::MAX))` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-non-exhaustive.rs:9:10 - | -LL | (0 | _,) => {} - | ^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.rs b/src/test/ui/or-patterns/exhaustiveness-pass.rs index 9b62810d29db9..8dcf8792f6f96 100644 --- a/src/test/ui/or-patterns/exhaustiveness-pass.rs +++ b/src/test/ui/or-patterns/exhaustiveness-pass.rs @@ -1,13 +1,10 @@ #![feature(or_patterns)] #![deny(unreachable_patterns)] -// We wrap patterns in a tuple because top-level or-patterns are special-cased for now. -fn main() { - // Get the fatal error out of the way - match (0,) { - (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet - } +// check-pass +// We wrap patterns in a tuple because top-level or-patterns were special-cased. +fn main() { match (0,) { (1 | 2,) => {} _ => {} diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.stderr b/src/test/ui/or-patterns/exhaustiveness-pass.stderr deleted file mode 100644 index dc5a4186ac700..0000000000000 --- a/src/test/ui/or-patterns/exhaustiveness-pass.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-pass.rs:9:10 - | -LL | (0 | _,) => {} - | ^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index dd1c16f500028..44bae282d8857 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -1,13 +1,8 @@ #![feature(or_patterns)] #![deny(unreachable_patterns)] -// We wrap patterns in a tuple because top-level or-patterns are special-cased for now. +// We wrap patterns in a tuple because top-level or-patterns were special-cased. fn main() { - // Get the fatal error out of the way - match (0u8,) { - (0 | _,) => {} //~^ ERROR or-patterns are not fully implemented yet - } - match (0u8,) { (1 | 2,) => {} (1,) => {} //~ ERROR unreachable pattern diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 1f07c27afad9c..bef6f8270bc54 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -1,110 +1,104 @@ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:15:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:8:9 | LL | (1,) => {} | ^^^^ | note: the lint level is defined here - --> $DIR/exhaustiveness-unreachable-pattern.rs:3:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:2:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:20:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:13:9 | LL | (2,) => {} | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:26:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9 | LL | (1 | 2,) => {} | ^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:31:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:24:9 | LL | (1, 3) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:32:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:25:9 | LL | (1, 4) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:33:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:26:9 | LL | (2, 4) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:34:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:27:9 | LL | (2 | 1, 4) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:36:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9 | LL | (1, 4 | 5) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:41:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:34:9 | LL | (Some(1),) => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:42:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:35:9 | LL | (None,) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:47:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:40:9 | -LL | ((1..=4,),) => {}, +LL | ((1..=4,),) => {} | ^^^^^^^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:53:12 + --> $DIR/exhaustiveness-unreachable-pattern.rs:45:14 | -LL | | 1,) => {} - | ^ +LL | (1 | 1,) => {} + | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:60:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:52:15 | LL | | 0] => {} | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:58:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:50:15 | LL | | 0 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:68:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:60:10 | LL | [1 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:74:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:66:14 | LL | Some(0 | ^ -error: or-patterns are not fully implemented yet - --> $DIR/exhaustiveness-unreachable-pattern.rs:9:10 - | -LL | (0 | _,) => {} - | ^^^^^ - -error: aborting due to 17 previous errors +error: aborting due to 16 previous errors diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.rs b/src/test/ui/or-patterns/feature-gate-const-fn.rs index d21cf3dc72c99..2ef5537db60ad 100644 --- a/src/test/ui/or-patterns/feature-gate-const-fn.rs +++ b/src/test/ui/or-patterns/feature-gate-const-fn.rs @@ -30,6 +30,8 @@ fn main() { let x = Ok(3); let Ok(y) | Err(y) = x; //~^ ERROR or-pattern is not allowed in a `const` + //~| ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type 2 }]; } diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.stderr b/src/test/ui/or-patterns/feature-gate-const-fn.stderr index 112bc62517260..9284e2d442dfa 100644 --- a/src/test/ui/or-patterns/feature-gate-const-fn.stderr +++ b/src/test/ui/or-patterns/feature-gate-const-fn.stderr @@ -52,6 +52,19 @@ LL | let Ok(y) | Err(y) = x; = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable -error: aborting due to 6 previous errors +error[E0019]: constant contains unimplemented expression type + --> $DIR/feature-gate-const-fn.rs:31:25 + | +LL | let Ok(y) | Err(y) = x; + | ^ + +error[E0019]: constant contains unimplemented expression type + --> $DIR/feature-gate-const-fn.rs:31:16 + | +LL | let Ok(y) | Err(y) = x; + | ^ + +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0019, E0658. +For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs index f6b317886bfad..4489303638358 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs @@ -6,7 +6,6 @@ fn foo(res: Result) -> u32 { let Ok(x) = res; //~^ ERROR refutable pattern x - //~^ ERROR use of possibly-uninitialized variable: `x` } fn main() { diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index f9ae75b18317d..aa23aed4b425a 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -11,13 +11,6 @@ help: you might want to use `if let` to ignore the variant that isn't matched LL | if let Ok(x) = res { /* */ } | -error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/recursive-types-are-not-uninhabited.rs:8:5 - | -LL | x - | ^ use of possibly-uninitialized `x` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr index 1f1211aa198f8..612fae208cc9d 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr @@ -65,13 +65,18 @@ LL | match &(e.clone(), e.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | &(Either::One(_t), Either::Two(_u)) - | ----------------------------------- - | | | | - | | | ...and here - | | data moved here - | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` + | -- -- ...and here + | | + | data moved here | = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider removing the `&` + | +LL | (Either::One(_t), Either::Two(_u)) +LL | +LL | +LL | | &(Either::Two(_t), Either::One(_u)) => (), + | error[E0507]: cannot move out of a shared reference --> $DIR/duplicate-suggestions.rs:70:11 @@ -170,13 +175,18 @@ LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | &mut (Either::One(_t), Either::Two(_u)) - | --------------------------------------- - | | | | - | | | ...and here - | | data moved here - | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` + | -- -- ...and here + | | + | data moved here | = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider removing the `&mut` + | +LL | (Either::One(_t), Either::Two(_u)) +LL | +LL | +LL | | &mut (Either::Two(_t), Either::One(_u)) => (), + | error[E0507]: cannot move out of a mutable reference --> $DIR/duplicate-suggestions.rs:122:11 diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr index ac91ac43736f9..5550e097cf554 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr @@ -263,11 +263,18 @@ LL | match r { | ^ LL | LL | &Either::One(_t) - | ---------------- - | | | - | | data moved here - | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait - | help: consider removing the `&`: `Either::One(_t)` + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: consider removing the `&` + | +LL | Either::One(_t) +LL | +LL | +LL | | &Either::Two(_t) => (), + | error[E0507]: cannot move out of `r.0` which is behind a shared reference --> $DIR/simple.rs:188:11 @@ -502,11 +509,18 @@ LL | match &e { | ^^ LL | LL | &Either::One(_t) - | ---------------- - | | | - | | data moved here - | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait - | help: consider removing the `&`: `Either::One(_t)` + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: consider removing the `&` + | +LL | Either::One(_t) +LL | +LL | +LL | | &Either::Two(_t) => (), + | error[E0507]: cannot move out of a shared reference --> $DIR/simple.rs:308:11 @@ -571,11 +585,18 @@ LL | match &mut em { | ^^^^^^^ LL | LL | &mut Either::One(_t) - | -------------------- - | | | - | | data moved here - | | move occurs because `_t` has type `X`, which does not implement the `Copy` trait - | help: consider removing the `&mut`: `Either::One(_t)` + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: consider removing the `&mut` + | +LL | Either::One(_t) +LL | +LL | +LL | | &mut Either::Two(_t) => (), + | error[E0507]: cannot move out of a mutable reference --> $DIR/simple.rs:343:11 From 0b1ff27cd8968454771d419703873e3f98caf2eb Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sun, 14 Jul 2019 01:33:02 +0000 Subject: [PATCH 0766/1253] Basic run-pass tests for or-patterns Add some basic run-pass ui tests for or-patterns. --- src/test/ui/or-patterns/basic-switch.rs | 33 +++++++++++++ src/test/ui/or-patterns/basic-switchint.rs | 57 ++++++++++++++++++++++ src/test/ui/or-patterns/mix-with-wild.rs | 19 ++++++++ src/test/ui/or-patterns/struct-like.rs | 42 ++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 src/test/ui/or-patterns/basic-switch.rs create mode 100644 src/test/ui/or-patterns/basic-switchint.rs create mode 100644 src/test/ui/or-patterns/mix-with-wild.rs create mode 100644 src/test/ui/or-patterns/struct-like.rs diff --git a/src/test/ui/or-patterns/basic-switch.rs b/src/test/ui/or-patterns/basic-switch.rs new file mode 100644 index 0000000000000..6daa9d9255b80 --- /dev/null +++ b/src/test/ui/or-patterns/basic-switch.rs @@ -0,0 +1,33 @@ +// Test basic or-patterns when the target pattern type will be lowered to a +// `Switch` (an `enum`). + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(x: Option) -> bool { + match x { + // most simple case + Some(Test::Bar | Test::Qux) => true, + // wild case + Some(_) => false, + // empty case + None => false, + } +} + +fn main() { + assert!(!test(Some(Test::Foo))); + assert!(test(Some(Test::Bar))); + assert!(!test(Some(Test::Baz))); + assert!(test(Some(Test::Qux))); + assert!(!test(None)) +} diff --git a/src/test/ui/or-patterns/basic-switchint.rs b/src/test/ui/or-patterns/basic-switchint.rs new file mode 100644 index 0000000000000..2ae5f2681655a --- /dev/null +++ b/src/test/ui/or-patterns/basic-switchint.rs @@ -0,0 +1,57 @@ +// Test basic or-patterns when the target pattern type will be lowered to +// a `SwitchInt`. This will happen when the target type is an integer. + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Foo { + One(usize), + Two(usize, usize), +} + +fn test_foo(x: Foo) -> MatchArm { + match x { + // normal pattern. + Foo::One(0) | Foo::One(1) | Foo::One(2) => MatchArm::Arm(0), + // most simple or-pattern. + Foo::One(42 | 255) => MatchArm::Arm(1), + // multiple or-patterns for one structure. + Foo::Two(42 | 255, 1024 | 2048) => MatchArm::Arm(2), + // mix of pattern types in one or-pattern (range). + // + // FIXME(dlrobertson | Nadrieril): Fix or-pattern completeness and + // unreachabilitychecks for ranges. + Foo::One(100 | 110..=120 | 210..=220) => MatchArm::Arm(3), + // multiple or-patterns with wild. + Foo::Two(0..=10 | 100..=110, 0 | _) => MatchArm::Arm(4), + // wild + _ => MatchArm::Wild, + } +} + +fn main() { + // `Foo` tests. + assert_eq!(test_foo(Foo::One(0)), MatchArm::Arm(0)); + assert_eq!(test_foo(Foo::One(42)), MatchArm::Arm(1)); + assert_eq!(test_foo(Foo::One(43)), MatchArm::Wild); + assert_eq!(test_foo(Foo::One(255)), MatchArm::Arm(1)); + assert_eq!(test_foo(Foo::One(256)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(42, 1023)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(255, 2048)), MatchArm::Arm(2)); + assert_eq!(test_foo(Foo::One(100)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(115)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(105)), MatchArm::Wild); + assert_eq!(test_foo(Foo::One(215)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(121)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(0, 42)), MatchArm::Arm(4)); + assert_eq!(test_foo(Foo::Two(100, 0)), MatchArm::Arm(4)); + assert_eq!(test_foo(Foo::Two(42, 0)), MatchArm::Wild); +} diff --git a/src/test/ui/or-patterns/mix-with-wild.rs b/src/test/ui/or-patterns/mix-with-wild.rs new file mode 100644 index 0000000000000..37f20df1b312d --- /dev/null +++ b/src/test/ui/or-patterns/mix-with-wild.rs @@ -0,0 +1,19 @@ +// Test that an or-pattern works with a wild pattern. This tests two things: +// +// 1) The Wild pattern should cause the pattern to always succeed. +// 2) or-patterns should work with simplifyable patterns. + +// run-pass +#![feature(or_patterns)] + +pub fn test(x: Option) -> bool { + match x { + Some(0 | _) => true, + _ => false, + } +} + +fn main() { + assert!(test(Some(42))); + assert!(!test(None)); +} diff --git a/src/test/ui/or-patterns/struct-like.rs b/src/test/ui/or-patterns/struct-like.rs new file mode 100644 index 0000000000000..3794a8b6c1510 --- /dev/null +++ b/src/test/ui/or-patterns/struct-like.rs @@ -0,0 +1,42 @@ +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug)] +enum Other { + One, + Two, + Three, +} + +#[derive(Debug)] +enum Test { + Foo { first: usize, second: usize }, + Bar { other: Option }, + Baz, +} + +fn test(x: Option) -> bool { + match x { + Some( + Test::Foo { first: 1024 | 2048, second: 2048 | 4096 } + | Test::Bar { other: Some(Other::One | Other::Two) }, + ) => true, + // wild case + Some(_) => false, + // empty case + None => false, + } +} + +fn main() { + assert!(test(Some(Test::Foo { first: 1024, second: 4096 }))); + assert!(!test(Some(Test::Foo { first: 2048, second: 8192 }))); + assert!(!test(Some(Test::Foo { first: 42, second: 2048 }))); + assert!(test(Some(Test::Bar { other: Some(Other::One) }))); + assert!(test(Some(Test::Bar { other: Some(Other::Two) }))); + assert!(!test(Some(Test::Bar { other: Some(Other::Three) }))); + assert!(!test(Some(Test::Bar { other: None }))); + assert!(!test(Some(Test::Baz))); + assert!(!test(None)); +} From 632d75e057743b7e3145360c6ffe82b987c1df5b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 08:38:28 +0900 Subject: [PATCH 0767/1253] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index c0f39cfb46620..ea85b4c7fb982 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit c0f39cfb466202a1dbe8368ca177848083dc34cb +Subproject commit ea85b4c7fb9826f72bd4ab743a703a34c75a40f0 From ae22bf9d42abb7fc5ae4619a5feaafc61aa0c539 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 09:02:54 +0900 Subject: [PATCH 0768/1253] Catch more ICEs --- src/test/ui/type-alias-impl-trait/issue-63279.rs | 2 ++ src/test/ui/type-alias-impl-trait/issue-63279.stderr | 4 ++-- .../issue-65679-inst-opaque-ty-from-val-twice.rs | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs index 586ff7a31587f..b97192a2aed4a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.rs +++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zsave-analysis + #![feature(type_alias_impl_trait)] type Closure = impl FnOnce(); //~ ERROR: type mismatch resolving diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr index 053ccee378542..bef4d01093c62 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,5 +1,5 @@ -error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:6:5: 6:28] as std::ops::FnOnce<()>>::Output == ()` - --> $DIR/issue-63279.rs:3:1 +error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:8:5: 8:28] as std::ops::FnOnce<()>>::Output == ()` + --> $DIR/issue-63279.rs:5:1 | LL | type Closure = impl FnOnce(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()` diff --git a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index 12eb75ae4c019..26d97cea989c5 100644 --- a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zsave-analysis // check-pass #![feature(type_alias_impl_trait)] From c377ed606c1abfb240321f26cade940946c768e6 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 09:23:47 +0900 Subject: [PATCH 0769/1253] Fix ICE with save-analysis --- src/librustc_save_analysis/dump_visitor.rs | 4 ++-- src/test/ui/issues/issue-26459.rs | 2 ++ src/test/ui/issues/issue-26459.stderr | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 09c261cdc2388..3f436a1e27c2c 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -866,8 +866,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // FIXME do something with _path? let hir_id = self.tcx.hir().node_to_hir_id(p.id); let adt = match self.save_ctxt.tables.node_type_opt(hir_id) { - Some(ty) => ty.ty_adt_def().unwrap(), - None => { + Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(), + _ => { visit::walk_pat(self, p); return; } diff --git a/src/test/ui/issues/issue-26459.rs b/src/test/ui/issues/issue-26459.rs index 79791e0e06ad5..2ba05a0a47e01 100644 --- a/src/test/ui/issues/issue-26459.rs +++ b/src/test/ui/issues/issue-26459.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zsave-analysis + fn main() { match 'a' { char{ch} => true diff --git a/src/test/ui/issues/issue-26459.stderr b/src/test/ui/issues/issue-26459.stderr index 187369263a446..9f594990c6de8 100644 --- a/src/test/ui/issues/issue-26459.stderr +++ b/src/test/ui/issues/issue-26459.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found builtin type `char` - --> $DIR/issue-26459.rs:3:9 + --> $DIR/issue-26459.rs:5:9 | LL | char{ch} => true | ^^^^ not a struct, variant or union type From 276734d6a4997088b6d2e7416f5d4c07b4c8acf5 Mon Sep 17 00:00:00 2001 From: David Ross Date: Sat, 1 Feb 2020 18:04:07 -0800 Subject: [PATCH 0770/1253] Fix 59191 This adds an explicit error for when macros replace the crate root with a non-module item. --- src/librustc_expand/expand.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index ea459064b0957..1aa4f11a13026 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -363,7 +363,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> { krate.attrs = vec![]; krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true }; } - _ => unreachable!(), + Some(ast::Item { span, kind, .. }) => { + self.cx.span_fatal( + span, + &format!( + "expected crate top-level item to be a module after macro expansion, found a {}", + kind.descriptive_variant() + ), + ); + } }; self.cx.trace_macros_diag(); krate From 410114b9d243020482689a94f7b254600f4d819e Mon Sep 17 00:00:00 2001 From: David Ross Date: Sat, 1 Feb 2020 18:07:26 -0800 Subject: [PATCH 0771/1253] Add tests for issue 59191 --- src/test/ui/proc-macro/auxiliary/issue-59191.rs | 16 ++++++++++++++++ .../issue-59191-replace-root-with-fn.rs | 7 +++++++ .../issue-59191-replace-root-with-fn.stderr | 8 ++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/issue-59191.rs create mode 100644 src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs create mode 100644 src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr diff --git a/src/test/ui/proc-macro/auxiliary/issue-59191.rs b/src/test/ui/proc-macro/auxiliary/issue-59191.rs new file mode 100644 index 0000000000000..d9ee77067ecb7 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-59191.rs @@ -0,0 +1,16 @@ +// edition:2018 +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn no_main(_attrs: TokenStream, _input: TokenStream) -> TokenStream { + let new_krate = r#" + fn main() {} + "#; + new_krate.parse().unwrap() +} diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs new file mode 100644 index 0000000000000..039878af56eb6 --- /dev/null +++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -0,0 +1,7 @@ +// edition:2018 +// aux-crate:issue_59191=issue-59191.rs +// Test that using a macro to replace the entire crate tree with a non-'mod' item errors out nicely. +// `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`. +#![feature(custom_inner_attributes)] +#![issue_59191::no_main] +//~^ ERROR expected crate top-level item to be a module after macro expansion, found a function diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr new file mode 100644 index 0000000000000..1bda86551d418 --- /dev/null +++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr @@ -0,0 +1,8 @@ +error: expected crate top-level item to be a module after macro expansion, found a function + --> $DIR/issue-59191-replace-root-with-fn.rs:6:1 + | +LL | #![issue_59191::no_main] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 9fa54e594b371bda6e8a2bb570e645d5aa61820b Mon Sep 17 00:00:00 2001 From: Tyler Lanphear Date: Sat, 1 Feb 2020 19:11:33 -0500 Subject: [PATCH 0772/1253] stdarch: update submodule. --- src/libstd/lib.rs | 6 ------ src/libstd/tests/run-time-detect.rs | 1 + src/stdarch | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bc07c6b487b17..2f27bfc225549 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -335,12 +335,6 @@ extern crate libc; #[allow(unused_extern_crates)] extern crate unwind; -// Only needed for now for the `std_detect` module until that crate changes to -// use `cfg_if::cfg_if!` -#[macro_use] -#[cfg(not(test))] -extern crate cfg_if; - // During testing, this crate is not actually the "real" std library, but rather // it links to the real std library, which was compiled from this same source // code. So any lang items std defines are conditionally excluded (or else they diff --git a/src/libstd/tests/run-time-detect.rs b/src/libstd/tests/run-time-detect.rs index e39cc1eed5e4a..2e6d1bc8efd3f 100644 --- a/src/libstd/tests/run-time-detect.rs +++ b/src/libstd/tests/run-time-detect.rs @@ -6,6 +6,7 @@ all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")), all(target_arch = "powerpc", target_os = "linux"), all(target_arch = "powerpc64", target_os = "linux"), + any(target_arch = "x86", target_arch = "x86_64"), ), feature(stdsimd) )] diff --git a/src/stdarch b/src/stdarch index e0ab2c165ace0..dea57529b3695 160000 --- a/src/stdarch +++ b/src/stdarch @@ -1 +1 @@ -Subproject commit e0ab2c165ace03a61139b61f1d9b86b07028850f +Subproject commit dea57529b3695605909e7d327bb6551d7a10c788 From f6c389472448257a91c2f6713061cd69025c766f Mon Sep 17 00:00:00 2001 From: Tyler Lanphear Date: Sun, 2 Feb 2020 01:05:53 -0500 Subject: [PATCH 0773/1253] compiletest: error if `compile-fail` header in ui test. --- .../bad-bounds-on-assoc-in-trait.rs | 1 - .../bad-bounds-on-assoc-in-trait.stderr | 10 +- .../ui/associated-type-bounds/duplicate.rs | 1 - .../associated-type-bounds/duplicate.stderr | 194 +++++++++--------- .../implied-region-constraints.nll.stderr | 4 +- .../implied-region-constraints.rs | 2 - .../implied-region-constraints.stderr | 4 +- .../ui/associated-type-bounds/inside-adt.rs | 1 - .../associated-type-bounds/inside-adt.stderr | 36 ++-- src/test/ui/async-await/async-fn-nonsend.rs | 1 - .../ui/async-await/async-fn-nonsend.stderr | 12 +- src/test/ui/async-await/no-async-const.rs | 1 - src/test/ui/async-await/no-async-const.stderr | 2 +- src/test/ui/async-await/no-const-async.rs | 1 - src/test/ui/async-await/no-const-async.stderr | 4 +- .../no-move-across-await-struct.rs | 1 - .../no-move-across-await-struct.stderr | 2 +- .../async-await/no-move-across-await-tuple.rs | 1 - .../no-move-across-await-tuple.stderr | 2 +- .../no-non-guaranteed-initialization.rs | 1 - .../no-non-guaranteed-initialization.stderr | 2 +- .../two-phase-nonrecv-autoref.nll.stderr | 14 +- .../ui/borrowck/two-phase-nonrecv-autoref.rs | 7 - .../ui/impl-trait/bound-normalization-fail.rs | 1 - .../bound-normalization-fail.stderr | 8 +- ...f_types_pin_lifetime_impl_trait.nll.stderr | 2 +- ...rary_self_types_pin_lifetime_impl_trait.rs | 2 - ..._self_types_pin_lifetime_impl_trait.stderr | 8 +- ...elf_types_pin_lifetime_mismatch.nll.stderr | 6 +- ...itrary_self_types_pin_lifetime_mismatch.rs | 2 - ...ry_self_types_pin_lifetime_mismatch.stderr | 6 +- .../reservation-impl-coherence-conflict.rs | 2 - ...reservation-impl-coherence-conflict.stderr | 2 +- .../reservation-impl-no-use.rs | 2 - .../reservation-impl-no-use.stderr | 2 +- .../ui/traits/wf-trait-object-maybe-bound.rs | 2 - .../traits/wf-trait-object-maybe-bound.stderr | 10 +- src/tools/compiletest/src/header.rs | 3 + 38 files changed, 168 insertions(+), 194 deletions(-) diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs index 78704a9b51239..3db5e468b35bf 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -1,4 +1,3 @@ -// compile-fail // ignore-tidy-linelength // NOTE: rustc cannot currently handle bounds of the form `for<'a> >::Assoc: Baz`. diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 9f6a73cfe3910..5303a09644d50 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -1,5 +1,5 @@ error[E0277]: `>::App` doesn't implement `std::fmt::Debug` - --> $DIR/bad-bounds-on-assoc-in-trait.rs:32:6 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:31:6 | LL | impl Case1 for S1 { | ^^^^^ `>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` @@ -7,7 +7,7 @@ LL | impl Case1 for S1 { = help: the trait `for<'a> std::fmt::Debug` is not implemented for `>::App` error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator - --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | fn assume_case1() { | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` @@ -24,7 +24,7 @@ LL | | } = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | trait Case1 { | ----------- required by `Case1` @@ -44,7 +44,7 @@ LL | | } = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | trait Case1 { | ----------- required by `Case1` @@ -64,7 +64,7 @@ LL | | } = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` - --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | trait Case1 { | ----------- required by `Case1` diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 65ca017e2f269..f8d230da36523 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -1,4 +1,3 @@ -// compile-fail // ignore-tidy-linelength #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index defa62994e9e1..df1151d876c04 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/duplicate.rs:6:12 + --> $DIR/duplicate.rs:5:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:11:36 + --> $DIR/duplicate.rs:10:36 | LL | struct SI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -15,7 +15,7 @@ LL | struct SI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:13:36 + --> $DIR/duplicate.rs:12:36 | LL | struct SI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -23,7 +23,7 @@ LL | struct SI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:15:39 + --> $DIR/duplicate.rs:14:39 | LL | struct SI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -31,7 +31,7 @@ LL | struct SI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:17:45 + --> $DIR/duplicate.rs:16:45 | LL | struct SW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -39,7 +39,7 @@ LL | struct SW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:19:45 + --> $DIR/duplicate.rs:18:45 | LL | struct SW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -47,7 +47,7 @@ LL | struct SW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:21:48 + --> $DIR/duplicate.rs:20:48 | LL | struct SW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -55,7 +55,7 @@ LL | struct SW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:24:34 + --> $DIR/duplicate.rs:23:34 | LL | enum EI1> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -63,7 +63,7 @@ LL | enum EI1> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:26:34 + --> $DIR/duplicate.rs:25:34 | LL | enum EI2> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -71,7 +71,7 @@ LL | enum EI2> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:28:37 + --> $DIR/duplicate.rs:27:37 | LL | enum EI3> { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -79,7 +79,7 @@ LL | enum EI3> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:30:43 + --> $DIR/duplicate.rs:29:43 | LL | enum EW1 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -87,7 +87,7 @@ LL | enum EW1 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:32:43 + --> $DIR/duplicate.rs:31:43 | LL | enum EW2 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -95,7 +95,7 @@ LL | enum EW2 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:34:46 + --> $DIR/duplicate.rs:33:46 | LL | enum EW3 where T: Iterator { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -103,7 +103,7 @@ LL | enum EW3 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:37:35 + --> $DIR/duplicate.rs:36:35 | LL | union UI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -111,7 +111,7 @@ LL | union UI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:39:35 + --> $DIR/duplicate.rs:38:35 | LL | union UI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -119,7 +119,7 @@ LL | union UI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:41:38 + --> $DIR/duplicate.rs:40:38 | LL | union UI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -127,7 +127,7 @@ LL | union UI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:43:44 + --> $DIR/duplicate.rs:42:44 | LL | union UW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -135,7 +135,7 @@ LL | union UW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:45:44 + --> $DIR/duplicate.rs:44:44 | LL | union UW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -143,7 +143,7 @@ LL | union UW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:47:47 + --> $DIR/duplicate.rs:46:47 | LL | union UW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -151,7 +151,7 @@ LL | union UW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:50:32 + --> $DIR/duplicate.rs:49:32 | LL | fn FI1>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -159,7 +159,7 @@ LL | fn FI1>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:52:32 + --> $DIR/duplicate.rs:51:32 | LL | fn FI2>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -167,7 +167,7 @@ LL | fn FI2>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:54:35 + --> $DIR/duplicate.rs:53:35 | LL | fn FI3>() {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -175,7 +175,7 @@ LL | fn FI3>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:56:43 + --> $DIR/duplicate.rs:55:43 | LL | fn FW1() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -183,7 +183,7 @@ LL | fn FW1() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:58:43 + --> $DIR/duplicate.rs:57:43 | LL | fn FW2() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -191,7 +191,7 @@ LL | fn FW2() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:60:46 + --> $DIR/duplicate.rs:59:46 | LL | fn FW3() where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -199,7 +199,7 @@ LL | fn FW3() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:69:40 + --> $DIR/duplicate.rs:68:40 | LL | fn FAPIT1(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -207,7 +207,7 @@ LL | fn FAPIT1(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:71:40 + --> $DIR/duplicate.rs:70:40 | LL | fn FAPIT2(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -215,7 +215,7 @@ LL | fn FAPIT2(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:73:43 + --> $DIR/duplicate.rs:72:43 | LL | fn FAPIT3(_: impl Iterator) {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -223,7 +223,7 @@ LL | fn FAPIT3(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:63:42 + --> $DIR/duplicate.rs:62:42 | LL | fn FRPIT1() -> impl Iterator { iter::empty() } | ---------- ^^^^^^^^^^ re-bound here @@ -231,7 +231,7 @@ LL | fn FRPIT1() -> impl Iterator { iter::empty() } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:65:42 + --> $DIR/duplicate.rs:64:42 | LL | fn FRPIT2() -> impl Iterator { iter::empty() } | ---------- ^^^^^^^^^^ re-bound here @@ -239,7 +239,7 @@ LL | fn FRPIT2() -> impl Iterator { iter::empty() } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:67:45 + --> $DIR/duplicate.rs:66:45 | LL | fn FRPIT3() -> impl Iterator { iter::empty() } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -247,7 +247,7 @@ LL | fn FRPIT3() -> impl Iterator { iter::empty() | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:76:39 + --> $DIR/duplicate.rs:75:39 | LL | const CIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -255,7 +255,7 @@ LL | const CIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:78:39 + --> $DIR/duplicate.rs:77:39 | LL | const CIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -263,7 +263,7 @@ LL | const CIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:80:42 + --> $DIR/duplicate.rs:79:42 | LL | const CIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -271,7 +271,7 @@ LL | const CIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:82:40 + --> $DIR/duplicate.rs:81:40 | LL | static SIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -279,7 +279,7 @@ LL | static SIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:84:40 + --> $DIR/duplicate.rs:83:40 | LL | static SIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -287,7 +287,7 @@ LL | static SIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:86:43 + --> $DIR/duplicate.rs:85:43 | LL | static SIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -295,7 +295,7 @@ LL | static SIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:89:46 + --> $DIR/duplicate.rs:88:46 | LL | fn lit1() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -303,7 +303,7 @@ LL | fn lit1() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:91:46 + --> $DIR/duplicate.rs:90:46 | LL | fn lit2() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -311,7 +311,7 @@ LL | fn lit2() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:93:49 + --> $DIR/duplicate.rs:92:49 | LL | fn lit3() { let _: impl Iterator = iter::empty(); } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -319,7 +319,7 @@ LL | fn lit3() { let _: impl Iterator = iter::empt | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:96:35 + --> $DIR/duplicate.rs:95:35 | LL | type TAI1> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -327,7 +327,7 @@ LL | type TAI1> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:98:35 + --> $DIR/duplicate.rs:97:35 | LL | type TAI2> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -335,7 +335,7 @@ LL | type TAI2> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:100:38 + --> $DIR/duplicate.rs:99:38 | LL | type TAI3> = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -343,7 +343,7 @@ LL | type TAI3> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:102:44 + --> $DIR/duplicate.rs:101:44 | LL | type TAW1 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -351,7 +351,7 @@ LL | type TAW1 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:104:44 + --> $DIR/duplicate.rs:103:44 | LL | type TAW2 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -359,7 +359,7 @@ LL | type TAW2 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:106:47 + --> $DIR/duplicate.rs:105:47 | LL | type TAW3 where T: Iterator = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -367,13 +367,13 @@ LL | type TAW3 where T: Iterator = T; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:109:1 + --> $DIR/duplicate.rs:108:1 | LL | type ETAI1> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:109:36 + --> $DIR/duplicate.rs:108:36 | LL | type ETAI1> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -381,13 +381,13 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:114:1 + --> $DIR/duplicate.rs:113:1 | LL | type ETAI2> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:114:36 + --> $DIR/duplicate.rs:113:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -395,13 +395,13 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:119:1 + --> $DIR/duplicate.rs:118:1 | LL | type ETAI3> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:119:39 + --> $DIR/duplicate.rs:118:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -409,13 +409,13 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:124:1 + --> $DIR/duplicate.rs:123:1 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:124:40 + --> $DIR/duplicate.rs:123:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -423,13 +423,13 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:129:1 + --> $DIR/duplicate.rs:128:1 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:129:40 + --> $DIR/duplicate.rs:128:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -437,13 +437,13 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:134:1 + --> $DIR/duplicate.rs:133:1 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:134:43 + --> $DIR/duplicate.rs:133:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -451,7 +451,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:140:36 + --> $DIR/duplicate.rs:139:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -459,7 +459,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:142:36 + --> $DIR/duplicate.rs:141:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -467,7 +467,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:144:39 + --> $DIR/duplicate.rs:143:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -475,7 +475,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:146:34 + --> $DIR/duplicate.rs:145:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -483,7 +483,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:148:34 + --> $DIR/duplicate.rs:147:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -491,7 +491,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:150:37 + --> $DIR/duplicate.rs:149:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -499,7 +499,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:152:45 + --> $DIR/duplicate.rs:151:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -507,7 +507,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:154:45 + --> $DIR/duplicate.rs:153:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -515,7 +515,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:156:48 + --> $DIR/duplicate.rs:155:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -523,7 +523,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:158:46 + --> $DIR/duplicate.rs:157:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -531,7 +531,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:158:46 + --> $DIR/duplicate.rs:157:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -539,7 +539,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:161:46 + --> $DIR/duplicate.rs:160:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -547,7 +547,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:161:46 + --> $DIR/duplicate.rs:160:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -555,7 +555,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:164:49 + --> $DIR/duplicate.rs:163:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -563,7 +563,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:164:49 + --> $DIR/duplicate.rs:163:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -571,7 +571,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:167:43 + --> $DIR/duplicate.rs:166:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -579,7 +579,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:169:43 + --> $DIR/duplicate.rs:168:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -587,7 +587,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:171:46 + --> $DIR/duplicate.rs:170:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -595,7 +595,7 @@ LL | trait TRA3 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:174:40 + --> $DIR/duplicate.rs:173:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -603,7 +603,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:178:44 + --> $DIR/duplicate.rs:177:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -611,7 +611,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:182:43 + --> $DIR/duplicate.rs:181:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -619,109 +619,109 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:109:24 + --> $DIR/duplicate.rs:108:24 | LL | type ETAI1> = impl Copy; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:109:36 + --> $DIR/duplicate.rs:108:36 | LL | type ETAI1> = impl Copy; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:114:24 + --> $DIR/duplicate.rs:113:24 | LL | type ETAI2> = impl Copy; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:114:36 + --> $DIR/duplicate.rs:113:36 | LL | type ETAI2> = impl Copy; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:119:24 + --> $DIR/duplicate.rs:118:24 | LL | type ETAI3> = impl Copy; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:119:39 + --> $DIR/duplicate.rs:118:39 | LL | type ETAI3> = impl Copy; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:124:28 + --> $DIR/duplicate.rs:123:28 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:124:40 + --> $DIR/duplicate.rs:123:40 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:129:28 + --> $DIR/duplicate.rs:128:28 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:129:40 + --> $DIR/duplicate.rs:128:40 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:134:28 + --> $DIR/duplicate.rs:133:28 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:134:43 + --> $DIR/duplicate.rs:133:43 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:174:28 + --> $DIR/duplicate.rs:173:28 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:174:40 + --> $DIR/duplicate.rs:173:40 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:178:32 + --> $DIR/duplicate.rs:177:32 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:178:44 + --> $DIR/duplicate.rs:177:44 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:182:28 + --> $DIR/duplicate.rs:181:28 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:182:43 + --> $DIR/duplicate.rs:181:43 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr index b8c54b13d8b4d..cddce8777eab7 100644 --- a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/implied-region-constraints.rs:19:56 + --> $DIR/implied-region-constraints.rs:17:56 | LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; = help: consider adding the following bound: `'a: 'b` error: lifetime may not live long enough - --> $DIR/implied-region-constraints.rs:40:64 + --> $DIR/implied-region-constraints.rs:38:64 | LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) | -- -- lifetime `'b` defined here diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.rs b/src/test/ui/associated-type-bounds/implied-region-constraints.rs index 4dbaab50a61db..ccad947f7f074 100644 --- a/src/test/ui/associated-type-bounds/implied-region-constraints.rs +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.rs @@ -1,5 +1,3 @@ -// compile-fail - #![feature(associated_type_bounds)] trait Tr1 { type As1; } diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr index 60c6e8a80fb6a..c338e38d28f71 100644 --- a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/implied-region-constraints.rs:19:64 + --> $DIR/implied-region-constraints.rs:17:64 | LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) | ------------- this type is declared with multiple lifetimes... @@ -8,7 +8,7 @@ LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; | ^^^^^ ...but data with one lifetime flows into the other here error[E0623]: lifetime mismatch - --> $DIR/implied-region-constraints.rs:40:72 + --> $DIR/implied-region-constraints.rs:38:72 | LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) | -------------- this type is declared with multiple lifetimes... diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs index 59ce9496d28f0..b74c03829b48b 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.rs +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -1,4 +1,3 @@ -// compile-fail #![feature(associated_type_bounds)] #![feature(untagged_unions)] diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr index 9c4d03e900940..a532bb0c76697 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.stderr +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -1,107 +1,107 @@ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:5:29 + --> $DIR/inside-adt.rs:4:29 | LL | struct S1 { f: dyn Iterator } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:8:33 + --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box> } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:11:29 + --> $DIR/inside-adt.rs:10:29 | LL | struct S3 { f: dyn Iterator } | ^^^^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:15:26 + --> $DIR/inside-adt.rs:14:26 | LL | enum E1 { V(dyn Iterator) } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:18:30 + --> $DIR/inside-adt.rs:17:30 | LL | enum E2 { V(Box>) } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:21:26 + --> $DIR/inside-adt.rs:20:26 | LL | enum E3 { V(dyn Iterator) } | ^^^^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:25:28 + --> $DIR/inside-adt.rs:24:28 | LL | union U1 { f: dyn Iterator } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:28:32 + --> $DIR/inside-adt.rs:27:32 | LL | union U2 { f: Box> } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:31:28 + --> $DIR/inside-adt.rs:30:28 | LL | union U3 { f: dyn Iterator } | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:5:29 + --> $DIR/inside-adt.rs:4:29 | LL | struct S1 { f: dyn Iterator } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:8:33 + --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box> } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:11:29 + --> $DIR/inside-adt.rs:10:29 | LL | struct S3 { f: dyn Iterator } | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:15:26 + --> $DIR/inside-adt.rs:14:26 | LL | enum E1 { V(dyn Iterator) } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:18:30 + --> $DIR/inside-adt.rs:17:30 | LL | enum E2 { V(Box>) } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:21:26 + --> $DIR/inside-adt.rs:20:26 | LL | enum E3 { V(dyn Iterator) } | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:25:28 + --> $DIR/inside-adt.rs:24:28 | LL | union U1 { f: dyn Iterator } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:28:32 + --> $DIR/inside-adt.rs:27:32 | LL | union U2 { f: Box> } | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/inside-adt.rs:31:28 + --> $DIR/inside-adt.rs:30:28 | LL | union U3 { f: dyn Iterator } | ^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs index ceeebbca5195a..845941200fc95 100644 --- a/src/test/ui/async-await/async-fn-nonsend.rs +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 105fd23ecfb66..3a2c42b383700 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -1,5 +1,5 @@ error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:50:5 + --> $DIR/async-fn-nonsend.rs:49:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` @@ -9,7 +9,7 @@ LL | assert_send(local_dropped_before_await()); | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` note: future is not `Send` as this value is used across an await - --> $DIR/async-fn-nonsend.rs:25:5 + --> $DIR/async-fn-nonsend.rs:24:5 | LL | let x = non_send(); | - has type `impl std::fmt::Debug` @@ -20,7 +20,7 @@ LL | } | - `x` is later dropped here error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:52:5 + --> $DIR/async-fn-nonsend.rs:51:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` @@ -30,7 +30,7 @@ LL | assert_send(non_send_temporary_in_match()); | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` note: future is not `Send` as this value is used across an await - --> $DIR/async-fn-nonsend.rs:34:20 + --> $DIR/async-fn-nonsend.rs:33:20 | LL | match Some(non_send()) { | ---------- has type `impl std::fmt::Debug` @@ -41,7 +41,7 @@ LL | } | - `non_send()` is later dropped here error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:54:5 + --> $DIR/async-fn-nonsend.rs:53:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` @@ -51,7 +51,7 @@ LL | assert_send(non_sync_with_method_call()); | = help: the trait `std::marker::Send` is not implemented for `dyn std::fmt::Write` note: future is not `Send` as this value is used across an await - --> $DIR/async-fn-nonsend.rs:43:9 + --> $DIR/async-fn-nonsend.rs:42:9 | LL | let f: &mut std::fmt::Formatter = panic!(); | - has type `&mut std::fmt::Formatter<'_>` diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs index 44f02d1a7b19b..64322990d0a93 100644 --- a/src/test/ui/async-await/no-async-const.rs +++ b/src/test/ui/async-await/no-async-const.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr index 05cdbff0bf042..d5b8b344abe62 100644 --- a/src/test/ui/async-await/no-async-const.stderr +++ b/src/test/ui/async-await/no-async-const.stderr @@ -1,5 +1,5 @@ error: expected one of `fn` or `unsafe`, found keyword `const` - --> $DIR/no-async-const.rs:5:11 + --> $DIR/no-async-const.rs:4:11 | LL | pub async const fn x() {} | ^^^^^ expected one of `fn` or `unsafe` diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index ef7edf8504952..55b27bd3fa1ac 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 7ed822a5cd5a1..62cd5c45d1950 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -1,11 +1,11 @@ error: expected identifier, found keyword `async` - --> $DIR/no-const-async.rs:5:11 + --> $DIR/no-const-async.rs:4:11 | LL | pub const async fn x() {} | ^^^^^ expected identifier, found keyword error: expected `:`, found keyword `fn` - --> $DIR/no-const-async.rs:5:17 + --> $DIR/no-const-async.rs:4:17 | LL | pub const async fn x() {} | ^^ expected `:` diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs index bef477bd256ec..51c9a42b3f4e3 100644 --- a/src/test/ui/async-await/no-move-across-await-struct.rs +++ b/src/test/ui/async-await/no-move-across-await-struct.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr index 88f147b8d9ddd..adfae09925fef 100644 --- a/src/test/ui/async-await/no-move-across-await-struct.stderr +++ b/src/test/ui/async-await/no-move-across-await-struct.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `s.x` - --> $DIR/no-move-across-await-struct.rs:8:5 + --> $DIR/no-move-across-await-struct.rs:7:5 | LL | needs_vec(s.x).await; | --- value moved here diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs index 565cbd7d5f4ae..a656332698c43 100644 --- a/src/test/ui/async-await/no-move-across-await-tuple.rs +++ b/src/test/ui/async-await/no-move-across-await-tuple.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr index fe98ecd599a23..a60fd9361a779 100644 --- a/src/test/ui/async-await/no-move-across-await-tuple.stderr +++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x.1` - --> $DIR/no-move-across-await-tuple.rs:9:5 + --> $DIR/no-move-across-await-tuple.rs:8:5 | LL | drop(x.1); | --- value moved here diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs index 6a34209d55289..24070fe33083c 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs @@ -1,4 +1,3 @@ -// compile-fail // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr index b9aa9924bb815..f5991f4bccac9 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -1,5 +1,5 @@ error[E0381]: use of possibly-uninitialized variable: `y` - --> $DIR/no-non-guaranteed-initialization.rs:10:5 + --> $DIR/no-non-guaranteed-initialization.rs:9:5 | LL | y | ^ use of possibly-uninitialized `y` diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr index baf122df5e268..21ae25c16bb78 100644 --- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr +++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `*f` as mutable more than once at a time - --> $DIR/two-phase-nonrecv-autoref.rs:58:11 + --> $DIR/two-phase-nonrecv-autoref.rs:51:11 | LL | f(f(10)); | - ^ second mutable borrow occurs here @@ -8,7 +8,7 @@ LL | f(f(10)); | first borrow later used by call error[E0382]: use of moved value: `f` - --> $DIR/two-phase-nonrecv-autoref.rs:66:11 + --> $DIR/two-phase-nonrecv-autoref.rs:59:11 | LL | fn twice_ten_so i32>(f: Box) { | - move occurs because `f` has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -18,7 +18,7 @@ LL | f(f(10)); | value moved here error[E0499]: cannot borrow `*f` as mutable more than once at a time - --> $DIR/two-phase-nonrecv-autoref.rs:72:11 + --> $DIR/two-phase-nonrecv-autoref.rs:65:11 | LL | f(f(10)); | - ^ second mutable borrow occurs here @@ -27,7 +27,7 @@ LL | f(f(10)); | first borrow later used by call error[E0382]: use of moved value: `f` - --> $DIR/two-phase-nonrecv-autoref.rs:80:11 + --> $DIR/two-phase-nonrecv-autoref.rs:73:11 | LL | fn twice_ten_oo(f: Box i32>) { | - move occurs because `f` has type `std::boxed::Box i32>`, which does not implement the `Copy` trait @@ -37,7 +37,7 @@ LL | f(f(10)); | value moved here error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/two-phase-nonrecv-autoref.rs:119:27 + --> $DIR/two-phase-nonrecv-autoref.rs:112:27 | LL | double_access(&mut a, &a); | ------------- ------ ^^ immutable borrow occurs here @@ -46,7 +46,7 @@ LL | double_access(&mut a, &a); | mutable borrow later used by call error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable - --> $DIR/two-phase-nonrecv-autoref.rs:145:7 + --> $DIR/two-phase-nonrecv-autoref.rs:138:7 | LL | i[i[3]] = 4; | --^---- @@ -56,7 +56,7 @@ LL | i[i[3]] = 4; | mutable borrow later used here error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable - --> $DIR/two-phase-nonrecv-autoref.rs:150:7 + --> $DIR/two-phase-nonrecv-autoref.rs:143:7 | LL | i[i[3]] = i[4]; | --^---- diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs index b29664e3d8cbd..918c7a1be197a 100644 --- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs +++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs @@ -13,13 +13,6 @@ // receivers (namely, in many cases demonstrated below, the error // would not arise). -// (If we revise the compiler or this test so that the g2p revision -// passes, turn the `rustc_attrs` feature back on and tag the `fn -// main` with `#[rustc_error]` so that this remains a valid -// compile-fail test.) -// -// #![feature(rustc_attrs)] - use std::ops::{Index, IndexMut}; fn foo(x: &mut u32, y: u32) { diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 235c1f80ef637..5bf3ec733f5d7 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -1,4 +1,3 @@ -// compile-fail // ignore-tidy-linelength // edition:2018 diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index fc4cddd02168e..22ba8342ff41f 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/bound-normalization-fail.rs:5:12 + --> $DIR/bound-normalization-fail.rs:4:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` - --> $DIR/bound-normalization-fail.rs:28:32 + --> $DIR/bound-normalization-fail.rs:27:32 | LL | fn foo_fail() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type @@ -19,13 +19,13 @@ LL | fn foo_fail() -> impl FooLike { = note: the return type of a function must have a statically known size error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:44:41 + --> $DIR/bound-normalization-fail.rs:43:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` - --> $DIR/bound-normalization-fail.rs:44:41 + --> $DIR/bound-normalization-fail.rs:43:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr index b76966e8693f2..73766c31b93b6 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:31 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } | - ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs index ad8959727cbee..5054568b18970 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs @@ -1,5 +1,3 @@ -// compile-fail - use std::pin::Pin; struct Foo; diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 9f5414995151b..47ab6fff83878 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,17 +1,17 @@ error: cannot infer an appropriate lifetime - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:44 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ^^^^ ...but this borrow... | | | this return type evaluates to the `'static` lifetime... | -note: ...can't outlive the anonymous lifetime #1 defined on the method body at 8:5 - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:5 +note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 8:5 +help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5 | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr index 8a0f1a804ad82..1a0904fcbba6e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46 | LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -8,7 +8,7 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | let's call the lifetime of this reference `'2` error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:69 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:69 | LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -17,7 +17,7 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | let's call the lifetime of this reference `'2` error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58 | LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | -- ---- has type `std::pin::Pin<&'1 Foo>` ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs index fc5f94201b81a..8291e44080b37 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs @@ -1,5 +1,3 @@ -// compile-fail - use std::pin::Pin; struct Foo; diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr index f3a7d14720171..6bb7ad7cdc7c2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46 | LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | ---- ---- ^ ...but data from `f` is returned here @@ -7,7 +7,7 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:76 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:76 | LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } | ---- ----------------- ^ ...but data from `f` is returned here @@ -15,7 +15,7 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58 | LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | ------ --- ^^^ ...but data from `arg` is returned here diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs index 775278c30cd4c..fa4a309315b47 100644 --- a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs +++ b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs @@ -1,5 +1,3 @@ -// compile-fail - // check that reservation impls are accounted for in negative reasoning. #![feature(rustc_attrs)] diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr index 47e141bd048eb..d76d3a91c8d3f 100644 --- a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr +++ b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `OtherTrait` for type `()`: - --> $DIR/reservation-impl-coherence-conflict.rs:13:1 + --> $DIR/reservation-impl-coherence-conflict.rs:11:1 | LL | impl OtherTrait for () {} | ---------------------- first implementation here diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs index 3391daaabe975..65a55d9e20936 100644 --- a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs +++ b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs @@ -1,5 +1,3 @@ -// compile-fail - // check that reservation impls can't be used as normal impls in positive reasoning. #![feature(rustc_attrs)] diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr index 0cd56b978f10c..794faff8848fe 100644 --- a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr +++ b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): MyTrait` is not satisfied - --> $DIR/reservation-impl-no-use.rs:12:26 + --> $DIR/reservation-impl-no-use.rs:10:26 | LL | trait MyTrait { fn foo(&self); } | -------------- required by `MyTrait::foo` diff --git a/src/test/ui/traits/wf-trait-object-maybe-bound.rs b/src/test/ui/traits/wf-trait-object-maybe-bound.rs index f24c1301c53ab..17771e976ef3b 100644 --- a/src/test/ui/traits/wf-trait-object-maybe-bound.rs +++ b/src/test/ui/traits/wf-trait-object-maybe-bound.rs @@ -1,5 +1,3 @@ -// compile-fail - // Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects). trait Foo {} diff --git a/src/test/ui/traits/wf-trait-object-maybe-bound.stderr b/src/test/ui/traits/wf-trait-object-maybe-bound.stderr index 11187342d59f2..4a570efcb5dbc 100644 --- a/src/test/ui/traits/wf-trait-object-maybe-bound.stderr +++ b/src/test/ui/traits/wf-trait-object-maybe-bound.stderr @@ -1,29 +1,29 @@ error: `?Trait` is not permitted in trait object types - --> $DIR/wf-trait-object-maybe-bound.rs:7:15 + --> $DIR/wf-trait-object-maybe-bound.rs:5:15 | LL | type _0 = dyn ?Sized + Foo; | ^^^^^^ error: `?Trait` is not permitted in trait object types - --> $DIR/wf-trait-object-maybe-bound.rs:10:21 + --> $DIR/wf-trait-object-maybe-bound.rs:8:21 | LL | type _1 = dyn Foo + ?Sized; | ^^^^^^ error: `?Trait` is not permitted in trait object types - --> $DIR/wf-trait-object-maybe-bound.rs:13:21 + --> $DIR/wf-trait-object-maybe-bound.rs:11:21 | LL | type _2 = dyn Foo + ?Sized + ?Sized; | ^^^^^^ error: `?Trait` is not permitted in trait object types - --> $DIR/wf-trait-object-maybe-bound.rs:13:30 + --> $DIR/wf-trait-object-maybe-bound.rs:11:30 | LL | type _2 = dyn Foo + ?Sized + ?Sized; | ^^^^^^ error: `?Trait` is not permitted in trait object types - --> $DIR/wf-trait-object-maybe-bound.rs:17:15 + --> $DIR/wf-trait-object-maybe-bound.rs:15:15 | LL | type _3 = dyn ?Sized + Foo; | ^^^^^^ diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 817705c0bd6bf..555e79d3e065c 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -554,6 +554,9 @@ impl TestProps { panic!("`{}-fail` header is only supported in UI tests", mode); } }; + if config.mode == Mode::Ui && config.parse_name_directive(ln, "compile-fail") { + panic!("`compile-fail` header is useless in UI tests"); + } let fail_mode = if config.parse_name_directive(ln, "check-fail") { check_ui("check"); Some(FailMode::Check) From b0a9e949e7afc1a77b6f73a0d3fa6b6081763a57 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sun, 2 Feb 2020 15:08:46 +0700 Subject: [PATCH 0774/1253] Strip unnecessary subexpression It became unnecessary since a06baa56b95674fc626b3c3fd680d6a65357fe60 reformatted the file. --- src/libstd/sys/unix/time.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 2310441997872..6707f790cab0a 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -282,7 +282,6 @@ mod inner { (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64")) || (cfg!(target_os = "linux") && cfg!(target_arch = "x86")) || cfg!(target_os = "fuchsia") - || false // last clause, used so `||` is always trailing above } pub fn checked_sub_instant(&self, other: &Instant) -> Option { From 00f0b0cd3ab667e151b8e4d06e314d3b40038495 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 1 Feb 2020 18:45:03 +0100 Subject: [PATCH 0775/1253] pretty: print attrs in struct expr --- src/librustc_ast_pretty/pprust.rs | 1 + .../issue-68710-field-attr-proc-mac-lost.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 761af72f95dd6..3cc67a7c82117 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1749,6 +1749,7 @@ impl<'a> State<'a> { Consistent, &fields[..], |s, field| { + s.print_outer_attributes(&field.attrs); s.ibox(INDENT_UNIT); if !field.is_shorthand { s.print_ident(field.ident); diff --git a/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs new file mode 100644 index 0000000000000..643ca761aac32 --- /dev/null +++ b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs @@ -0,0 +1,16 @@ +// pp-exact + +fn main() { } + +struct C { + field: u8, +} + +#[allow()] +const C: C = + C{ + #[cfg(debug_assertions)] + field: 0, + + #[cfg(not (debug_assertions))] + field: 1,}; From 8674efdb7c9d263caef8d282086a4243eae8df20 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 29 Jan 2020 01:30:01 +0100 Subject: [PATCH 0776/1253] parser: move restrictions re. `self` to `ast_validation`. --- src/librustc_ast_passes/ast_validation.rs | 44 +++- src/librustc_parse/parser/diagnostics.rs | 12 +- src/librustc_parse/parser/item.rs | 60 +++-- src/librustc_parse/parser/ty.rs | 4 +- .../ui/invalid-self-argument/bare-fn-start.rs | 6 +- .../bare-fn-start.stderr | 6 +- .../ui/parser/self-param-semantic-fail.rs | 64 +++++ .../ui/parser/self-param-semantic-fail.stderr | 220 ++++++++++++++++++ .../ui/parser/self-param-syntactic-pass.rs | 66 ++++++ 9 files changed, 426 insertions(+), 56 deletions(-) create mode 100644 src/test/ui/parser/self-param-semantic-fail.rs create mode 100644 src/test/ui/parser/self-param-semantic-fail.stderr create mode 100644 src/test/ui/parser/self-param-syntactic-pass.rs diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 152086bfce0ea..f37f93c0254bd 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -23,6 +23,12 @@ use syntax::print::pprust; use syntax::visit::{self, Visitor}; use syntax::walk_list; +/// Is `self` allowed semantically as the first parameter in an `FnDecl`? +enum SelfSemantic { + Yes, + No, +} + /// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`). #[derive(Clone, Copy)] enum BoundContext { @@ -302,7 +308,13 @@ impl<'a> AstValidator<'a> { } } - fn check_fn_decl(&self, fn_decl: &FnDecl) { + fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { + self.check_decl_cvaradic_pos(fn_decl); + self.check_decl_attrs(fn_decl); + self.check_decl_self_param(fn_decl, self_semantic); + } + + fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) { match &*fn_decl.inputs { [Param { ty, span, .. }] => { if let TyKind::CVarArgs = ty.kind { @@ -324,7 +336,9 @@ impl<'a> AstValidator<'a> { } _ => {} } + } + fn check_decl_attrs(&self, fn_decl: &FnDecl) { fn_decl .inputs .iter() @@ -352,6 +366,21 @@ impl<'a> AstValidator<'a> { }); } + fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { + if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) { + if param.is_self() { + self.err_handler() + .struct_span_err( + param.span, + "`self` parameter only allowed in associated `fn`s", + ) + .span_label(param.span, "not semantically valid as function parameter") + .note("associated `fn`s are those in `impl` or `trait` definitions") + .emit(); + } + } + } + fn check_defaultness(&self, span: Span, defaultness: Defaultness) { if let Defaultness::Default = defaultness { self.err_handler() @@ -504,7 +533,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.kind { ExprKind::Closure(_, _, _, fn_decl, _, _) => { - self.check_fn_decl(fn_decl); + self.check_fn_decl(fn_decl, SelfSemantic::No); } ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => { struct_span_err!( @@ -524,7 +553,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_ty(&mut self, ty: &'a Ty) { match ty.kind { TyKind::BareFn(ref bfty) => { - self.check_fn_decl(&bfty.decl); + self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _| { struct_span_err!( self.session, @@ -685,7 +714,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Fn(ref sig, ref generics, _) => { self.visit_fn_header(&sig.header); - self.check_fn_decl(&sig.decl); + self.check_fn_decl(&sig.decl, SelfSemantic::No); // We currently do not permit const generics in `const fn`, as // this is tantamount to allowing compile-time dependent typing. if sig.header.constness.node == Constness::Const { @@ -793,7 +822,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { match fi.kind { ForeignItemKind::Fn(ref decl, _) => { - self.check_fn_decl(decl); + self.check_fn_decl(decl, SelfSemantic::No); Self::check_decl_no_pat(decl, |span, _| { struct_span_err!( self.session, @@ -987,9 +1016,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { AssocItemKind::Const(_, body) => { self.check_impl_item_provided(ii.span, body, "constant", " = ;"); } - AssocItemKind::Fn(sig, body) => { + AssocItemKind::Fn(_, body) => { self.check_impl_item_provided(ii.span, body, "function", " { }"); - self.check_fn_decl(&sig.decl); } AssocItemKind::TyAlias(bounds, body) => { self.check_impl_item_provided(ii.span, body, "type", " = ;"); @@ -1005,7 +1033,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(ti.span, ti.defaultness); if let AssocItemKind::Fn(sig, block) = &ti.kind { - self.check_fn_decl(&sig.decl); self.check_trait_fn_not_async(ti.span, sig.header.asyncness.node); self.check_trait_fn_not_const(sig.header.constness); if block.is_none() { @@ -1035,6 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_assoc_item(&mut self, item: &'a AssocItem) { if let AssocItemKind::Fn(sig, _) = &item.kind { + self.check_fn_decl(&sig.decl, SelfSemantic::Yes); self.check_c_varadic_type(&sig.decl); } visit::walk_assoc_item(self, item); diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 80bc5c158a64f..09f393a81abad 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1336,8 +1336,8 @@ impl<'a> Parser<'a> { err: &mut DiagnosticBuilder<'_>, pat: P, require_name: bool, - is_self_allowed: bool, - is_trait_item: bool, + is_self_semantic: bool, + in_assoc_item: bool, ) -> Option { // If we find a pattern followed by an identifier, it could be an (incorrect) // C-style parameter declaration. @@ -1357,13 +1357,13 @@ impl<'a> Parser<'a> { return Some(ident); } else if let PatKind::Ident(_, ident, _) = pat.kind { if require_name - && (is_trait_item + && (in_assoc_item || self.token == token::Comma || self.token == token::Lt || self.token == token::CloseDelim(token::Paren)) { // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` - if is_self_allowed { + if is_self_semantic { err.span_suggestion( pat.span, "if this is a `self` type, give it a parameter name", @@ -1423,12 +1423,12 @@ impl<'a> Parser<'a> { pub(super) fn recover_bad_self_param( &mut self, mut param: ast::Param, - is_trait_item: bool, + in_assoc_item: bool, ) -> PResult<'a, ast::Param> { let sp = param.pat.span; param.ty.kind = TyKind::Err; let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function"); - if is_trait_item { + if in_assoc_item { err.span_label(sp, "must be the first associated function parameter"); } else { err.span_label(sp, "not valid as function parameter"); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 6611661132306..0ff595f444413 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1715,8 +1715,9 @@ impl<'a> Parser<'a> { /// The parsing configuration used to parse a parameter list (see `parse_fn_params`). pub(super) struct ParamCfg { - /// Is `self` is allowed as the first parameter? - pub is_self_allowed: bool, + /// Is `self` is *semantically* allowed as the first parameter? + /// This is only used for diagnostics. + pub in_assoc_item: bool, /// `is_name_required` decides if, per-parameter, /// the parameter must have a pattern or just a type. pub is_name_required: fn(&token::Token) -> bool, @@ -1732,8 +1733,8 @@ impl<'a> Parser<'a> { attrs: Vec, header: FnHeader, ) -> PResult<'a, Option>> { - let (ident, decl, generics) = - self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?; + let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true }; + let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let kind = ItemKind::Fn(FnSig { decl, header }, generics, body); self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) @@ -1747,20 +1748,13 @@ impl<'a> Parser<'a> { attrs: Vec, extern_sp: Span, ) -> PResult<'a, P> { + let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true }; self.expect_keyword(kw::Fn)?; - let (ident, decl, generics) = - self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?; + let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; let span = lo.to(self.token.span); self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; - Ok(P(ast::ForeignItem { - ident, - attrs, - kind: ForeignItemKind::Fn(decl, generics), - id: DUMMY_NODE_ID, - span, - vis, - tokens: None, - })) + let kind = ForeignItemKind::Fn(decl, generics); + Ok(P(ast::ForeignItem { ident, attrs, kind, id: DUMMY_NODE_ID, span, vis, tokens: None })) } fn parse_assoc_fn( @@ -1769,9 +1763,9 @@ impl<'a> Parser<'a> { attrs: &mut Vec, is_name_required: fn(&token::Token) -> bool, ) -> PResult<'a, (Ident, AssocItemKind, Generics)> { + let cfg = ParamCfg { in_assoc_item: true, is_name_required }; let header = self.parse_fn_front_matter()?; - let (ident, decl, generics) = - self.parse_fn_sig(ParamCfg { is_self_allowed: true, is_name_required })?; + let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; let sig = FnSig { header, decl }; let body = self.parse_assoc_fn_body(at_end, attrs)?; Ok((ident, AssocItemKind::Fn(sig, body), generics)) @@ -1847,7 +1841,7 @@ impl<'a> Parser<'a> { } /// Parse the "signature", including the identifier, parameters, and generics of a function. - fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P, Generics)> { + fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P, Generics)> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; let decl = self.parse_fn_decl(cfg, true)?; @@ -1858,7 +1852,7 @@ impl<'a> Parser<'a> { /// Parses the parameter list and result type of a function declaration. pub(super) fn parse_fn_decl( &mut self, - cfg: ParamCfg, + cfg: &ParamCfg, ret_allow_plus: bool, ) -> PResult<'a, P> { Ok(P(FnDecl { @@ -1868,11 +1862,11 @@ impl<'a> Parser<'a> { } /// Parses the parameter list of a function, including the `(` and `)` delimiters. - fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec> { - let is_trait_item = cfg.is_self_allowed; - // Parse the arguments, starting out with `self` being possibly allowed... + fn parse_fn_params(&mut self, cfg: &ParamCfg) -> PResult<'a, Vec> { + let mut first_param = true; + // Parse the arguments, starting out with `self` being allowed... let (mut params, _) = self.parse_paren_comma_seq(|p| { - let param = p.parse_param_general(&cfg, is_trait_item).or_else(|mut e| { + let param = p.parse_param_general(&cfg, first_param).or_else(|mut e| { e.emit(); let lo = p.prev_span; // Skip every token until next possible arg or end. @@ -1881,7 +1875,7 @@ impl<'a> Parser<'a> { Ok(dummy_arg(Ident::new(kw::Invalid, lo.to(p.prev_span)))) }); // ...now that we've parsed the first argument, `self` is no longer allowed. - cfg.is_self_allowed = false; + first_param = false; param })?; // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors. @@ -1889,20 +1883,20 @@ impl<'a> Parser<'a> { Ok(params) } - /// Skips unexpected attributes and doc comments in this position and emits an appropriate - /// error. - /// This version of parse param doesn't necessarily require identifier names. - fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> { + /// Parses a single function parameter. + /// + /// - `self` is syntactically allowed when `first_param` holds. + fn parse_param_general(&mut self, cfg: &ParamCfg, first_param: bool) -> PResult<'a, Param> { let lo = self.token.span; let attrs = self.parse_outer_attributes()?; // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. if let Some(mut param) = self.parse_self_param()? { param.attrs = attrs.into(); - return if cfg.is_self_allowed { + return if first_param { Ok(param) } else { - self.recover_bad_self_param(param, is_trait_item) + self.recover_bad_self_param(param, cfg.in_assoc_item) }; } @@ -1919,8 +1913,8 @@ impl<'a> Parser<'a> { &mut err, pat, is_name_required, - cfg.is_self_allowed, - is_trait_item, + first_param && cfg.in_assoc_item, + cfg.in_assoc_item, ) { err.emit(); Ok(dummy_arg(ident)) @@ -1975,8 +1969,6 @@ impl<'a> Parser<'a> { } /// Returns the parsed optional self parameter and whether a self shortcut was used. - /// - /// See `parse_self_param_with_attrs` to collect attributes. fn parse_self_param(&mut self) -> PResult<'a, Option> { // Extract an identifier *after* having confirmed that the token is one. let expect_self_ident = |this: &mut Self| { diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index a4cc9fa48f2a6..51367a37ad70a 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -288,8 +288,8 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); let ext = self.parse_extern()?; self.expect_keyword(kw::Fn)?; - let cfg = ParamCfg { is_self_allowed: false, is_name_required: |_| false }; - let decl = self.parse_fn_decl(cfg, false)?; + let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| false }; + let decl = self.parse_fn_decl(&cfg, false)?; Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl }))) } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs index a003a01941bde..8c92b7bc7c4b0 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.rs +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -1,6 +1,6 @@ fn a(&self) { } -//~^ ERROR unexpected `self` parameter in function -//~| NOTE not valid as function parameter -//~| NOTE `self` is only valid as the first parameter of an associated function +//~^ ERROR `self` parameter only allowed in associated `fn`s +//~| NOTE not semantically valid as function parameter +//~| NOTE associated `fn`s are those in `impl` or `trait` definitions fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr index 23de6502094f0..59120a60a6df1 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -1,10 +1,10 @@ -error: unexpected `self` parameter in function +error: `self` parameter only allowed in associated `fn`s --> $DIR/bare-fn-start.rs:1:6 | LL | fn a(&self) { } - | ^^^^^ not valid as function parameter + | ^^^^^ not semantically valid as function parameter | - = note: `self` is only valid as the first parameter of an associated function + = note: associated `fn`s are those in `impl` or `trait` definitions error: aborting due to previous error diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs new file mode 100644 index 0000000000000..773cf922b4da9 --- /dev/null +++ b/src/test/ui/parser/self-param-semantic-fail.rs @@ -0,0 +1,64 @@ +// This test ensures that `self` is semantically rejected +// in contexts with `FnDecl` but outside of associated `fn`s. +// FIXME(Centril): For now closures are an exception. + +fn main() {} + +fn free() { + fn f1(self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f2(mut self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f3(&self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f4(&mut self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f5<'a>(&'a self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f6<'a>(&'a mut self) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f7(self: u8) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f8(mut self: u8) {} + //~^ ERROR `self` parameter only allowed in associated `fn`s +} + +extern { + fn f1(self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f2(mut self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + //~| ERROR patterns aren't allowed in + fn f3(&self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f4(&mut self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f5<'a>(&'a self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f6<'a>(&'a mut self); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f7(self: u8); + //~^ ERROR `self` parameter only allowed in associated `fn`s + fn f8(mut self: u8); + //~^ ERROR `self` parameter only allowed in associated `fn`s + //~| ERROR patterns aren't allowed in +} + +type X1 = fn(self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X2 = fn(mut self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +//~| ERROR patterns aren't allowed in +type X3 = fn(&self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X4 = fn(&mut self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X5 = for<'a> fn(&'a self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X6 = for<'a> fn(&'a mut self); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X7 = fn(self: u8); +//~^ ERROR `self` parameter only allowed in associated `fn`s +type X8 = fn(mut self: u8); +//~^ ERROR `self` parameter only allowed in associated `fn`s +//~| ERROR patterns aren't allowed in diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr new file mode 100644 index 0000000000000..b45e4a5d26f16 --- /dev/null +++ b/src/test/ui/parser/self-param-semantic-fail.stderr @@ -0,0 +1,220 @@ +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:8:11 + | +LL | fn f1(self) {} + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:10:11 + | +LL | fn f2(mut self) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:12:11 + | +LL | fn f3(&self) {} + | ^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:14:11 + | +LL | fn f4(&mut self) {} + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:16:15 + | +LL | fn f5<'a>(&'a self) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:18:15 + | +LL | fn f6<'a>(&'a mut self) {} + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:20:11 + | +LL | fn f7(self: u8) {} + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:22:11 + | +LL | fn f8(mut self: u8) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:27:11 + | +LL | fn f1(self); + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:29:11 + | +LL | fn f2(mut self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error[E0130]: patterns aren't allowed in foreign function declarations + --> $DIR/self-param-semantic-fail.rs:29:11 + | +LL | fn f2(mut self); + | ^^^^^^^^ pattern not allowed in foreign function + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:32:11 + | +LL | fn f3(&self); + | ^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:34:11 + | +LL | fn f4(&mut self); + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:36:15 + | +LL | fn f5<'a>(&'a self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:38:15 + | +LL | fn f6<'a>(&'a mut self); + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:40:11 + | +LL | fn f7(self: u8); + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:42:11 + | +LL | fn f8(mut self: u8); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error[E0130]: patterns aren't allowed in foreign function declarations + --> $DIR/self-param-semantic-fail.rs:42:11 + | +LL | fn f8(mut self: u8); + | ^^^^^^^^ pattern not allowed in foreign function + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:47:14 + | +LL | type X1 = fn(self); + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:49:14 + | +LL | type X2 = fn(mut self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/self-param-semantic-fail.rs:49:14 + | +LL | type X2 = fn(mut self); + | ^^^^^^^^ + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:52:14 + | +LL | type X3 = fn(&self); + | ^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:54:14 + | +LL | type X4 = fn(&mut self); + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:56:22 + | +LL | type X5 = for<'a> fn(&'a self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:58:22 + | +LL | type X6 = for<'a> fn(&'a mut self); + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:60:14 + | +LL | type X7 = fn(self: u8); + | ^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error: `self` parameter only allowed in associated `fn`s + --> $DIR/self-param-semantic-fail.rs:62:14 + | +LL | type X8 = fn(mut self: u8); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated `fn`s are those in `impl` or `trait` definitions + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/self-param-semantic-fail.rs:62:14 + | +LL | type X8 = fn(mut self: u8); + | ^^^^^^^^ + +error: aborting due to 28 previous errors + +Some errors have detailed explanations: E0130, E0561. +For more information about an error, try `rustc --explain E0130`. diff --git a/src/test/ui/parser/self-param-syntactic-pass.rs b/src/test/ui/parser/self-param-syntactic-pass.rs new file mode 100644 index 0000000000000..9e215e6cdd4b7 --- /dev/null +++ b/src/test/ui/parser/self-param-syntactic-pass.rs @@ -0,0 +1,66 @@ +// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed. +// FIXME(Centril): For now closures are an exception. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn free() { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +extern { + fn f(self); + fn f(mut self); + fn f(&self); + fn f(&mut self); + fn f(&'a self); + fn f(&'a mut self); + fn f(self: u8); + fn f(mut self: u8); +} + +#[cfg(FALSE)] +trait X { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + type X = fn(self); + type X = fn(mut self); + type X = fn(&self); + type X = fn(&mut self); + type X = fn(&'a self); + type X = fn(&'a mut self); + type X = fn(self: u8); + type X = fn(mut self: u8); +} From 56ad8bcfe0025618d35c8479797bca5d05e81099 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 2 Feb 2020 17:55:11 +0900 Subject: [PATCH 0777/1253] Do not suggest duplicate bounds --- src/librustc_typeck/check/method/suggest.rs | 42 ++++++++++--------- .../associated-item-duplicate-bounds.rs | 11 +++++ .../associated-item-duplicate-bounds.stderr | 11 +++++ src/test/ui/issues/issue-39559.stderr | 4 -- src/test/ui/span/issue-7575.stderr | 13 ++---- 5 files changed, 49 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/associated-item/associated-item-duplicate-bounds.rs create mode 100644 src/test/ui/associated-item/associated-item-duplicate-bounds.stderr diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index e9942fad3bc64..490c69b55362b 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -853,26 +853,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { sp }; - // FIXME: contrast `t.def_id` against `param.bounds` to not suggest - // traits already there. That can happen when the cause is that - // we're in a const scope or associated function used as a method. - err.span_suggestions( - sp, - &message(format!( - "restrict type parameter `{}` with", - param.name.ident(), - )), - candidates.iter().map(|t| { - format!( - "{}{} {}{}", + let trait_def_ids: FxHashSet = param + .bounds + .iter() + .filter_map(|bound| bound.trait_def_id()) + .collect(); + if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { + err.span_suggestions( + sp, + &message(format!( + "restrict type parameter `{}` with", param.name.ident(), - if impl_trait { " +" } else { ":" }, - self.tcx.def_path_str(t.def_id), - if has_bounds.is_some() { " + " } else { "" }, - ) - }), - Applicability::MaybeIncorrect, - ); + )), + candidates.iter().map(|t| { + format!( + "{}{} {}{}", + param.name.ident(), + if impl_trait { " +" } else { ":" }, + self.tcx.def_path_str(t.def_id), + if has_bounds.is_some() { " + " } else { "" }, + ) + }), + Applicability::MaybeIncorrect, + ); + } suggested = true; } Node::Item(hir::Item { diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.rs b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs new file mode 100644 index 0000000000000..bec922b0721b9 --- /dev/null +++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs @@ -0,0 +1,11 @@ +trait Adapter { + const LINKS: usize; +} + +struct Foo { + adapter: A, + links: [u32; A::LINKS], // Shouldn't suggest bounds already there. + //~^ ERROR: no associated item named `LINKS` found +} + +fn main() {} diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr new file mode 100644 index 0000000000000..ff1ad4c006e78 --- /dev/null +++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr @@ -0,0 +1,11 @@ +error[E0599]: no associated item named `LINKS` found for type parameter `A` in the current scope + --> $DIR/associated-item-duplicate-bounds.rs:7:21 + | +LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there. + | ^^^^^ associated item not found in `A` + | + = help: items from traits can only be used if the type parameter is bounded by the trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr index 0554b232c248b..5e8d487f41658 100644 --- a/src/test/ui/issues/issue-39559.stderr +++ b/src/test/ui/issues/issue-39559.stderr @@ -5,10 +5,6 @@ LL | entries: [T; D::dim()], | ^^^ function or associated item not found in `D` | = help: items from traits can only be used if the type parameter is bounded by the trait -help: the following trait defines an item `dim`, perhaps you need to restrict type parameter `D` with it: - | -LL | pub struct Vector { - | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index eb85be039ba04..89b36848a2897 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -61,7 +61,10 @@ error[E0599]: no method named `is_str` found for type parameter `T` in the curre --> $DIR/issue-7575.rs:70:7 | LL | t.is_str() - | ^^^^^^ this is an associated function, not a method + | --^^^^^^-- + | | | + | | this is an associated function, not a method + | help: disambiguate the method call for the candidate: `ManyImplTrait::is_str(t)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `ManyImplTrait` @@ -70,14 +73,6 @@ note: the candidate is defined in the trait `ManyImplTrait` LL | fn is_str() -> bool { | ^^^^^^^^^^^^^^^^^^^ = help: items from traits can only be used if the type parameter is bounded by the trait -help: disambiguate the method call for the candidate - | -LL | ManyImplTrait::is_str(t) - | -help: the following trait defines an item `is_str`, perhaps you need to restrict type parameter `T` with it: - | -LL | fn param_bound(t: T) -> bool { - | ^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors From a606ffdb174dd6a7d226d632994e6a885bf8a1ac Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 2 Feb 2020 11:54:11 +0000 Subject: [PATCH 0778/1253] Avoid exponential behaviour when relating types --- src/librustc/infer/equate.rs | 10 ++++++-- src/librustc/infer/nll_relate/mod.rs | 11 +++++++++ .../ui/closures/deeply-nested_closures.rs | 23 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/closures/deeply-nested_closures.rs diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 4a41cdb14071b..f192295c1aa07 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -125,7 +125,13 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { where T: Relate<'tcx>, { - self.fields.higher_ranked_sub(a, b, self.a_is_expected)?; - self.fields.higher_ranked_sub(b, a, self.a_is_expected) + if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() { + self.fields.higher_ranked_sub(a, b, self.a_is_expected)?; + self.fields.higher_ranked_sub(b, a, self.a_is_expected) + } else { + // Fast path for the common case. + self.relate(a.skip_binder(), b.skip_binder())?; + return Ok(a.clone()); + } } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index 6b53871b9e2f5..6af004f7776a1 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -529,6 +529,10 @@ where b = self.infcx.shallow_resolve(b); } + if a == b { + return Ok(a); + } + match (&a.kind, &b.kind) { (_, &ty::Infer(ty::TyVar(vid))) => { if D::forbid_inference_vars() { @@ -638,6 +642,13 @@ where debug!("binders({:?}: {:?}, ambient_variance={:?})", a, b, self.ambient_variance); + if !a.skip_binder().has_escaping_bound_vars() && !b.skip_binder().has_escaping_bound_vars() + { + // Fast path for the common case. + self.relate(a.skip_binder(), b.skip_binder())?; + return Ok(a.clone()); + } + if self.ambient_covariance() { // Covariance, so we want `for<..> A <: for<..> B` -- // therefore we compare any instantiation of A (i.e., A diff --git a/src/test/ui/closures/deeply-nested_closures.rs b/src/test/ui/closures/deeply-nested_closures.rs new file mode 100644 index 0000000000000..a02684ee1de1e --- /dev/null +++ b/src/test/ui/closures/deeply-nested_closures.rs @@ -0,0 +1,23 @@ +// Check that this can be compiled in a reasonable time. + +// build-pass + +fn main() { + // 96 nested closures + let x = (); + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + [&(), &x]; +} From 044fe0f558aa62926e6de9a76b95e4a74c0b1f99 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 20:03:10 +0100 Subject: [PATCH 0779/1253] Add a resume type parameter to `Generator` --- .../src/language-features/generators.md | 26 ++++++-------- src/liballoc/boxed.rs | 24 +++++++++++++ src/libcore/ops/generator.rs | 35 ++++++++++++++++--- src/librustc/traits/util.rs | 6 ++-- src/librustc/ty/layout.rs | 4 +-- src/librustc_error_codes/error_codes/E0626.md | 10 +++--- .../dataflow/impls/storage_liveness.rs | 20 ++++++----- src/librustc_mir/transform/generator.rs | 3 +- src/librustc_mir_build/build/mod.rs | 9 +++-- src/libstd/future.rs | 5 ++- src/test/debuginfo/generator-locals.rs | 6 ++-- src/test/debuginfo/generator-objects.rs | 6 ++-- src/test/debuginfo/issue-57822.rs | 2 +- .../run-fail/generator-resume-after-panic.rs | 4 +-- ...65419-generator-resume-after-completion.rs | 6 ++-- src/test/ui/drop/dynamic-drop.rs | 2 +- .../generator/auxiliary/xcrate-reachable.rs | 2 +- src/test/ui/generator/auxiliary/xcrate.rs | 4 +-- src/test/ui/generator/borrowing.rs | 2 +- src/test/ui/generator/borrowing.stderr | 2 +- src/test/ui/generator/conditional-drop.rs | 8 ++--- src/test/ui/generator/control-flow.rs | 4 +-- src/test/ui/generator/drop-and-replace.rs | 2 +- src/test/ui/generator/drop-env.rs | 4 +-- src/test/ui/generator/dropck.rs | 2 +- .../generator-region-requirements.rs | 2 +- src/test/ui/generator/issue-44197.rs | 13 ++++--- .../issue-61442-stmt-expr-with-drop.rs | 4 +-- src/test/ui/generator/iterator-count.rs | 6 ++-- .../ui/generator/live-upvar-across-yield.rs | 2 +- src/test/ui/generator/nested_generators.rs | 2 +- src/test/ui/generator/panic-drops.rs | 4 +-- src/test/ui/generator/panic-safe.rs | 4 +-- src/test/ui/generator/resume-after-return.rs | 4 +-- src/test/ui/generator/sized-yield.rs | 2 +- src/test/ui/generator/sized-yield.stderr | 2 +- src/test/ui/generator/smoke.rs | 28 +++++++-------- src/test/ui/generator/static-generators.rs | 4 +-- src/test/ui/generator/xcrate-reachable.rs | 2 +- src/test/ui/generator/xcrate.rs | 6 ++-- .../ui/generator/yield-while-iterating.rs | 6 ++-- .../ui/generator/yield-while-iterating.stderr | 2 +- .../generator/yield-while-local-borrowed.rs | 6 ++-- .../generator/yield-while-ref-reborrowed.rs | 6 ++-- .../yield-while-ref-reborrowed.stderr | 2 +- src/test/ui/nll/issue-55850.rs | 2 +- 46 files changed, 185 insertions(+), 122 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md index 97cf58e57e605..8bc62418b3969 100644 --- a/src/doc/unstable-book/src/language-features/generators.md +++ b/src/doc/unstable-book/src/language-features/generators.md @@ -37,11 +37,11 @@ fn main() { return "foo" }; - match Pin::new(&mut generator).resume() { + match Pin::new(&mut generator).resume(()) { GeneratorState::Yielded(1) => {} _ => panic!("unexpected value from resume"), } - match Pin::new(&mut generator).resume() { + match Pin::new(&mut generator).resume(()) { GeneratorState::Complete("foo") => {} _ => panic!("unexpected value from resume"), } @@ -71,9 +71,9 @@ fn main() { }; println!("1"); - Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(()); println!("3"); - Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(()); println!("5"); } ``` @@ -92,10 +92,10 @@ The `Generator` trait in `std::ops` currently looks like: # use std::ops::GeneratorState; # use std::pin::Pin; -pub trait Generator { +pub trait Generator { type Yield; type Return; - fn resume(self: Pin<&mut Self>) -> GeneratorState; + fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState; } ``` @@ -152,10 +152,6 @@ closure-like semantics. Namely: * Whenever a generator is dropped it will drop all captured environment variables. -Note that unlike closures, generators at this time cannot take any arguments. -That is, generators must always look like `|| { ... }`. This restriction may be -lifted at a future date, the design is ongoing! - ### Generators as state machines In the compiler, generators are currently compiled as state machines. Each @@ -179,8 +175,8 @@ fn main() { return ret }; - Pin::new(&mut generator).resume(); - Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(()); + Pin::new(&mut generator).resume(()); } ``` @@ -205,7 +201,7 @@ fn main() { type Yield = i32; type Return = &'static str; - fn resume(mut self: Pin<&mut Self>) -> GeneratorState { + fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState { use std::mem; match mem::replace(&mut *self, __Generator::Done) { __Generator::Start(s) => { @@ -228,8 +224,8 @@ fn main() { __Generator::Start(ret) }; - Pin::new(&mut generator).resume(); - Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(()); + Pin::new(&mut generator).resume(()); } ``` diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8735c2c8f3625..04be86862ae9c 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -1103,6 +1103,7 @@ impl AsMut for Box { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Box {} +#[cfg(bootstrap)] #[unstable(feature = "generator_trait", issue = "43122")] impl Generator for Box { type Yield = G::Yield; @@ -1113,6 +1114,7 @@ impl Generator for Box { } } +#[cfg(bootstrap)] #[unstable(feature = "generator_trait", issue = "43122")] impl Generator for Pin> { type Yield = G::Yield; @@ -1123,6 +1125,28 @@ impl Generator for Pin> { } } +#[cfg(not(bootstrap))] +#[unstable(feature = "generator_trait", issue = "43122")] +impl + Unpin, R> Generator for Box { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume(Pin::new(&mut *self), arg) + } +} + +#[cfg(not(bootstrap))] +#[unstable(feature = "generator_trait", issue = "43122")] +impl, R> Generator for Pin> { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume((*self).as_mut(), arg) + } +} + #[stable(feature = "futures_api", since = "1.36.0")] impl Future for Box { type Output = F::Output; diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs index 5401fff860e9b..4e43561996c37 100644 --- a/src/libcore/ops/generator.rs +++ b/src/libcore/ops/generator.rs @@ -50,11 +50,11 @@ pub enum GeneratorState { /// return "foo" /// }; /// -/// match Pin::new(&mut generator).resume() { +/// match Pin::new(&mut generator).resume(()) { /// GeneratorState::Yielded(1) => {} /// _ => panic!("unexpected return from resume"), /// } -/// match Pin::new(&mut generator).resume() { +/// match Pin::new(&mut generator).resume(()) { /// GeneratorState::Complete("foo") => {} /// _ => panic!("unexpected return from resume"), /// } @@ -67,7 +67,7 @@ pub enum GeneratorState { #[lang = "generator"] #[unstable(feature = "generator_trait", issue = "43122")] #[fundamental] -pub trait Generator { +pub trait Generator<#[cfg(not(bootstrap))] R = ()> { /// The type of value this generator yields. /// /// This associated type corresponds to the `yield` expression and the @@ -110,9 +110,13 @@ pub trait Generator { /// been returned previously. While generator literals in the language are /// guaranteed to panic on resuming after `Complete`, this is not guaranteed /// for all implementations of the `Generator` trait. - fn resume(self: Pin<&mut Self>) -> GeneratorState; + fn resume( + self: Pin<&mut Self>, + #[cfg(not(bootstrap))] arg: R, + ) -> GeneratorState; } +#[cfg(bootstrap)] #[unstable(feature = "generator_trait", issue = "43122")] impl Generator for Pin<&mut G> { type Yield = G::Yield; @@ -123,6 +127,7 @@ impl Generator for Pin<&mut G> { } } +#[cfg(bootstrap)] #[unstable(feature = "generator_trait", issue = "43122")] impl Generator for &mut G { type Yield = G::Yield; @@ -132,3 +137,25 @@ impl Generator for &mut G { G::resume(Pin::new(&mut *self)) } } + +#[cfg(not(bootstrap))] +#[unstable(feature = "generator_trait", issue = "43122")] +impl, R> Generator for Pin<&mut G> { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume((*self).as_mut(), arg) + } +} + +#[cfg(not(bootstrap))] +#[unstable(feature = "generator_trait", issue = "43122")] +impl + Unpin, R> Generator for &mut G { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume(Pin::new(&mut *self), arg) + } +} diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index ae1a5e3efa2a7..947d66e38b434 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -643,8 +643,10 @@ pub fn generator_trait_ref_and_outputs( self_ty: Ty<'tcx>, sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { - let trait_ref = - ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[]) }; + let trait_ref = ty::TraitRef { + def_id: fn_trait_def_id, + substs: tcx.mk_substs_trait(self_ty, &[tcx.mk_unit().into()]), + }; ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index bda42db40b0ae..966b60c6cfbc1 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2350,8 +2350,8 @@ impl<'tcx> ty::Instance<'tcx> { ]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - tcx.mk_fn_sig(iter::once(env_ty), - ret_ty, + tcx.mk_fn_sig([env_ty, tcx.mk_unit()].iter(), + &ret_ty, false, hir::Unsafety::Normal, rustc_target::spec::abi::Abi::Rust diff --git a/src/librustc_error_codes/error_codes/E0626.md b/src/librustc_error_codes/error_codes/E0626.md index db50bd7ac4f6f..cc6e03d1ca70f 100644 --- a/src/librustc_error_codes/error_codes/E0626.md +++ b/src/librustc_error_codes/error_codes/E0626.md @@ -12,7 +12,7 @@ let mut b = || { yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); }; -Pin::new(&mut b).resume(); +Pin::new(&mut b).resume(()); ``` At present, it is not permitted to have a yield that occurs while a @@ -31,7 +31,7 @@ let mut b = || { yield (); println!("{}", a); }; -Pin::new(&mut b).resume(); +Pin::new(&mut b).resume(()); ``` This is a very simple case, of course. In more complex cases, we may @@ -50,7 +50,7 @@ let mut b = || { yield x; // ...when this yield occurs. } }; -Pin::new(&mut b).resume(); +Pin::new(&mut b).resume(()); ``` Such cases can sometimes be resolved by iterating "by value" (or using @@ -66,7 +66,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -Pin::new(&mut b).resume(); +Pin::new(&mut b).resume(()); ``` If taking ownership is not an option, using indices can work too: @@ -83,7 +83,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -Pin::new(&mut b).resume(); +Pin::new(&mut b).resume(()); // (*) -- Unfortunately, these temporaries are currently required. // See . diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 6a48d1e98032c..040c13e8210ea 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -31,10 +31,12 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { self.body.local_decls.len() } - fn start_block_effect(&self, _on_entry: &mut BitSet) { - // Nothing is live on function entry (generators only have a self - // argument, and we don't care about that) - assert_eq!(1, self.body.arg_count); + fn start_block_effect(&self, on_entry: &mut BitSet) { + // The resume argument is live on function entry (we don't care about + // the `self` argument) + for arg in self.body.args_iter().skip(1) { + on_entry.insert(arg); + } } fn statement_effect(&self, trans: &mut GenKillSet, loc: Location) { @@ -100,10 +102,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { self.body.local_decls.len() } - fn start_block_effect(&self, _sets: &mut BitSet) { - // Nothing is live on function entry (generators only have a self - // argument, and we don't care about that) - assert_eq!(1, self.body.arg_count); + fn start_block_effect(&self, on_entry: &mut BitSet) { + // The resume argument is live on function entry (we don't care about + // the `self` argument) + for arg in self.body.args_iter().skip(1) { + on_entry.insert(arg); + } } fn before_statement_effect(&self, sets: &mut GenKillSet, loc: Location) { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 1c86d6f3f65f2..a8defd03f7177 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -885,6 +885,7 @@ fn create_generator_drop_shim<'tcx>( drop_clean: BasicBlock, ) -> BodyAndCache<'tcx> { let mut body = body.clone(); + body.arg_count = 1; // make sure the resume argument is not included here let source_info = source_info(&body); @@ -1164,7 +1165,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // Update our MIR struct to reflect the changed we've made body.yield_ty = None; - body.arg_count = 1; + body.arg_count = 2; // self, resume arg body.spread_arg = None; body.generator_layout = Some(layout); diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 1f536b63a394a..ab539e6179e3d 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -75,13 +75,16 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi::Rust; - Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)) + vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)] } ty::Generator(..) => { let gen_ty = tcx.body_tables(body_id).node_type(id); - Some(ArgInfo(gen_ty, None, None, None)) + vec![ + ArgInfo(gen_ty, None, None, None), + ArgInfo(tcx.mk_unit(), None, None, None), + ] } - _ => None, + _ => vec![], }; let safety = match fn_sig.unsafety { diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 9c7422c2b20a6..f74c84e6dfd48 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -40,7 +40,10 @@ impl> Future for GenFuture { // Safe because we're !Unpin + !Drop mapping to a ?Unpin value let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }; let _guard = unsafe { set_task_context(cx) }; - match gen.resume() { + match gen.resume( + #[cfg(not(bootstrap))] + (), + ) { GeneratorState::Yielded(()) => Poll::Pending, GeneratorState::Complete(x) => Poll::Ready(x), } diff --git a/src/test/debuginfo/generator-locals.rs b/src/test/debuginfo/generator-locals.rs index 59dbfecc39ffc..fd46c1a8b4db7 100644 --- a/src/test/debuginfo/generator-locals.rs +++ b/src/test/debuginfo/generator-locals.rs @@ -78,9 +78,9 @@ fn main() { _zzz(); // #break a = c; }; - Pin::new(&mut b).resume(); - Pin::new(&mut b).resume(); - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); + Pin::new(&mut b).resume(()); + Pin::new(&mut b).resume(()); _zzz(); // #break } diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index bfa7a05cad057..f19a3c71dd8d2 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -57,11 +57,11 @@ fn main() { println!("{} {} {}", a, c, d); }; _zzz(); // #break - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); _zzz(); // #break - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); _zzz(); // #break - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); _zzz(); // #break } diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs index f18e41db0e6ba..4de88e9dae62b 100644 --- a/src/test/debuginfo/issue-57822.rs +++ b/src/test/debuginfo/issue-57822.rs @@ -45,7 +45,7 @@ fn main() { yield; }; let mut b = move || { - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); yield; }; diff --git a/src/test/run-fail/generator-resume-after-panic.rs b/src/test/run-fail/generator-resume-after-panic.rs index 910b4903bf6a3..1a7c2e8062901 100644 --- a/src/test/run-fail/generator-resume-after-panic.rs +++ b/src/test/run-fail/generator-resume-after-panic.rs @@ -16,7 +16,7 @@ fn main() { yield; }; panic::catch_unwind(panic::AssertUnwindSafe(|| { - let x = Pin::new(&mut g).resume(); + let x = Pin::new(&mut g).resume(()); })); - Pin::new(&mut g).resume(); + Pin::new(&mut g).resume(()); } diff --git a/src/test/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs b/src/test/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs index 23e3483e01c7d..9fc5667d6847e 100644 --- a/src/test/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs +++ b/src/test/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs @@ -19,7 +19,7 @@ fn main() { let mut g = || { yield; }; - Pin::new(&mut g).resume(); // Yields once. - Pin::new(&mut g).resume(); // Completes here. - Pin::new(&mut g).resume(); // Panics here. + Pin::new(&mut g).resume(()); // Yields once. + Pin::new(&mut g).resume(()); // Completes here. + Pin::new(&mut g).resume(()); // Panics here. } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index b4406204a5db9..659e520d4cd12 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -184,7 +184,7 @@ fn generator(a: &Allocator, run_count: usize) { ); }; for _ in 0..run_count { - Pin::new(&mut gen).resume(); + Pin::new(&mut gen).resume(()); } } diff --git a/src/test/ui/generator/auxiliary/xcrate-reachable.rs b/src/test/ui/generator/auxiliary/xcrate-reachable.rs index 33337f8038f60..2dd5ea675233c 100644 --- a/src/test/ui/generator/auxiliary/xcrate-reachable.rs +++ b/src/test/ui/generator/auxiliary/xcrate-reachable.rs @@ -6,7 +6,7 @@ fn msg() -> u32 { 0 } -pub fn foo() -> impl Generator { +pub fn foo() -> impl Generator<(), Yield=(), Return=u32> { || { yield; return msg(); diff --git a/src/test/ui/generator/auxiliary/xcrate.rs b/src/test/ui/generator/auxiliary/xcrate.rs index 613c495832f00..d07abd0918c78 100644 --- a/src/test/ui/generator/auxiliary/xcrate.rs +++ b/src/test/ui/generator/auxiliary/xcrate.rs @@ -3,7 +3,7 @@ use std::marker::Unpin; use std::ops::Generator; -pub fn foo() -> impl Generator { +pub fn foo() -> impl Generator<(), Yield = (), Return = ()> { || { if false { yield; @@ -11,7 +11,7 @@ pub fn foo() -> impl Generator { } } -pub fn bar(t: T) -> Box + Unpin> { +pub fn bar(t: T) -> Box + Unpin> { Box::new(|| { yield t; }) diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index 6234b73804878..d36592583cdc5 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -6,7 +6,7 @@ use std::pin::Pin; fn main() { let _b = { let a = 3; - Pin::new(&mut || yield &a).resume() + Pin::new(&mut || yield &a).resume(()) //~^ ERROR: `a` does not live long enough }; diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr index 3d58873f826da..83987e19839ce 100644 --- a/src/test/ui/generator/borrowing.stderr +++ b/src/test/ui/generator/borrowing.stderr @@ -1,7 +1,7 @@ error[E0597]: `a` does not live long enough --> $DIR/borrowing.rs:9:33 | -LL | Pin::new(&mut || yield &a).resume() +LL | Pin::new(&mut || yield &a).resume(()) | ----------^ | | | | | borrowed value does not live long enough diff --git a/src/test/ui/generator/conditional-drop.rs b/src/test/ui/generator/conditional-drop.rs index 907f7a3c06de7..990d94e6efc1b 100644 --- a/src/test/ui/generator/conditional-drop.rs +++ b/src/test/ui/generator/conditional-drop.rs @@ -35,9 +35,9 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); assert_eq!(A.load(Ordering::SeqCst), n + 1); - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); assert_eq!(A.load(Ordering::SeqCst), n + 1); } @@ -51,8 +51,8 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); assert_eq!(A.load(Ordering::SeqCst), n); - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); assert_eq!(A.load(Ordering::SeqCst), n + 1); } diff --git a/src/test/ui/generator/control-flow.rs b/src/test/ui/generator/control-flow.rs index df70e013bd330..9d4c217b76ed7 100644 --- a/src/test/ui/generator/control-flow.rs +++ b/src/test/ui/generator/control-flow.rs @@ -7,10 +7,10 @@ use std::ops::{GeneratorState, Generator}; use std::pin::Pin; fn finish(mut amt: usize, mut t: T) -> T::Return - where T: Generator + Unpin, + where T: Generator<(), Yield = ()> + Unpin, { loop { - match Pin::new(&mut t).resume() { + match Pin::new(&mut t).resume(()) { GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), GeneratorState::Complete(ret) => { assert_eq!(amt, 0); diff --git a/src/test/ui/generator/drop-and-replace.rs b/src/test/ui/generator/drop-and-replace.rs index bb33502815bf8..a9a50a122a19c 100644 --- a/src/test/ui/generator/drop-and-replace.rs +++ b/src/test/ui/generator/drop-and-replace.rs @@ -37,7 +37,7 @@ fn main() { }; loop { - match Pin::new(&mut a).resume() { + match Pin::new(&mut a).resume(()) { GeneratorState::Complete(()) => break, _ => (), } diff --git a/src/test/ui/generator/drop-env.rs b/src/test/ui/generator/drop-env.rs index ac4e06656285e..7ba711881045d 100644 --- a/src/test/ui/generator/drop-env.rs +++ b/src/test/ui/generator/drop-env.rs @@ -30,7 +30,7 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - drop(Pin::new(&mut foo).resume()); + drop(Pin::new(&mut foo).resume(())); assert_eq!(A.load(Ordering::SeqCst), n); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); @@ -43,7 +43,7 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - drop(Pin::new(&mut foo).resume()); + drop(Pin::new(&mut foo).resume(())); assert_eq!(A.load(Ordering::SeqCst), n + 1); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs index 65c61fbaac4e2..da00b230d9fb7 100644 --- a/src/test/ui/generator/dropck.rs +++ b/src/test/ui/generator/dropck.rs @@ -15,6 +15,6 @@ fn main() { let _d = ref_.take(); //~ ERROR `ref_` does not live long enough yield; }; - Pin::new(&mut gen).resume(); + Pin::new(&mut gen).resume(()); // drops the RefCell and then the Ref, leading to use-after-free } diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs index 41cb339f45911..5f0a6bb09b784 100644 --- a/src/test/ui/generator/generator-region-requirements.rs +++ b/src/test/ui/generator/generator-region-requirements.rs @@ -8,7 +8,7 @@ fn dangle(x: &mut i32) -> &'static mut i32 { x }; loop { - match Pin::new(&mut g).resume() { + match Pin::new(&mut g).resume(()) { GeneratorState::Complete(c) => return c, //~^ ERROR explicit lifetime required GeneratorState::Yielded(_) => (), diff --git a/src/test/ui/generator/issue-44197.rs b/src/test/ui/generator/issue-44197.rs index 6efaff50c1e62..389b9d1396941 100644 --- a/src/test/ui/generator/issue-44197.rs +++ b/src/test/ui/generator/issue-44197.rs @@ -2,14 +2,14 @@ #![feature(generators, generator_trait)] -use std::ops::{ Generator, GeneratorState }; +use std::ops::{Generator, GeneratorState}; use std::pin::Pin; fn foo(_: &str) -> String { String::new() } -fn bar(baz: String) -> impl Generator { +fn bar(baz: String) -> impl Generator<(), Yield = String, Return = ()> { move || { yield foo(&baz); } @@ -19,7 +19,7 @@ fn foo2(_: &str) -> Result { Err(()) } -fn bar2(baz: String) -> impl Generator { +fn bar2(baz: String) -> impl Generator<(), Yield = String, Return = ()> { move || { if let Ok(quux) = foo2(&baz) { yield quux; @@ -28,6 +28,9 @@ fn bar2(baz: String) -> impl Generator { } fn main() { - assert_eq!(Pin::new(&mut bar(String::new())).resume(), GeneratorState::Yielded(String::new())); - assert_eq!(Pin::new(&mut bar2(String::new())).resume(), GeneratorState::Complete(())); + assert_eq!( + Pin::new(&mut bar(String::new())).resume(()), + GeneratorState::Yielded(String::new()) + ); + assert_eq!(Pin::new(&mut bar2(String::new())).resume(()), GeneratorState::Complete(())); } diff --git a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs index e3d19029348a5..187c374021dca 100644 --- a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs +++ b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs @@ -18,12 +18,12 @@ fn drop_and_yield() { String::new(); yield; }; - Box::pin(x).as_mut().resume(); + Box::pin(x).as_mut().resume(()); let y = static || { String::new(); yield; }; - Box::pin(y).as_mut().resume(); + Box::pin(y).as_mut().resume(()); } fn main() { diff --git a/src/test/ui/generator/iterator-count.rs b/src/test/ui/generator/iterator-count.rs index ac7e122dd5802..90eefe02f664e 100644 --- a/src/test/ui/generator/iterator-count.rs +++ b/src/test/ui/generator/iterator-count.rs @@ -10,18 +10,18 @@ struct W(T); // This impl isn't safe in general, but the generator used in this test is movable // so it won't cause problems. -impl + Unpin> Iterator for W { +impl + Unpin> Iterator for W { type Item = T::Yield; fn next(&mut self) -> Option { - match Pin::new(&mut self.0).resume() { + match Pin::new(&mut self.0).resume(()) { GeneratorState::Complete(..) => None, GeneratorState::Yielded(v) => Some(v), } } } -fn test() -> impl Generator + Unpin { +fn test() -> impl Generator<(), Return=(), Yield=u8> + Unpin { || { for i in 1..6 { yield i diff --git a/src/test/ui/generator/live-upvar-across-yield.rs b/src/test/ui/generator/live-upvar-across-yield.rs index a1064165b2f7a..6a2e42a5573a8 100644 --- a/src/test/ui/generator/live-upvar-across-yield.rs +++ b/src/test/ui/generator/live-upvar-across-yield.rs @@ -10,5 +10,5 @@ fn main() { let mut a = || { b(yield); }; - Pin::new(&mut a).resume(); + Pin::new(&mut a).resume(()); } diff --git a/src/test/ui/generator/nested_generators.rs b/src/test/ui/generator/nested_generators.rs index b56cce1dc44f1..45519150eec2b 100644 --- a/src/test/ui/generator/nested_generators.rs +++ b/src/test/ui/generator/nested_generators.rs @@ -11,7 +11,7 @@ fn main() { yield 2; }; - match Pin::new(&mut sub_generator).resume() { + match Pin::new(&mut sub_generator).resume(()) { GeneratorState::Yielded(x) => { yield x; } diff --git a/src/test/ui/generator/panic-drops.rs b/src/test/ui/generator/panic-drops.rs index f88687858fd11..c9a201725aea2 100644 --- a/src/test/ui/generator/panic-drops.rs +++ b/src/test/ui/generator/panic-drops.rs @@ -35,7 +35,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 0); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume() + Pin::new(&mut foo).resume(()) })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); @@ -50,7 +50,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 1); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume() + Pin::new(&mut foo).resume(()) })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); diff --git a/src/test/ui/generator/panic-safe.rs b/src/test/ui/generator/panic-safe.rs index 5f6778674dce1..500a3c9c2950e 100644 --- a/src/test/ui/generator/panic-safe.rs +++ b/src/test/ui/generator/panic-safe.rs @@ -17,13 +17,13 @@ fn main() { }; let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume() + Pin::new(&mut foo).resume(()) })); assert!(res.is_err()); for _ in 0..10 { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume() + Pin::new(&mut foo).resume(()) })); assert!(res.is_err()); } diff --git a/src/test/ui/generator/resume-after-return.rs b/src/test/ui/generator/resume-after-return.rs index 71a68ff684af3..efed08bd4708f 100644 --- a/src/test/ui/generator/resume-after-return.rs +++ b/src/test/ui/generator/resume-after-return.rs @@ -16,12 +16,12 @@ fn main() { yield; }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } - match panic::catch_unwind(move || Pin::new(&mut foo).resume()) { + match panic::catch_unwind(move || Pin::new(&mut foo).resume(())) { Ok(_) => panic!("generator successfully resumed"), Err(_) => {} } diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs index f64849b3149b8..c6dd738d6ac60 100644 --- a/src/test/ui/generator/sized-yield.rs +++ b/src/test/ui/generator/sized-yield.rs @@ -9,6 +9,6 @@ fn main() { //~^ ERROR the size for values of type yield s[..]; }; - Pin::new(&mut gen).resume(); + Pin::new(&mut gen).resume(()); //~^ ERROR the size for values of type } diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr index c2caac7ebe2e7..79aeec2ec0280 100644 --- a/src/test/ui/generator/sized-yield.stderr +++ b/src/test/ui/generator/sized-yield.stderr @@ -15,7 +15,7 @@ LL | | }; error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/sized-yield.rs:12:23 | -LL | Pin::new(&mut gen).resume(); +LL | Pin::new(&mut gen).resume(()); | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `str` diff --git a/src/test/ui/generator/smoke.rs b/src/test/ui/generator/smoke.rs index 533f2399084fa..9289710b34bf9 100644 --- a/src/test/ui/generator/smoke.rs +++ b/src/test/ui/generator/smoke.rs @@ -17,7 +17,7 @@ fn simple() { } }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -33,7 +33,7 @@ fn return_capture() { a }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -45,11 +45,11 @@ fn simple_yield() { yield; }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -62,11 +62,11 @@ fn yield_capture() { yield b; }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -79,11 +79,11 @@ fn simple_yield_value() { return String::from("foo") }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(ref s) if *s == "bar" => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -97,11 +97,11 @@ fn return_after_yield() { return a }; - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -149,11 +149,11 @@ fn send_and_sync() { fn send_over_threads() { let mut foo = || { yield }; thread::spawn(move || { - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -162,11 +162,11 @@ fn send_over_threads() { let a = String::from("a"); let mut foo = || { yield a }; thread::spawn(move || { - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(ref s) if *s == "a" => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/ui/generator/static-generators.rs b/src/test/ui/generator/static-generators.rs index 965d3c61c22d5..3980766c4287e 100644 --- a/src/test/ui/generator/static-generators.rs +++ b/src/test/ui/generator/static-generators.rs @@ -15,6 +15,6 @@ fn main() { // Safety: We shadow the original generator variable so have no safe API to // move it after this point. let mut generator = unsafe { Pin::new_unchecked(&mut generator) }; - assert_eq!(generator.as_mut().resume(), GeneratorState::Yielded(())); - assert_eq!(generator.as_mut().resume(), GeneratorState::Complete(())); + assert_eq!(generator.as_mut().resume(()), GeneratorState::Yielded(())); + assert_eq!(generator.as_mut().resume(()), GeneratorState::Complete(())); } diff --git a/src/test/ui/generator/xcrate-reachable.rs b/src/test/ui/generator/xcrate-reachable.rs index 9483ad7395ea1..1b1cff3387d9f 100644 --- a/src/test/ui/generator/xcrate-reachable.rs +++ b/src/test/ui/generator/xcrate-reachable.rs @@ -10,5 +10,5 @@ use std::ops::Generator; use std::pin::Pin; fn main() { - Pin::new(&mut foo::foo()).resume(); + Pin::new(&mut foo::foo()).resume(()); } diff --git a/src/test/ui/generator/xcrate.rs b/src/test/ui/generator/xcrate.rs index febf5c3583f30..40986bbeb6517 100644 --- a/src/test/ui/generator/xcrate.rs +++ b/src/test/ui/generator/xcrate.rs @@ -12,18 +12,18 @@ use std::pin::Pin; fn main() { let mut foo = xcrate::foo(); - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } let mut foo = xcrate::bar(3); - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Yielded(3) => {} s => panic!("bad state: {:?}", s), } - match Pin::new(&mut foo).resume() { + match Pin::new(&mut foo).resume(()) { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs index e42781d1279e7..985e5d8bdc838 100644 --- a/src/test/ui/generator/yield-while-iterating.rs +++ b/src/test/ui/generator/yield-while-iterating.rs @@ -43,7 +43,7 @@ fn yield_during_iter_borrowed_slice_3() { yield p; } }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn yield_during_iter_borrowed_slice_4() { @@ -56,7 +56,7 @@ fn yield_during_iter_borrowed_slice_4() { } }; println!("{}", x[0]); //~ ERROR - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn yield_during_range_iter() { @@ -69,7 +69,7 @@ fn yield_during_range_iter() { yield x; } }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn main() { } diff --git a/src/test/ui/generator/yield-while-iterating.stderr b/src/test/ui/generator/yield-while-iterating.stderr index 6a96b25b19fb4..b6563475235c2 100644 --- a/src/test/ui/generator/yield-while-iterating.stderr +++ b/src/test/ui/generator/yield-while-iterating.stderr @@ -16,7 +16,7 @@ LL | for p in &mut x { ... LL | println!("{}", x[0]); | ^ immutable borrow occurs here -LL | Pin::new(&mut b).resume(); +LL | Pin::new(&mut b).resume(()); | ------ mutable borrow later used here error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs index b643bbf3376fb..061a64dbc364d 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.rs +++ b/src/test/ui/generator/yield-while-local-borrowed.rs @@ -15,7 +15,7 @@ fn borrow_local_inline() { yield(); println!("{}", a); }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn borrow_local_inline_done() { @@ -26,7 +26,7 @@ fn borrow_local_inline_done() { } yield(); }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn borrow_local() { @@ -43,7 +43,7 @@ fn borrow_local() { println!("{}", b); } }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn main() { } diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs index f54a4f468f6a0..a03ef945dd231 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.rs +++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs @@ -12,7 +12,7 @@ fn reborrow_shared_ref(x: &i32) { yield(); println!("{}", a); }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn reborrow_mutable_ref(x: &mut i32) { @@ -23,7 +23,7 @@ fn reborrow_mutable_ref(x: &mut i32) { yield(); println!("{}", a); }; - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn reborrow_mutable_ref_2(x: &mut i32) { @@ -34,7 +34,7 @@ fn reborrow_mutable_ref_2(x: &mut i32) { println!("{}", a); }; println!("{}", x); //~ ERROR - Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(()); } fn main() { } diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr index 4c37cd351732b..fd885660d0927 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr @@ -8,7 +8,7 @@ LL | let a = &mut *x; ... LL | println!("{}", x); | ^ second borrow occurs here -LL | Pin::new(&mut b).resume(); +LL | Pin::new(&mut b).resume(()); | ------ first borrow later used here error: aborting due to previous error diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs index a8f7299f89937..e6279bd028e01 100644 --- a/src/test/ui/nll/issue-55850.rs +++ b/src/test/ui/nll/issue-55850.rs @@ -15,7 +15,7 @@ where type Item = G::Yield; fn next(&mut self) -> Option { - match Pin::new(&mut self.0).resume() { + match Pin::new(&mut self.0).resume(()) { Yielded(y) => Some(y), _ => None } From 0117033c721d35ade8d815e1fbf83f10d73f15e4 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 23 Jan 2020 19:13:36 +0100 Subject: [PATCH 0780/1253] Add a resume type param to the generator substs ...and unify it with `()` for now --- src/librustc/infer/opaque_types/mod.rs | 1 + src/librustc/traits/util.rs | 2 +- src/librustc/ty/structural_impls.rs | 4 +-- src/librustc/ty/sty.rs | 41 ++++++++++++++++++++------ src/librustc_typeck/check/closure.rs | 5 ++++ src/librustc_typeck/collect.rs | 2 +- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index fe3a5d149f676..d28507f6eb2e3 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -744,6 +744,7 @@ where substs.as_generator().return_ty(def_id, self.tcx).visit_with(self); substs.as_generator().yield_ty(def_id, self.tcx).visit_with(self); + substs.as_generator().resume_ty(def_id, self.tcx).visit_with(self); } _ => { ty.super_visit_with(self); diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 947d66e38b434..d4c3518260c60 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -645,7 +645,7 @@ pub fn generator_trait_ref_and_outputs( ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[tcx.mk_unit().into()]), + substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), }; ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c1ae4d9fe1724..9d00d27226320 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -598,8 +598,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> { type Lifted = ty::GenSig<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&(self.yield_ty, self.return_ty)) - .map(|(yield_ty, return_ty)| ty::GenSig { yield_ty, return_ty }) + tcx.lift(&(self.resume_ty, self.yield_ty, self.return_ty)) + .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty }) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index dffe86d946212..0d30395d2501b 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -346,9 +346,17 @@ static_assert_size!(TyKind<'_>, 24); /// ## Generators /// /// Generators are handled similarly in `GeneratorSubsts`. The set of -/// type parameters is similar, but the role of CK and CS are -/// different. CK represents the "yield type" and CS represents the -/// "return type" of the generator. +/// type parameters is similar, but `CK` and `CS` are replaced by the +/// following type parameters: +/// +/// * `GS`: The generator's "resume type", which is the type of the +/// argument passed to `resume`, and the type of `yield` expressions +/// inside the generator. +/// * `GY`: The "yield type", which is the type of values passed to +/// `yield` inside the generator. +/// * `GR`: The "return type", which is the type of value returned upon +/// completion of the generator. +/// * `GW`: The "generator witness". #[derive(Copy, Clone, Debug, TypeFoldable)] pub struct ClosureSubsts<'tcx> { /// Lifetime and type parameters from the enclosing function, @@ -442,6 +450,7 @@ pub struct GeneratorSubsts<'tcx> { } struct SplitGeneratorSubsts<'tcx> { + resume_ty: Ty<'tcx>, yield_ty: Ty<'tcx>, return_ty: Ty<'tcx>, witness: Ty<'tcx>, @@ -453,10 +462,11 @@ impl<'tcx> GeneratorSubsts<'tcx> { let generics = tcx.generics_of(def_id); let parent_len = generics.parent_count; SplitGeneratorSubsts { - yield_ty: self.substs.type_at(parent_len), - return_ty: self.substs.type_at(parent_len + 1), - witness: self.substs.type_at(parent_len + 2), - upvar_kinds: &self.substs[parent_len + 3..], + resume_ty: self.substs.type_at(parent_len), + yield_ty: self.substs.type_at(parent_len + 1), + return_ty: self.substs.type_at(parent_len + 2), + witness: self.substs.type_at(parent_len + 3), + upvar_kinds: &self.substs[parent_len + 4..], } } @@ -485,6 +495,11 @@ impl<'tcx> GeneratorSubsts<'tcx> { }) } + /// Returns the type representing the resume type of the generator. + pub fn resume_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { + self.split(def_id, tcx).resume_ty + } + /// Returns the type representing the yield type of the generator. pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { self.split(def_id, tcx).yield_ty @@ -505,10 +520,14 @@ impl<'tcx> GeneratorSubsts<'tcx> { ty::Binder::dummy(self.sig(def_id, tcx)) } - /// Returns the "generator signature", which consists of its yield + /// Returns the "generator signature", which consists of its resume, yield /// and return types. pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> { - ty::GenSig { yield_ty: self.yield_ty(def_id, tcx), return_ty: self.return_ty(def_id, tcx) } + ty::GenSig { + resume_ty: self.resume_ty(def_id, tcx), + yield_ty: self.yield_ty(def_id, tcx), + return_ty: self.return_ty(def_id, tcx), + } } } @@ -1072,6 +1091,7 @@ impl<'tcx> ProjectionTy<'tcx> { #[derive(Clone, Debug, TypeFoldable)] pub struct GenSig<'tcx> { + pub resume_ty: Ty<'tcx>, pub yield_ty: Ty<'tcx>, pub return_ty: Ty<'tcx>, } @@ -1079,6 +1099,9 @@ pub struct GenSig<'tcx> { pub type PolyGenSig<'tcx> = Binder>; impl<'tcx> PolyGenSig<'tcx> { + pub fn resume_ty(&self) -> ty::Binder> { + self.map_bound_ref(|sig| sig.resume_ty) + } pub fn yield_ty(&self) -> ty::Binder> { self.map_bound_ref(|sig| sig.yield_ty) } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 084e6c8d083c5..97067e0b0551d 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -94,6 +94,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types { let generator_substs = substs.as_generator(); + self.demand_eqtype( + expr.span, + self.tcx.mk_unit(), // WIP + generator_substs.resume_ty(expr_def_id, self.tcx), + ); self.demand_eqtype( expr.span, yield_ty, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4d812d2621c61..dc089c9045693 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1189,7 +1189,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { // and we don't do that for closures. if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., gen), .. }) = node { let dummy_args = if gen.is_some() { - &["", "", ""][..] + &["", "", "", ""][..] } else { &["", ""][..] }; From 25af2f66cec1366f845e1de1bfec8b64d4f5cfff Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:27:05 +0100 Subject: [PATCH 0781/1253] Use real resume type as second argument --- src/librustc/ty/layout.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 966b60c6cfbc1..0a5ab790adbab 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2350,7 +2350,8 @@ impl<'tcx> ty::Instance<'tcx> { ]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - tcx.mk_fn_sig([env_ty, tcx.mk_unit()].iter(), + tcx.mk_fn_sig( + [env_ty, sig.resume_ty].iter(), &ret_ty, false, hir::Unsafety::Normal, From 8a1227a67bd5df8a8f27c02b7032bd8092d44a92 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:27:51 +0100 Subject: [PATCH 0782/1253] Infer type of `yield` to be resume type --- src/librustc_typeck/check/closure.rs | 5 +++-- src/librustc_typeck/check/expr.rs | 11 +++++++---- src/librustc_typeck/check/mod.rs | 18 ++++++++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 97067e0b0551d..fd6be8520510b 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -92,11 +92,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into(), GenericParamDefKind::Const => span_bug!(expr.span, "closure has const param"), }); - if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types { + if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types + { let generator_substs = substs.as_generator(); self.demand_eqtype( expr.span, - self.tcx.mk_unit(), // WIP + resume_ty, generator_substs.resume_ty(expr_def_id, self.tcx), ); self.demand_eqtype( diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index b4c2b85241f96..9ce89bd636304 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1796,9 +1796,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, src: &'tcx hir::YieldSource, ) -> Ty<'tcx> { - match self.yield_ty { - Some(ty) => { - self.check_expr_coercable_to_type(&value, ty); + match self.resume_yield_tys { + Some((resume_ty, yield_ty)) => { + self.check_expr_coercable_to_type(&value, yield_ty); + + resume_ty } // Given that this `yield` expression was generated as a result of lowering a `.await`, // we know that the yield type must be `()`; however, the context won't contain this @@ -1806,6 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // value's type against `()` (this check should always hold). None if src == &hir::YieldSource::Await => { self.check_expr_coercable_to_type(&value, self.tcx.mk_unit()); + self.tcx.mk_unit() } _ => { struct_span_err!( @@ -1815,9 +1818,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "yield expression outside of generator literal" ) .emit(); + self.tcx.mk_unit() } } - self.tcx.mk_unit() } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0a917a1853eb5..9612500e3b019 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -573,7 +573,7 @@ pub struct FnCtxt<'a, 'tcx> { /// First span of a return site that we find. Used in error messages. ret_coercion_span: RefCell>, - yield_ty: Option>, + resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>, ps: RefCell, @@ -1248,6 +1248,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { /// includes yield), it returns back some information about the yield /// points. struct GeneratorTypes<'tcx> { + /// Type of generator argument / values returned by `yield`. + resume_ty: Ty<'tcx>, + /// Type of value that is yielded. yield_ty: Ty<'tcx>, @@ -1308,7 +1311,11 @@ fn check_fn<'a, 'tcx>( let yield_ty = fcx .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType); - fcx.yield_ty = Some(yield_ty); + + // Resume type defaults to `()` if the generator has no argument. + let resume_ty = fn_sig.inputs().get(0).map(|ty| *ty).unwrap_or_else(|| tcx.mk_unit()); + + fcx.resume_yield_tys = Some((resume_ty, yield_ty)); } let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id)); @@ -1361,8 +1368,11 @@ fn check_fn<'a, 'tcx>( let interior = fcx .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }); fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind)); + + let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap(); Some(GeneratorTypes { - yield_ty: fcx.yield_ty.unwrap(), + resume_ty, + yield_ty, interior, movability: can_be_generator.unwrap(), }) @@ -2764,7 +2774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err_count_on_creation: inh.tcx.sess.err_count(), ret_coercion: None, ret_coercion_span: RefCell::new(None), - yield_ty: None, + resume_yield_tys: None, ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), diverges: Cell::new(Diverges::Maybe), has_errors: Cell::new(false), From 32005fe1957fc163036fbe0da8b12d39a9fb54cb Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:28:41 +0100 Subject: [PATCH 0783/1253] Allow 0 or 1 explicit generator parameters --- src/librustc_ast_lowering/expr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 5dc855e935c07..0c4cfa1f6505a 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -688,12 +688,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> Option { match generator_kind { Some(hir::GeneratorKind::Gen) => { - if !decl.inputs.is_empty() { + if decl.inputs.len() > 1 { struct_span_err!( self.sess, fn_decl_span, E0628, - "generators cannot have explicit parameters" + "too many parameters for generator (expected 0 or 1 parameters)" ) .emit(); } From 2101a1fec0e53677e32d1389b44f70a987a97c8d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:29:09 +0100 Subject: [PATCH 0784/1253] Adjust tests to type inference changes This makes some error messages ungreat, but those seem to be preexisting bugs that also apply to closures / return position `impl Trait` in general. --- .../generator-yielding-or-returning-itself.rs | 2 +- ...erator-yielding-or-returning-itself.stderr | 21 ++++++------ .../generator/no-parameters-on-generators.rs | 4 ++- .../no-parameters-on-generators.stderr | 32 +++++++++++++++---- .../type-mismatch-signature-deduction.rs | 6 ++-- .../type-mismatch-signature-deduction.stderr | 25 +++++++++++---- 6 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/test/ui/generator-yielding-or-returning-itself.rs b/src/test/ui/generator-yielding-or-returning-itself.rs index fd52667981873..30788e3c1864b 100644 --- a/src/test/ui/generator-yielding-or-returning-itself.rs +++ b/src/test/ui/generator-yielding-or-returning-itself.rs @@ -13,7 +13,7 @@ pub fn want_cyclic_generator_return(_: T) fn supply_cyclic_generator_return() { want_cyclic_generator_return(|| { - //~^ ERROR closure/generator type that references itself + //~^ ERROR type mismatch if false { yield None.unwrap(); } None.unwrap() }) diff --git a/src/test/ui/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator-yielding-or-returning-itself.stderr index c9a71e03858f1..1572219cf4ac8 100644 --- a/src/test/ui/generator-yielding-or-returning-itself.stderr +++ b/src/test/ui/generator-yielding-or-returning-itself.stderr @@ -1,13 +1,13 @@ -error[E0644]: closure/generator type that references itself - --> $DIR/generator-yielding-or-returning-itself.rs:15:34 +error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _] as std::ops::Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _]` + --> $DIR/generator-yielding-or-returning-itself.rs:15:5 | -LL | want_cyclic_generator_return(|| { - | __________________________________^ -LL | | -LL | | if false { yield None.unwrap(); } -LL | | None.unwrap() -LL | | }) - | |_____^ cyclic type of infinite size +LL | pub fn want_cyclic_generator_return(_: T) + | ---------------------------- +LL | where T: Generator + | ---------- required by this bound in `want_cyclic_generator_return` +... +LL | want_cyclic_generator_return(|| { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, @@ -30,5 +30,4 @@ LL | want_cyclic_generator_yield(|| { error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0644. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/generator/no-parameters-on-generators.rs b/src/test/ui/generator/no-parameters-on-generators.rs index 6b5a557933953..cad004895349f 100644 --- a/src/test/ui/generator/no-parameters-on-generators.rs +++ b/src/test/ui/generator/no-parameters-on-generators.rs @@ -1,8 +1,10 @@ #![feature(generators)] fn main() { - let gen = |start| { //~ ERROR generators cannot have explicit parameters + let gen = |start| { //~^ ERROR type inside generator must be known in this context yield; + //~^ ERROR type inside generator must be known in this context + //~| ERROR type inside generator must be known in this context }; } diff --git a/src/test/ui/generator/no-parameters-on-generators.stderr b/src/test/ui/generator/no-parameters-on-generators.stderr index 5e8e043a391ce..f5f83b0476905 100644 --- a/src/test/ui/generator/no-parameters-on-generators.stderr +++ b/src/test/ui/generator/no-parameters-on-generators.stderr @@ -1,9 +1,3 @@ -error[E0628]: generators cannot have explicit parameters - --> $DIR/no-parameters-on-generators.rs:4:15 - | -LL | let gen = |start| { - | ^^^^^^^ - error[E0698]: type inside generator must be known in this context --> $DIR/no-parameters-on-generators.rs:4:16 | @@ -16,6 +10,30 @@ note: the type is part of the generator because of this `yield` LL | yield; | ^^^^^ -error: aborting due to 2 previous errors +error[E0698]: type inside generator must be known in this context + --> $DIR/no-parameters-on-generators.rs:6:9 + | +LL | yield; + | ^^^^^ cannot infer type + | +note: the type is part of the generator because of this `yield` + --> $DIR/no-parameters-on-generators.rs:6:9 + | +LL | yield; + | ^^^^^ + +error[E0698]: type inside generator must be known in this context + --> $DIR/no-parameters-on-generators.rs:6:9 + | +LL | yield; + | ^^^^^ cannot infer type + | +note: the type is part of the generator because of this `yield` + --> $DIR/no-parameters-on-generators.rs:6:9 + | +LL | yield; + | ^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0698`. diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs index b9c6bc5d0796e..7774ff48f56b7 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.rs +++ b/src/test/ui/generator/type-mismatch-signature-deduction.rs @@ -2,15 +2,15 @@ use std::ops::Generator; -fn foo() -> impl Generator { +fn foo() -> impl Generator { //~ ERROR type mismatch || { if false { - return Ok(6); //~ ERROR mismatched types [E0308] + return Ok(6); } yield (); - 5 + 5 //~ ERROR mismatched types [E0308] } } diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index 8606ecd33dab4..8de77798ff48e 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -1,12 +1,23 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-signature-deduction.rs:8:20 + --> $DIR/type-mismatch-signature-deduction.rs:13:9 | -LL | return Ok(6); - | ^^^^^ expected `i32`, found enum `std::result::Result` +LL | 5 + | ^ expected enum `std::result::Result`, found integer | - = note: expected type `i32` - found enum `std::result::Result<{integer}, _>` + = note: expected type `std::result::Result<{integer}, _>` + found type `{integer}` -error: aborting due to previous error +error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6 _] as std::ops::Generator>::Return == i32` + --> $DIR/type-mismatch-signature-deduction.rs:5:13 + | +LL | fn foo() -> impl Generator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `i32` + | + = note: expected enum `std::result::Result<{integer}, _>` + found type `i32` + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0271, E0308. +For more information about an error, try `rustc --explain E0271`. From f2c1468965a7af5887d353adf77427344327be0d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:30:46 +0100 Subject: [PATCH 0785/1253] Add resume arg place to `Yield` MIR terminator --- src/librustc/mir/mod.rs | 11 ++++++++--- src/librustc/mir/visit.rs | 6 ++++++ src/librustc_mir/borrow_check/invalidation.rs | 4 +++- src/librustc_mir/borrow_check/mod.rs | 4 +++- src/librustc_mir/borrow_check/universal_regions.rs | 4 +++- src/librustc_mir/dataflow/move_paths/builder.rs | 4 +++- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 4e9835a52b779..f6c7174649fe8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1120,6 +1120,8 @@ pub enum TerminatorKind<'tcx> { value: Operand<'tcx>, /// Where to resume to. resume: BasicBlock, + /// The place to store the resume argument in. + resume_arg: Place<'tcx>, /// Cleanup to be done if the generator is dropped at this suspend point. drop: Option, }, @@ -2645,9 +2647,12 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { target, unwind, }, - Yield { ref value, resume, drop } => { - Yield { value: value.fold_with(folder), resume: resume, drop: drop } - } + Yield { ref value, resume, ref resume_arg, drop } => Yield { + value: value.fold_with(folder), + resume, + resume_arg: resume_arg.fold_with(folder), + drop, + }, Call { ref func, ref args, ref destination, cleanup, from_hir_call } => { let dest = destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest)); diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 4c5db1b07d225..2f094516a35d9 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -516,8 +516,14 @@ macro_rules! make_mir_visitor { TerminatorKind::Yield { value, resume: _, + resume_arg, drop: _, } => { + self.visit_place( + resume_arg, + PlaceContext::MutatingUse(MutatingUseContext::Store), + source_location, + ); self.visit_operand(value, source_location); } diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index bb56c11872a29..392f164d3148c 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -159,7 +159,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, index); } } - TerminatorKind::Yield { ref value, resume, drop: _ } => { + TerminatorKind::Yield { ref value, resume, resume_arg, drop: _ } => { self.consume_operand(location, value); // Invalidate all borrows of local places @@ -170,6 +170,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.all_facts.invalidates.push((resume, i)); } } + + self.mutate_place(location, resume_arg, Deep, JustWrite); } TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => { // Invalidate all borrows of local places diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 717359d75c3be..e528159fcef17 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -684,7 +684,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx } } - TerminatorKind::Yield { ref value, resume: _, drop: _ } => { + TerminatorKind::Yield { ref value, resume: _, ref resume_arg, drop: _ } => { self.consume_operand(loc, (value, span), flow_state); if self.movable_generator { @@ -697,6 +697,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx } }); } + + self.mutate_place(loc, (resume_arg, span), Deep, JustWrite, flow_state); } TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => { diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index 6e36508ed60af..f6e3ca2f80900 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -581,9 +581,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::Generator(def_id, substs, movability) => { assert_eq!(self.mir_def_id, def_id); + let resume_ty = substs.as_generator().resume_ty(def_id, tcx); let output = substs.as_generator().return_ty(def_id, tcx); let generator_ty = tcx.mk_generator(def_id, substs, movability); - let inputs_and_output = self.infcx.tcx.intern_type_list(&[generator_ty, output]); + let inputs_and_output = + self.infcx.tcx.intern_type_list(&[generator_ty, resume_ty, output]); ty::Binder::dummy(inputs_and_output) } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 62af196174fd7..6f8caca5e21ef 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -380,7 +380,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.gather_operand(discr); } - TerminatorKind::Yield { ref value, .. } => { + TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => { + self.create_move_path(place); + self.gather_init(place.as_ref(), InitKind::Deep); self.gather_operand(value); } From 3c069a066e50598ef230ba71ed5c5bcf596beb90 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:31:32 +0100 Subject: [PATCH 0786/1253] Change MIR building to fill in the resume place This changes `Yield` from `as_rvalue` to `into` lowering, which could have a possible performance impact. I could imagine special-casing some resume types here to use a simpler lowering for them, but it's unclear if that makes sense at this stage. --- .../build/expr/as_rvalue.rs | 14 ++------- src/librustc_mir_build/build/expr/category.rs | 2 +- src/librustc_mir_build/build/expr/into.rs | 21 ++++++++++++-- src/librustc_mir_build/build/mod.rs | 29 ++++++++++++------- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs index 16795b459b6bd..6f5c5f0dd4c50 100644 --- a/src/librustc_mir_build/build/expr/as_rvalue.rs +++ b/src/librustc_mir_build/build/expr/as_rvalue.rs @@ -230,18 +230,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block = unpack!(this.stmt_expr(block, expr, None)); block.and(this.unit_rvalue()) } - ExprKind::Yield { value } => { - let value = unpack!(block = this.as_operand(block, scope, value)); - let resume = this.cfg.start_new_block(); - let cleanup = this.generator_drop_cleanup(); - this.cfg.terminate( - block, - source_info, - TerminatorKind::Yield { value: value, resume: resume, drop: cleanup }, - ); - resume.and(this.unit_rvalue()) - } - ExprKind::Literal { .. } + ExprKind::Yield { .. } + | ExprKind::Literal { .. } | ExprKind::StaticRef { .. } | ExprKind::Block { .. } | ExprKind::Match { .. } diff --git a/src/librustc_mir_build/build/expr/category.rs b/src/librustc_mir_build/build/expr/category.rs index c4d340953c925..cc139dee63f92 100644 --- a/src/librustc_mir_build/build/expr/category.rs +++ b/src/librustc_mir_build/build/expr/category.rs @@ -50,6 +50,7 @@ impl Category { | ExprKind::Adt { .. } | ExprKind::Borrow { .. } | ExprKind::AddressOf { .. } + | ExprKind::Yield { .. } | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)), ExprKind::Array { .. } @@ -63,7 +64,6 @@ impl Category { | ExprKind::Repeat { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } - | ExprKind::Yield { .. } | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => Some(Category::Constant), diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index 5ef338c624da2..51b0b5bc7cb0b 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -365,6 +365,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.unit() } + ExprKind::Yield { value } => { + let scope = this.local_scope(); + let value = unpack!(block = this.as_operand(block, scope, value)); + let resume = this.cfg.start_new_block(); + let cleanup = this.generator_drop_cleanup(); + this.cfg.terminate( + block, + source_info, + TerminatorKind::Yield { + value, + resume, + resume_arg: destination.clone(), + drop: cleanup, + }, + ); + resume.unit() + } + // these are the cases that are more naturally handled by some other mode ExprKind::Unary { .. } | ExprKind::Binary { .. } @@ -376,8 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::Tuple { .. } | ExprKind::Closure { .. } | ExprKind::Literal { .. } - | ExprKind::StaticRef { .. } - | ExprKind::Yield { .. } => { + | ExprKind::StaticRef { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { // should be handled above Category::Rvalue(RvalueFunc::Into) => false, diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index ab539e6179e3d..4c8d8e3a0eac8 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -68,6 +68,12 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { let fn_sig = cx.tables().liberated_fn_sigs()[id]; let fn_def_id = tcx.hir().local_def_id(id); + let safety = match fn_sig.unsafety { + hir::Unsafety::Normal => Safety::Safe, + hir::Unsafety::Unsafe => Safety::FnUnsafe, + }; + + let body = tcx.hir().body(body_id); let ty = tcx.type_of(fn_def_id); let mut abi = fn_sig.abi; let implicit_argument = match ty.kind { @@ -77,22 +83,23 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { abi = Abi::Rust; vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)] } - ty::Generator(..) => { + ty::Generator(def_id, substs, _) => { let gen_ty = tcx.body_tables(body_id).node_type(id); - vec![ - ArgInfo(gen_ty, None, None, None), - ArgInfo(tcx.mk_unit(), None, None, None), - ] + let resume_ty = substs.as_generator().resume_ty(def_id, tcx); + + // The resume argument may be missing, in that case we need to provide it here. + if body.params.is_empty() { + vec![ + ArgInfo(gen_ty, None, None, None), + ArgInfo(resume_ty, None, None, None), + ] + } else { + vec![ArgInfo(gen_ty, None, None, None)] + } } _ => vec![], }; - let safety = match fn_sig.unsafety { - hir::Unsafety::Normal => Safety::Safe, - hir::Unsafety::Unsafe => Safety::FnUnsafe, - }; - - let body = tcx.hir().body(body_id); let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| { let owner_id = tcx.hir().body_owner(body_id); let opt_ty_info; From 3c22e51e7f6debd96af76f36aa8b090c40b8acb6 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 02:33:52 +0100 Subject: [PATCH 0787/1253] Make generator transform move resume arg around The resume arg is passed as argument `_2` and needs to be moved to the `Yield`s target `Place` --- src/librustc_mir/transform/generator.rs | 26 ++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index a8defd03f7177..c0fefd60f83bc 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -192,9 +192,10 @@ const RETURNED: usize = GeneratorSubsts::RETURNED; /// Generator has been poisoned const POISONED: usize = GeneratorSubsts::POISONED; -struct SuspensionPoint { +struct SuspensionPoint<'tcx> { state: usize, resume: BasicBlock, + resume_arg: Place<'tcx>, drop: Option, storage_liveness: liveness::LiveVarSet, } @@ -216,7 +217,7 @@ struct TransformVisitor<'tcx> { storage_liveness: FxHashMap, // A list of suspension points, generated during the transform - suspension_points: Vec, + suspension_points: Vec>, // The original RETURN_PLACE local new_ret_local: Local, @@ -303,8 +304,8 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { Operand::Move(Place::from(self.new_ret_local)), None, )), - TerminatorKind::Yield { ref value, resume, drop } => { - Some((VariantIdx::new(0), Some(resume), value.clone(), drop)) + TerminatorKind::Yield { ref value, resume, resume_arg, drop } => { + Some((VariantIdx::new(0), Some((resume, resume_arg)), value.clone(), drop)) } _ => None, }; @@ -319,13 +320,14 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { self.make_state(state_idx, v), )), }); - let state = if let Some(resume) = resume { + let state = if let Some((resume, resume_arg)) = resume { // Yield let state = 3 + self.suspension_points.len(); self.suspension_points.push(SuspensionPoint { state, resume, + resume_arg, drop, storage_liveness: self.storage_liveness.get(&block).unwrap().clone(), }); @@ -1063,7 +1065,7 @@ fn create_cases<'tcx, F>( target: F, ) -> Vec<(usize, BasicBlock)> where - F: Fn(&SuspensionPoint) -> Option, + F: Fn(&SuspensionPoint<'tcx>) -> Option, { let source_info = source_info(body); @@ -1085,6 +1087,16 @@ where } } + // Move the resume argument to the destination place of the `Yield` terminator + let resume_arg = Local::new(2); // 0 = return, 1 = self + statements.push(Statement { + source_info, + kind: StatementKind::Assign(box ( + point.resume_arg, + Rvalue::Use(Operand::Move(resume_arg.into())), + )), + }); + // Then jump to the real target body.basic_blocks_mut().push(BasicBlockData { statements, @@ -1163,7 +1175,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { }; transform.visit_body(body); - // Update our MIR struct to reflect the changed we've made + // Update our MIR struct to reflect the changes we've made body.yield_ty = None; body.arg_count = 2; // self, resume arg body.spread_arg = None; From 5b2059b2572cff9974e6820791c8ab57b6c50234 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 24 Jan 2020 00:49:44 +0100 Subject: [PATCH 0788/1253] Fix error message on type mismatch in generator Instead of "closure is expected to take 0 arguments" we now get the expected type mismatch error. --- src/librustc_typeck/check/closure.rs | 5 +++-- src/test/ui/generator/type-mismatch-error.rs | 22 +++++++++++++++++++ .../ui/generator/type-mismatch-error.stderr | 19 ++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/generator/type-mismatch-error.rs create mode 100644 src/test/ui/generator/type-mismatch-error.stderr diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index fd6be8520510b..26777b3b01048 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -265,8 +265,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return None, } } else { - // Generators cannot have explicit arguments. - vec![] + // Generators with a `()` resume type may be defined with 0 or 1 explicit arguments, + // else they must have exactly 1 argument. For now though, just give up in this case. + return None; }; let ret_param_ty = projection.skip_binder().ty; diff --git a/src/test/ui/generator/type-mismatch-error.rs b/src/test/ui/generator/type-mismatch-error.rs new file mode 100644 index 0000000000000..d39c788a84bd4 --- /dev/null +++ b/src/test/ui/generator/type-mismatch-error.rs @@ -0,0 +1,22 @@ +//! Test that we get the expected type mismatch error instead of "closure is expected to take 0 +//! arguments" (which got introduced after implementing resume arguments). + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn f(_: G, _: G::Return) {} + +fn main() { + f( + |a: u8| { + if false { + yield (); + } else { + a + //~^ error: `if` and `else` have incompatible types + } + }, + 0u8, + ); +} diff --git a/src/test/ui/generator/type-mismatch-error.stderr b/src/test/ui/generator/type-mismatch-error.stderr new file mode 100644 index 0000000000000..8f5949533e2c7 --- /dev/null +++ b/src/test/ui/generator/type-mismatch-error.stderr @@ -0,0 +1,19 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/type-mismatch-error.rs:16:17 + | +LL | / if false { +LL | | yield (); + | | --------- + | | | | + | | | help: consider removing this semicolon + | | expected because of this +LL | | } else { +LL | | a + | | ^ expected `()`, found `u8` +LL | | +LL | | } + | |_____________- `if` and `else` have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From fca614eb578092fd869df57d6654ba0dcf92c6ef Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 24 Jan 2020 21:56:08 +0100 Subject: [PATCH 0789/1253] Add tests for generator resume arguments --- src/test/ui/generator/retain-resume-ref.rs | 25 +++++ .../ui/generator/retain-resume-ref.stderr | 13 +++ src/test/ui/generator/smoke-resume-args.rs | 97 +++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 src/test/ui/generator/retain-resume-ref.rs create mode 100644 src/test/ui/generator/retain-resume-ref.stderr create mode 100644 src/test/ui/generator/smoke-resume-args.rs diff --git a/src/test/ui/generator/retain-resume-ref.rs b/src/test/ui/generator/retain-resume-ref.rs new file mode 100644 index 0000000000000..0606ea71cdf37 --- /dev/null +++ b/src/test/ui/generator/retain-resume-ref.rs @@ -0,0 +1,25 @@ +//! This test ensures that a mutable reference cannot be passed as a resume argument twice. + +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::{ + Generator, + GeneratorState::{self, *}, +}; +use std::pin::Pin; + +fn main() { + let mut thing = String::from("hello"); + + let mut gen = |r| { + if false { + yield r; + } + }; + + let mut gen = Pin::new(&mut gen); + gen.as_mut().resume(&mut thing); + gen.as_mut().resume(&mut thing); + //~^ cannot borrow `thing` as mutable more than once at a time +} diff --git a/src/test/ui/generator/retain-resume-ref.stderr b/src/test/ui/generator/retain-resume-ref.stderr new file mode 100644 index 0000000000000..e33310d12d9ef --- /dev/null +++ b/src/test/ui/generator/retain-resume-ref.stderr @@ -0,0 +1,13 @@ +error[E0499]: cannot borrow `thing` as mutable more than once at a time + --> $DIR/retain-resume-ref.rs:23:25 + | +LL | gen.as_mut().resume(&mut thing); + | ---------- first mutable borrow occurs here +LL | gen.as_mut().resume(&mut thing); + | ------ ^^^^^^^^^^ second mutable borrow occurs here + | | + | first borrow later used by call + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/generator/smoke-resume-args.rs b/src/test/ui/generator/smoke-resume-args.rs new file mode 100644 index 0000000000000..32f3ee32d77b9 --- /dev/null +++ b/src/test/ui/generator/smoke-resume-args.rs @@ -0,0 +1,97 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::fmt::Debug; +use std::marker::Unpin; +use std::ops::{ + Generator, + GeneratorState::{self, *}, +}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +fn drain + Unpin, R, Y>( + gen: &mut G, + inout: Vec<(R, GeneratorState)>, +) where + Y: Debug + PartialEq, + G::Return: Debug + PartialEq, +{ + let mut gen = Pin::new(gen); + + for (input, out) in inout { + assert_eq!(gen.as_mut().resume(input), out); + } +} + +static DROPS: AtomicUsize = AtomicUsize::new(0); + +#[derive(Debug, PartialEq)] +struct DropMe; + +impl Drop for DropMe { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::SeqCst); + } +} + +fn expect_drops(expected_drops: usize, f: impl FnOnce() -> T) -> T { + DROPS.store(0, Ordering::SeqCst); + + let res = f(); + + let actual_drops = DROPS.load(Ordering::SeqCst); + assert_eq!(actual_drops, expected_drops); + res +} + +fn main() { + drain( + &mut |mut b| { + while b != 0 { + b = yield (b + 1); + } + -1 + }, + vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))], + ); + + expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))])); + + expect_drops(6, || { + drain( + &mut |a| yield yield a, + vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))], + ) + }); + + #[allow(unreachable_code)] + expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))])); + + expect_drops(2, || { + drain( + &mut |a: DropMe| { + if false { yield () } else { a } + }, + vec![(DropMe, Complete(DropMe))], + ) + }); + + expect_drops(4, || { + drain( + #[allow(unused_assignments, unused_variables)] + &mut |mut a: DropMe| { + a = yield; + a = yield; + a = yield; + }, + vec![ + (DropMe, Yielded(())), + (DropMe, Yielded(())), + (DropMe, Yielded(())), + (DropMe, Complete(())), + ], + ) + }); +} From 4ee857c4c3ecb15d4bc5aebe4fa7ba67dce797b5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 24 Jan 2020 23:00:45 +0100 Subject: [PATCH 0790/1253] Add test for E0628 (too many generator parameters) --- src/test/ui/generator/too-many-parameters.rs | 7 +++++++ src/test/ui/generator/too-many-parameters.stderr | 8 ++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/generator/too-many-parameters.rs create mode 100644 src/test/ui/generator/too-many-parameters.stderr diff --git a/src/test/ui/generator/too-many-parameters.rs b/src/test/ui/generator/too-many-parameters.rs new file mode 100644 index 0000000000000..a0a27d9068241 --- /dev/null +++ b/src/test/ui/generator/too-many-parameters.rs @@ -0,0 +1,7 @@ +#![feature(generators)] + +fn main() { + |(), ()| { //~ error: too many parameters for generator + yield; + }; +} diff --git a/src/test/ui/generator/too-many-parameters.stderr b/src/test/ui/generator/too-many-parameters.stderr new file mode 100644 index 0000000000000..0dbe5f3f6fde9 --- /dev/null +++ b/src/test/ui/generator/too-many-parameters.stderr @@ -0,0 +1,8 @@ +error[E0628]: too many parameters for generator (expected 0 or 1 parameters) + --> $DIR/too-many-parameters.rs:4:5 + | +LL | |(), ()| { + | ^^^^^^^^ + +error: aborting due to previous error + From 7a9709b08a57620a791259b53d71a59acf8f7b5c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 24 Jan 2020 23:55:54 +0100 Subject: [PATCH 0791/1253] Fix bootstrap rustc build --- src/librustc_data_structures/box_region.rs | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/librustc_data_structures/box_region.rs b/src/librustc_data_structures/box_region.rs index 94abb89503c03..dbc54291f4087 100644 --- a/src/librustc_data_structures/box_region.rs +++ b/src/librustc_data_structures/box_region.rs @@ -25,6 +25,7 @@ pub struct PinnedGenerator { } impl PinnedGenerator { + #[cfg(bootstrap)] pub fn new, Return = R> + 'static>( generator: T, ) -> (I, Self) { @@ -39,6 +40,22 @@ impl PinnedGenerator { (init, result) } + #[cfg(not(bootstrap))] + pub fn new, Return = R> + 'static>( + generator: T, + ) -> (I, Self) { + let mut result = PinnedGenerator { generator: Box::pin(generator) }; + + // Run it to the first yield to set it up + let init = match Pin::new(&mut result.generator).resume(()) { + GeneratorState::Yielded(YieldType::Initial(y)) => y, + _ => panic!(), + }; + + (init, result) + } + + #[cfg(bootstrap)] pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) { BOX_REGION_ARG.with(|i| { i.set(Action::Access(AccessAction(closure))); @@ -50,6 +67,19 @@ impl PinnedGenerator { } } + #[cfg(not(bootstrap))] + pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) { + BOX_REGION_ARG.with(|i| { + i.set(Action::Access(AccessAction(closure))); + }); + + // Call the generator, which in turn will call the closure in BOX_REGION_ARG + if let GeneratorState::Complete(_) = Pin::new(&mut self.generator).resume(()) { + panic!() + } + } + + #[cfg(bootstrap)] pub fn complete(&mut self) -> R { // Tell the generator we want it to complete, consuming it and yielding a result BOX_REGION_ARG.with(|i| i.set(Action::Complete)); @@ -57,6 +87,15 @@ impl PinnedGenerator { let result = Pin::new(&mut self.generator).resume(); if let GeneratorState::Complete(r) = result { r } else { panic!() } } + + #[cfg(not(bootstrap))] + pub fn complete(&mut self) -> R { + // Tell the generator we want it to complete, consuming it and yielding a result + BOX_REGION_ARG.with(|i| i.set(Action::Complete)); + + let result = Pin::new(&mut self.generator).resume(()); + if let GeneratorState::Complete(r) = result { r } else { panic!() } + } } #[derive(PartialEq)] From 3bb8ecb512a632fb3f5568e4e443cfe46f2f3ea6 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 25 Jan 2020 16:03:44 +0100 Subject: [PATCH 0792/1253] Adjust mir-opt tests to new `yield` lowering --- src/test/mir-opt/generator-drop-cleanup.rs | 8 +-- .../mir-opt/generator-storage-dead-unwind.rs | 52 +++++++++---------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs index f97e1ba6c89d4..307370f14358e 100644 --- a/src/test/mir-opt/generator-drop-cleanup.rs +++ b/src/test/mir-opt/generator-drop-cleanup.rs @@ -13,12 +13,12 @@ fn main() { // START rustc.main-{{closure}}.generator_drop.0.mir // bb0: { -// _5 = discriminant((*_1)); -// switchInt(move _5) -> [0u32: bb4, 3u32: bb7, otherwise: bb8]; +// _6 = discriminant((*_1)); +// switchInt(move _6) -> [0u32: bb4, 3u32: bb7, otherwise: bb8]; // } // bb1: { +// StorageDead(_4); // StorageDead(_3); -// StorageDead(_2); // goto -> bb5; // } // bb2: { @@ -39,6 +39,8 @@ fn main() { // bb7: { // StorageLive(_2); // StorageLive(_3); +// StorageLive(_4); +// _3 = move _2; // goto -> bb1; // } // bb8: { diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs index ecce0a08c7bf0..4442fa5f52126 100644 --- a/src/test/mir-opt/generator-storage-dead-unwind.rs +++ b/src/test/mir-opt/generator-storage-dead-unwind.rs @@ -31,81 +31,81 @@ fn main() { // START rustc.main-{{closure}}.StateTransform.before.mir // ... -// let _2: Foo; +// let _3: Foo; // ... -// let mut _7: Foo; +// let mut _8: Foo; // ... -// let mut _9: Bar; +// let mut _10: Bar; // scope 1 { -// debug a => _2; -// let _3: Bar; +// debug a => _3; +// let _4: Bar; // scope 2 { -// debug b => _3; +// debug b => _4; // } // } // bb0: { -// StorageLive(_2); -// _2 = Foo(const 5i32,); // StorageLive(_3); -// _3 = Bar(const 6i32,); +// _3 = Foo(const 5i32,); +// StorageLive(_4); +// _4 = Bar(const 6i32,); // ... -// _1 = suspend(move _5) -> [resume: bb2, drop: bb4]; +// _1 = suspend(move _6) -> [resume: bb2, drop: bb4]; // } // bb1 (cleanup): { // resume; // } // bb2: { // ... -// StorageLive(_6); // StorageLive(_7); -// _7 = move _2; -// _6 = const take::(move _7) -> [return: bb7, unwind: bb9]; +// StorageLive(_8); +// _8 = move _3; +// _7 = const take::(move _8) -> [return: bb7, unwind: bb9]; // } // bb3 (cleanup): { -// StorageDead(_2); +// StorageDead(_3); // drop(_1) -> bb1; // } // bb4: { // ... -// StorageDead(_3); -// drop(_2) -> [return: bb5, unwind: bb3]; +// StorageDead(_4); +// drop(_3) -> [return: bb5, unwind: bb3]; // } // bb5: { -// StorageDead(_2); +// StorageDead(_3); // drop(_1) -> [return: bb6, unwind: bb1]; // } // bb6: { // generator_drop; // } // bb7: { +// StorageDead(_8); // StorageDead(_7); -// StorageDead(_6); -// StorageLive(_8); // StorageLive(_9); -// _9 = move _3; -// _8 = const take::(move _9) -> [return: bb10, unwind: bb11]; +// StorageLive(_10); +// _10 = move _4; +// _9 = const take::(move _10) -> [return: bb10, unwind: bb11]; // } // bb8 (cleanup): { +// StorageDead(_4); // StorageDead(_3); -// StorageDead(_2); // drop(_1) -> bb1; // } // bb9 (cleanup): { +// StorageDead(_8); // StorageDead(_7); -// StorageDead(_6); // goto -> bb8; // } // bb10: { +// StorageDead(_10); // StorageDead(_9); -// StorageDead(_8); // ... +// StorageDead(_4); // StorageDead(_3); -// StorageDead(_2); // drop(_1) -> [return: bb12, unwind: bb1]; // } // bb11 (cleanup): { +// StorageDead(_10); // StorageDead(_9); -// StorageDead(_8); // goto -> bb8; // } // bb12: { From aae0f543cff16afe27384171e83de91887bc9f4d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 27 Jan 2020 22:32:57 +0100 Subject: [PATCH 0793/1253] No resume argument in the drop shim --- src/librustc_mir/transform/generator.rs | 51 ++++++++++++++-------- src/test/mir-opt/generator-drop-cleanup.rs | 1 - 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index c0fefd60f83bc..b5edcbe457b63 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -891,7 +891,7 @@ fn create_generator_drop_shim<'tcx>( let source_info = source_info(&body); - let mut cases = create_cases(&mut body, transform, |point| point.drop); + let mut cases = create_cases(&mut body, transform, Operation::Drop); cases.insert(0, (UNRESUMED, drop_clean)); @@ -1009,7 +1009,7 @@ fn create_generator_resume_function<'tcx>( } } - let mut cases = create_cases(body, &transform, |point| Some(point.resume)); + let mut cases = create_cases(body, &transform, Operation::Resume); use rustc::mir::interpret::PanicInfo::{ResumedAfterPanic, ResumedAfterReturn}; @@ -1059,14 +1059,27 @@ fn insert_clean_drop(body: &mut BodyAndCache<'_>) -> BasicBlock { drop_clean } -fn create_cases<'tcx, F>( +/// An operation that can be performed on a generator. +#[derive(PartialEq, Copy, Clone)] +enum Operation { + Resume, + Drop, +} + +impl Operation { + fn target_block(self, point: &SuspensionPoint<'_>) -> Option { + match self { + Operation::Resume => Some(point.resume), + Operation::Drop => point.drop, + } + } +} + +fn create_cases<'tcx>( body: &mut BodyAndCache<'tcx>, transform: &TransformVisitor<'tcx>, - target: F, -) -> Vec<(usize, BasicBlock)> -where - F: Fn(&SuspensionPoint<'tcx>) -> Option, -{ + operation: Operation, +) -> Vec<(usize, BasicBlock)> { let source_info = source_info(body); transform @@ -1074,7 +1087,7 @@ where .iter() .filter_map(|point| { // Find the target for this suspension point, if applicable - target(point).map(|target| { + operation.target_block(point).map(|target| { let block = BasicBlock::new(body.basic_blocks().len()); let mut statements = Vec::new(); @@ -1087,15 +1100,17 @@ where } } - // Move the resume argument to the destination place of the `Yield` terminator - let resume_arg = Local::new(2); // 0 = return, 1 = self - statements.push(Statement { - source_info, - kind: StatementKind::Assign(box ( - point.resume_arg, - Rvalue::Use(Operand::Move(resume_arg.into())), - )), - }); + if operation == Operation::Resume { + // Move the resume argument to the destination place of the `Yield` terminator + let resume_arg = Local::new(2); // 0 = return, 1 = self + statements.push(Statement { + source_info, + kind: StatementKind::Assign(box ( + point.resume_arg, + Rvalue::Use(Operand::Move(resume_arg.into())), + )), + }); + } // Then jump to the real target body.basic_blocks_mut().push(BasicBlockData { diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs index 307370f14358e..e5f3f9221c098 100644 --- a/src/test/mir-opt/generator-drop-cleanup.rs +++ b/src/test/mir-opt/generator-drop-cleanup.rs @@ -40,7 +40,6 @@ fn main() { // StorageLive(_2); // StorageLive(_3); // StorageLive(_4); -// _3 = move _2; // goto -> bb1; // } // bb8: { From 9fa46fe15367a8154f38371d0d913fa2f97f6416 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 27 Jan 2020 23:26:37 +0100 Subject: [PATCH 0794/1253] Teach dropck about resume arguments --- src/librustc_traits/dropck_outlives.rs | 5 +-- src/test/ui/generator/dropck-resume.rs | 33 +++++++++++++++++++ src/test/ui/generator/dropck-resume.stderr | 15 +++++++++ .../ui/generator/retain-resume-ref.stderr | 7 ++-- 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/generator/dropck-resume.rs create mode 100644 src/test/ui/generator/dropck-resume.stderr diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index bc4d03cca7fee..346d2a931d10b 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -227,8 +227,8 @@ fn dtorck_constraint_for_ty<'tcx>( // In particular, skipping over `_interior` is safe // because any side-effects from dropping `_interior` can // only take place through references with lifetimes - // derived from lifetimes attached to the upvars, and we - // *do* incorporate the upvars here. + // derived from lifetimes attached to the upvars and resume + // argument, and we *do* incorporate those here. constraints.outlives.extend( substs @@ -236,6 +236,7 @@ fn dtorck_constraint_for_ty<'tcx>( .upvar_tys(def_id, tcx) .map(|t| -> ty::subst::GenericArg<'tcx> { t.into() }), ); + constraints.outlives.push(substs.as_generator().resume_ty(def_id, tcx).into()); } ty::Adt(def, substs) => { diff --git a/src/test/ui/generator/dropck-resume.rs b/src/test/ui/generator/dropck-resume.rs new file mode 100644 index 0000000000000..4c18077f33573 --- /dev/null +++ b/src/test/ui/generator/dropck-resume.rs @@ -0,0 +1,33 @@ +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +struct SetToNone<'a: 'b, 'b>(&'b mut Option<&'a i32>); + +impl<'a, 'b> Drop for SetToNone<'a, 'b> { + fn drop(&mut self) { + *self.0 = None; + } +} + +fn drop_using_generator() -> i32 { + let mut y = Some(&0); + let z = &mut y; + let r; + { + let mut g = move |r| { + let _s = SetToNone(r); + yield; + }; + let mut g = Pin::new(&mut g); + g.as_mut().resume(z); + r = y.as_ref().unwrap(); + //~^ ERROR cannot borrow `y` as immutable because it is also borrowed as mutable + } + **r +} + +fn main() { + println!("{}", drop_using_generator()); +} diff --git a/src/test/ui/generator/dropck-resume.stderr b/src/test/ui/generator/dropck-resume.stderr new file mode 100644 index 0000000000000..ecf92e7e3ae79 --- /dev/null +++ b/src/test/ui/generator/dropck-resume.stderr @@ -0,0 +1,15 @@ +error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable + --> $DIR/dropck-resume.rs:25:13 + | +LL | let z = &mut y; + | ------ mutable borrow occurs here +... +LL | r = y.as_ref().unwrap(); + | ^ immutable borrow occurs here +LL | +LL | } + | - mutable borrow might be used here, when `g` is dropped and runs the destructor for generator + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/generator/retain-resume-ref.stderr b/src/test/ui/generator/retain-resume-ref.stderr index e33310d12d9ef..bc715c7030eb3 100644 --- a/src/test/ui/generator/retain-resume-ref.stderr +++ b/src/test/ui/generator/retain-resume-ref.stderr @@ -4,9 +4,10 @@ error[E0499]: cannot borrow `thing` as mutable more than once at a time LL | gen.as_mut().resume(&mut thing); | ---------- first mutable borrow occurs here LL | gen.as_mut().resume(&mut thing); - | ------ ^^^^^^^^^^ second mutable borrow occurs here - | | - | first borrow later used by call + | ^^^^^^^^^^ second mutable borrow occurs here +LL | +LL | } + | - first borrow might be used here, when `gen` is dropped and runs the destructor for generator error: aborting due to previous error From 71a6f58229c00720b35579856bdb64e2a19af521 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 11:10:27 +0100 Subject: [PATCH 0795/1253] parser: address review comments re. `self`. --- src/librustc_ast_passes/ast_validation.rs | 4 +- src/librustc_parse/parser/diagnostics.rs | 25 ++--- src/librustc_parse/parser/item.rs | 26 ++--- src/librustc_parse/parser/ty.rs | 3 +- .../ui/invalid-self-argument/bare-fn-start.rs | 4 +- .../bare-fn-start.stderr | 4 +- src/test/ui/invalid-self-argument/bare-fn.rs | 3 +- .../ui/invalid-self-argument/bare-fn.stderr | 4 +- src/test/ui/invalid-self-argument/trait-fn.rs | 2 +- .../ui/invalid-self-argument/trait-fn.stderr | 2 +- src/test/ui/parser/inverted-parameters.rs | 1 + src/test/ui/parser/inverted-parameters.stderr | 6 +- .../ui/parser/omitted-arg-in-item-fn.stderr | 4 + src/test/ui/parser/pat-lt-bracket-2.stderr | 4 + .../ui/parser/self-in-function-arg.stderr | 4 +- .../ui/parser/self-param-semantic-fail.rs | 48 +++++----- .../ui/parser/self-param-semantic-fail.stderr | 96 +++++++++---------- src/test/ui/span/issue-34264.stderr | 8 ++ .../suggestions/issue-64252-self-type.stderr | 4 + 19 files changed, 124 insertions(+), 128 deletions(-) diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index f37f93c0254bd..23c5ef9b3d652 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -372,10 +372,10 @@ impl<'a> AstValidator<'a> { self.err_handler() .struct_span_err( param.span, - "`self` parameter only allowed in associated `fn`s", + "`self` parameter is only allowed in associated functions", ) .span_label(param.span, "not semantically valid as function parameter") - .note("associated `fn`s are those in `impl` or `trait` definitions") + .note("associated functions are those in `impl` or `trait` definitions") .emit(); } } diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 09f393a81abad..4f259d314fbf1 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1336,8 +1336,7 @@ impl<'a> Parser<'a> { err: &mut DiagnosticBuilder<'_>, pat: P, require_name: bool, - is_self_semantic: bool, - in_assoc_item: bool, + first_param: bool, ) -> Option { // If we find a pattern followed by an identifier, it could be an (incorrect) // C-style parameter declaration. @@ -1357,13 +1356,12 @@ impl<'a> Parser<'a> { return Some(ident); } else if let PatKind::Ident(_, ident, _) = pat.kind { if require_name - && (in_assoc_item - || self.token == token::Comma + && (self.token == token::Comma || self.token == token::Lt || self.token == token::CloseDelim(token::Paren)) { // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` - if is_self_semantic { + if first_param { err.span_suggestion( pat.span, "if this is a `self` type, give it a parameter name", @@ -1420,21 +1418,12 @@ impl<'a> Parser<'a> { Ok((pat, ty)) } - pub(super) fn recover_bad_self_param( - &mut self, - mut param: ast::Param, - in_assoc_item: bool, - ) -> PResult<'a, ast::Param> { + pub(super) fn recover_bad_self_param(&mut self, mut param: Param) -> PResult<'a, Param> { let sp = param.pat.span; param.ty.kind = TyKind::Err; - let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function"); - if in_assoc_item { - err.span_label(sp, "must be the first associated function parameter"); - } else { - err.span_label(sp, "not valid as function parameter"); - err.note("`self` is only valid as the first parameter of an associated function"); - } - err.emit(); + self.struct_span_err(sp, "unexpected `self` parameter in function") + .span_label(sp, "must be the first parameter of an associated function") + .emit(); Ok(param) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 0ff595f444413..da5cc0bb83e35 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1715,9 +1715,6 @@ impl<'a> Parser<'a> { /// The parsing configuration used to parse a parameter list (see `parse_fn_params`). pub(super) struct ParamCfg { - /// Is `self` is *semantically* allowed as the first parameter? - /// This is only used for diagnostics. - pub in_assoc_item: bool, /// `is_name_required` decides if, per-parameter, /// the parameter must have a pattern or just a type. pub is_name_required: fn(&token::Token) -> bool, @@ -1733,7 +1730,7 @@ impl<'a> Parser<'a> { attrs: Vec, header: FnHeader, ) -> PResult<'a, Option>> { - let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true }; + let cfg = ParamCfg { is_name_required: |_| true }; let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let kind = ItemKind::Fn(FnSig { decl, header }, generics, body); @@ -1748,7 +1745,7 @@ impl<'a> Parser<'a> { attrs: Vec, extern_sp: Span, ) -> PResult<'a, P> { - let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true }; + let cfg = ParamCfg { is_name_required: |_| true }; self.expect_keyword(kw::Fn)?; let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; let span = lo.to(self.token.span); @@ -1763,9 +1760,8 @@ impl<'a> Parser<'a> { attrs: &mut Vec, is_name_required: fn(&token::Token) -> bool, ) -> PResult<'a, (Ident, AssocItemKind, Generics)> { - let cfg = ParamCfg { in_assoc_item: true, is_name_required }; let header = self.parse_fn_front_matter()?; - let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; + let (ident, decl, generics) = self.parse_fn_sig(&ParamCfg { is_name_required })?; let sig = FnSig { header, decl }; let body = self.parse_assoc_fn_body(at_end, attrs)?; Ok((ident, AssocItemKind::Fn(sig, body), generics)) @@ -1893,11 +1889,7 @@ impl<'a> Parser<'a> { // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. if let Some(mut param) = self.parse_self_param()? { param.attrs = attrs.into(); - return if first_param { - Ok(param) - } else { - self.recover_bad_self_param(param, cfg.in_assoc_item) - }; + return if first_param { Ok(param) } else { self.recover_bad_self_param(param) }; } let is_name_required = match self.token.kind { @@ -1909,13 +1901,9 @@ impl<'a> Parser<'a> { let pat = self.parse_fn_param_pat()?; if let Err(mut err) = self.expect(&token::Colon) { - return if let Some(ident) = self.parameter_without_type( - &mut err, - pat, - is_name_required, - first_param && cfg.in_assoc_item, - cfg.in_assoc_item, - ) { + return if let Some(ident) = + self.parameter_without_type(&mut err, pat, is_name_required, first_param) + { err.emit(); Ok(dummy_arg(ident)) } else { diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 51367a37ad70a..c9c2cbb98ca40 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -288,8 +288,7 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); let ext = self.parse_extern()?; self.expect_keyword(kw::Fn)?; - let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| false }; - let decl = self.parse_fn_decl(&cfg, false)?; + let decl = self.parse_fn_decl(&ParamCfg { is_name_required: |_| false }, false)?; Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl }))) } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs index 8c92b7bc7c4b0..7c580bc5a5dea 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.rs +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -1,6 +1,6 @@ fn a(&self) { } -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions //~| NOTE not semantically valid as function parameter -//~| NOTE associated `fn`s are those in `impl` or `trait` definitions +//~| NOTE associated functions are those in `impl` or `trait` definitions fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr index 59120a60a6df1..37753e61f582a 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -1,10 +1,10 @@ -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/bare-fn-start.rs:1:6 | LL | fn a(&self) { } | ^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs index 73d68e8b7a5ab..342bdc31a7c82 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.rs +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -1,6 +1,5 @@ fn b(foo: u32, &mut self) { } //~^ ERROR unexpected `self` parameter in function -//~| NOTE not valid as function parameter -//~| NOTE `self` is only valid as the first parameter of an associated function +//~| NOTE must be the first parameter of an associated function fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr index 601a51bb4a96a..ff2217b5e80bc 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -2,9 +2,7 @@ error: unexpected `self` parameter in function --> $DIR/bare-fn.rs:1:16 | LL | fn b(foo: u32, &mut self) { } - | ^^^^^^^^^ not valid as function parameter - | - = note: `self` is only valid as the first parameter of an associated function + | ^^^^^^^^^ must be the first parameter of an associated function error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs index 1e8220d7b4a78..5ccea589561cb 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.rs +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -3,7 +3,7 @@ struct Foo {} impl Foo { fn c(foo: u32, self) {} //~^ ERROR unexpected `self` parameter in function - //~| NOTE must be the first associated function parameter + //~| NOTE must be the first parameter of an associated function fn good(&mut self, foo: u32) {} } diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr index 96a2251c036b1..b9887af962cbc 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.stderr +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -2,7 +2,7 @@ error: unexpected `self` parameter in function --> $DIR/trait-fn.rs:4:20 | LL | fn c(foo: u32, self) {} - | ^^^^ must be the first associated function parameter + | ^^^^ must be the first parameter of an associated function error: aborting due to previous error diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs index d6efc8be072bd..6f19ee9c7dc0d 100644 --- a/src/test/ui/parser/inverted-parameters.rs +++ b/src/test/ui/parser/inverted-parameters.rs @@ -21,6 +21,7 @@ fn pattern((i32, i32) (a, b)) {} fn fizz(i32) {} //~^ ERROR expected one of `:`, `@` //~| HELP if this was a parameter name, give it a type +//~| HELP if this is a `self` type, give it a parameter name //~| HELP if this is a type, explicitly ignore the parameter name fn missing_colon(quux S) {} diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr index 51e9087ffc1e1..043ff65f74e1a 100644 --- a/src/test/ui/parser/inverted-parameters.stderr +++ b/src/test/ui/parser/inverted-parameters.stderr @@ -35,6 +35,10 @@ LL | fn fizz(i32) {} | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn fizz(self: i32) {} + | ^^^^^^^^^ help: if this was a parameter name, give it a type | LL | fn fizz(i32: TypeName) {} @@ -45,7 +49,7 @@ LL | fn fizz(_: i32) {} | ^^^^^^ error: expected one of `:`, `@`, or `|`, found `S` - --> $DIR/inverted-parameters.rs:26:23 + --> $DIR/inverted-parameters.rs:27:23 | LL | fn missing_colon(quux S) {} | -----^ diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr index c7c76a7f1d42c..9f138bf84ce19 100644 --- a/src/test/ui/parser/omitted-arg-in-item-fn.stderr +++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr @@ -5,6 +5,10 @@ LL | fn foo(x) { | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn foo(self: x) { + | ^^^^^^^ help: if this was a parameter name, give it a type | LL | fn foo(x: TypeName) { diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr index e51dd57f9c707..6db9a4a0f15a6 100644 --- a/src/test/ui/parser/pat-lt-bracket-2.stderr +++ b/src/test/ui/parser/pat-lt-bracket-2.stderr @@ -5,6 +5,10 @@ LL | fn a(B<) {} | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn a(self: B<) {} + | ^^^^^^^ help: if this is a type, explicitly ignore the parameter name | LL | fn a(_: B<) {} diff --git a/src/test/ui/parser/self-in-function-arg.stderr b/src/test/ui/parser/self-in-function-arg.stderr index f58df9b9e79b3..47d8381b0b1da 100644 --- a/src/test/ui/parser/self-in-function-arg.stderr +++ b/src/test/ui/parser/self-in-function-arg.stderr @@ -2,9 +2,7 @@ error: unexpected `self` parameter in function --> $DIR/self-in-function-arg.rs:1:15 | LL | fn foo(x:i32, self: i32) -> i32 { self } - | ^^^^ not valid as function parameter - | - = note: `self` is only valid as the first parameter of an associated function + | ^^^^ must be the first parameter of an associated function error: aborting due to previous error diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs index 773cf922b4da9..5676971b01ae4 100644 --- a/src/test/ui/parser/self-param-semantic-fail.rs +++ b/src/test/ui/parser/self-param-semantic-fail.rs @@ -6,59 +6,59 @@ fn main() {} fn free() { fn f1(self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f2(mut self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f3(&self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f4(&mut self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f5<'a>(&'a self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f6<'a>(&'a mut self) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f7(self: u8) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f8(mut self: u8) {} - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions } extern { fn f1(self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f2(mut self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR patterns aren't allowed in fn f3(&self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f4(&mut self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f5<'a>(&'a self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f6<'a>(&'a mut self); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f7(self: u8); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions fn f8(mut self: u8); - //~^ ERROR `self` parameter only allowed in associated `fn`s + //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR patterns aren't allowed in } type X1 = fn(self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X2 = fn(mut self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR patterns aren't allowed in type X3 = fn(&self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X4 = fn(&mut self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X5 = for<'a> fn(&'a self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X6 = for<'a> fn(&'a mut self); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X7 = fn(self: u8); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions type X8 = fn(mut self: u8); -//~^ ERROR `self` parameter only allowed in associated `fn`s +//~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR patterns aren't allowed in diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr index b45e4a5d26f16..e5d679773696b 100644 --- a/src/test/ui/parser/self-param-semantic-fail.stderr +++ b/src/test/ui/parser/self-param-semantic-fail.stderr @@ -1,82 +1,82 @@ -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:8:11 | LL | fn f1(self) {} | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:10:11 | LL | fn f2(mut self) {} | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:12:11 | LL | fn f3(&self) {} | ^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:14:11 | LL | fn f4(&mut self) {} | ^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:16:15 | LL | fn f5<'a>(&'a self) {} | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:18:15 | LL | fn f6<'a>(&'a mut self) {} | ^^^^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:20:11 | LL | fn f7(self: u8) {} | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:22:11 | LL | fn f8(mut self: u8) {} | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:27:11 | LL | fn f1(self); | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:29:11 | LL | fn f2(mut self); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions error[E0130]: patterns aren't allowed in foreign function declarations --> $DIR/self-param-semantic-fail.rs:29:11 @@ -84,53 +84,53 @@ error[E0130]: patterns aren't allowed in foreign function declarations LL | fn f2(mut self); | ^^^^^^^^ pattern not allowed in foreign function -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:32:11 | LL | fn f3(&self); | ^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:34:11 | LL | fn f4(&mut self); | ^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:36:15 | LL | fn f5<'a>(&'a self); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:38:15 | LL | fn f6<'a>(&'a mut self); | ^^^^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:40:11 | LL | fn f7(self: u8); | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:42:11 | LL | fn f8(mut self: u8); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions error[E0130]: patterns aren't allowed in foreign function declarations --> $DIR/self-param-semantic-fail.rs:42:11 @@ -138,21 +138,21 @@ error[E0130]: patterns aren't allowed in foreign function declarations LL | fn f8(mut self: u8); | ^^^^^^^^ pattern not allowed in foreign function -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:47:14 | LL | type X1 = fn(self); | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:49:14 | LL | type X2 = fn(mut self); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions error[E0561]: patterns aren't allowed in function pointer types --> $DIR/self-param-semantic-fail.rs:49:14 @@ -160,53 +160,53 @@ error[E0561]: patterns aren't allowed in function pointer types LL | type X2 = fn(mut self); | ^^^^^^^^ -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:52:14 | LL | type X3 = fn(&self); | ^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:54:14 | LL | type X4 = fn(&mut self); | ^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:56:22 | LL | type X5 = for<'a> fn(&'a self); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:58:22 | LL | type X6 = for<'a> fn(&'a mut self); | ^^^^^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:60:14 | LL | type X7 = fn(self: u8); | ^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions -error: `self` parameter only allowed in associated `fn`s +error: `self` parameter is only allowed in associated functions --> $DIR/self-param-semantic-fail.rs:62:14 | LL | type X8 = fn(mut self: u8); | ^^^^^^^^ not semantically valid as function parameter | - = note: associated `fn`s are those in `impl` or `trait` definitions + = note: associated functions are those in `impl` or `trait` definitions error[E0561]: patterns aren't allowed in function pointer types --> $DIR/self-param-semantic-fail.rs:62:14 diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index 56a2686945ca2..80a237ac6aad4 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -5,6 +5,10 @@ LL | fn foo(Option, String) {} | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn foo(self: Option, String) {} + | ^^^^^^^^^^^^ help: if this is a type, explicitly ignore the parameter name | LL | fn foo(_: Option, String) {} @@ -33,6 +37,10 @@ LL | fn bar(x, y: usize) {} | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn bar(self: x, y: usize) {} + | ^^^^^^^ help: if this was a parameter name, give it a type | LL | fn bar(x: TypeName, y: usize) {} diff --git a/src/test/ui/suggestions/issue-64252-self-type.stderr b/src/test/ui/suggestions/issue-64252-self-type.stderr index 4abffb1ad79f6..e96db3f1e8630 100644 --- a/src/test/ui/suggestions/issue-64252-self-type.stderr +++ b/src/test/ui/suggestions/issue-64252-self-type.stderr @@ -5,6 +5,10 @@ LL | pub fn foo(Box) { } | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | pub fn foo(self: Box) { } + | ^^^^^^^^^ help: if this is a type, explicitly ignore the parameter name | LL | pub fn foo(_: Box) { } From d154bef4d3f9ea178493024fd27612dcba3acc58 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 31 Jan 2020 07:24:23 +0100 Subject: [PATCH 0796/1253] parser: avoid re-wrapping NtItem --- src/librustc_parse/parser/item.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 7f15c403e9af9..82600c354e9f8 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -70,16 +70,15 @@ impl<'a> Parser<'a> { /// Parses one of the items allowed by the flags. fn parse_item_implementation( &mut self, - attrs: Vec, + mut attrs: Vec, macros_allowed: bool, attributes_allowed: bool, ) -> PResult<'a, Option>> { maybe_whole!(self, NtItem, |item| { - let mut item = item.into_inner(); - let mut attrs = attrs; + let mut item = item; mem::swap(&mut item.attrs, &mut attrs); item.attrs.extend(attrs); - Some(P(item)) + Some(item) }); let lo = self.token.span; From 7af9ff3e699207da7a5220b98ba9831d66697c80 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Jan 2020 02:14:51 +0100 Subject: [PATCH 0797/1253] introduce `#![feature(move_ref_pattern)]` --- src/librustc_errors/diagnostic_builder.rs | 16 +- src/librustc_feature/active.rs | 4 + .../hair/pattern/check_match.rs | 177 +++++++++++------- src/librustc_span/symbol.rs | 1 + 4 files changed, 125 insertions(+), 73 deletions(-) diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 3c217c1d64373..82bbae18a9c0b 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -186,11 +186,25 @@ impl<'a> DiagnosticBuilder<'a> { /// all, and you just supplied a `Span` to create the diagnostic, /// then the snippet will just include that `Span`, which is /// called the primary span. - pub fn span_label>(&mut self, span: Span, label: T) -> &mut Self { + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { self.0.diagnostic.span_label(span, label); self } + /// Labels all the given spans with the provided label. + /// See `span_label` for more information. + pub fn span_labels( + &mut self, + spans: impl IntoIterator, + label: impl AsRef, + ) -> &mut Self { + let label = label.as_ref(); + for span in spans { + self.0.diagnostic.span_label(span, label); + } + self + } + forward!(pub fn note_expected_found( &mut self, expected_label: &dyn fmt::Display, diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index f20a57ea61c42..e0abf5d4f3c1f 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -538,6 +538,10 @@ declare_features! ( /// For example, you can write `x @ Some(y)`. (active, bindings_after_at, "1.41.0", Some(65490), None), + /// Allows patterns with concurrent by-move and by-ref bindings. + /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref. + (active, move_ref_pattern, "1.42.0", Some(68354), None), + /// Allows `impl const Trait for T` syntax. (active, const_trait_impl, "1.42.0", Some(67792), None), diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 82822f0c471a4..a563864b61b31 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -16,8 +16,7 @@ use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME; use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS}; use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::symbol::sym; -use rustc_span::{MultiSpan, Span}; +use rustc_span::{sym, Span}; use syntax::ast::Mutability; use std::slice; @@ -114,8 +113,10 @@ impl PatCtxt<'_, '_> { impl<'tcx> MatchVisitor<'_, 'tcx> { fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) { - check_legality_of_move_bindings(self, has_guard, pat); - check_borrow_conflicts_in_at_patterns(self, pat); + if !self.tcx.features().move_ref_pattern { + check_legality_of_move_bindings(self, has_guard, pat); + } + pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat)); if !self.tcx.features().bindings_after_at { check_legality_of_bindings_in_at_patterns(self, pat); } @@ -559,6 +560,11 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec covered } +/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`. +fn is_binding_by_move(cx: &MatchVisitor<'_, '_>, hir_id: HirId, span: Span) -> bool { + !cx.tables.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env, span) +} + /// Check the legality of legality of by-move bindings. fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) { let sess = cx.tcx.sess; @@ -589,8 +595,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo pat.walk_always(|p| { if let hir::PatKind::Binding(.., sub) = &p.kind { if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) { - let pat_ty = tables.node_type(p.hir_id); - if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { + if is_binding_by_move(cx, p.hir_id, p.span) { check_move(p, sub.as_deref()); } } @@ -599,11 +604,11 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo // Found some bad by-move spans, error! if !by_move_spans.is_empty() { - let mut err = struct_span_err!( - sess, - MultiSpan::from_spans(by_move_spans.clone()), - E0009, - "cannot bind by-move and by-ref in the same pattern", + let mut err = feature_err( + &sess.parse_sess, + sym::move_ref_pattern, + by_move_spans.clone(), + "binding by-move and by-ref in the same pattern is unstable", ); for span in by_ref_spans.iter() { err.span_label(*span, "by-ref pattern here"); @@ -615,81 +620,109 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } } -/// Check that there are no borrow conflicts in `binding @ subpat` patterns. +/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns. /// /// For example, this would reject: /// - `ref x @ Some(ref mut y)`, -/// - `ref mut x @ Some(ref y)` -/// - `ref mut x @ Some(ref mut y)`. +/// - `ref mut x @ Some(ref y)`, +/// - `ref mut x @ Some(ref mut y)`, +/// - `ref mut? x @ Some(y)`, and +/// - `x @ Some(ref mut? y)`. /// /// This analysis is *not* subsumed by NLL. fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) { - let tab = cx.tables; - let sess = cx.tcx.sess; - // Get the mutability of `p` if it's by-ref. - let extract_binding_mut = |hir_id, span| match tab.extract_binding_mode(sess, hir_id, span)? { - ty::BindByValue(_) => None, - ty::BindByReference(m) => Some(m), + // Extract `sub` in `binding @ sub`. + let (name, sub) = match &pat.kind { + hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), + _ => return, }; - pat.walk_always(|pat| { - // Extract `sub` in `binding @ sub`. - let (name, sub) = match &pat.kind { - hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), - _ => return, - }; + let binding_span = pat.span.with_hi(name.span.hi()); - // Extract the mutability. - let mut_outer = match extract_binding_mut(pat.hir_id, pat.span) { - None => return, - Some(m) => m, - }; + let tables = cx.tables; + let sess = cx.tcx.sess; - // We now have `ref $mut_outer binding @ sub` (semantically). - // Recurse into each binding in `sub` and find mutability conflicts. - let mut conflicts_mut_mut = Vec::new(); - let mut conflicts_mut_ref = Vec::new(); - sub.each_binding(|_, hir_id, span, _| { - if let Some(mut_inner) = extract_binding_mut(hir_id, span) { - match (mut_outer, mut_inner) { - (Mutability::Not, Mutability::Not) => {} - (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), - _ => conflicts_mut_ref.push(span), + // Get the binding move, extract the mutability if by-ref. + let mut_outer = match tables.extract_binding_mode(sess, pat.hir_id, pat.span) { + Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => { + // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`. + let mut conflicts_ref = Vec::new(); + sub.each_binding(|_, hir_id, span, _| { + match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + sess.delay_span_bug(span, "by-move in subpat unchecked by borrowck"); + } + Some(ty::BindByValue(_)) | None => {} + Some(ty::BindByReference(_)) => conflicts_ref.push(span), } + }); + if !conflicts_ref.is_empty() { + let occurs_because = format!( + "move occurs because `{}` has type `{}` which does implement the `Copy` trait", + name, + tables.node_type(pat.hir_id), + ); + sess.struct_span_err(pat.span, &format!("borrow of moved value: `{}`", name)) + .span_label(binding_span, "value moved here") + .span_label(binding_span, occurs_because) + .span_labels(conflicts_ref, "value borrowed here after move") + .emit(); } - }); + return; + } + Some(ty::BindByValue(_)) | None => return, + Some(ty::BindByReference(m)) => m, + }; - // Report errors if any. - let binding_span = pat.span.with_hi(name.span.hi()); - if !conflicts_mut_mut.is_empty() { - // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); - let mut err = sess.struct_span_err(pat.span, msg); - err.span_label(binding_span, "first mutable borrow occurs here"); - for sp in conflicts_mut_mut { - err.span_label(sp, "another mutable borrow occurs here"); - } - for sp in conflicts_mut_ref { - err.span_label(sp, "also borrowed as immutable here"); - } - err.emit(); - } else if !conflicts_mut_ref.is_empty() { - // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. - let (primary, also) = match mut_outer { - Mutability::Mut => ("mutable", "immutable"), - Mutability::Not => ("immutable", "mutable"), - }; - let msg = &format!( - "cannot borrow `{}` as {} because it is also borrowed as {}", - name, also, primary, - ); - let mut err = sess.struct_span_err(pat.span, msg); - err.span_label(binding_span, &format!("{} borrow occurs here", primary)); - for sp in conflicts_mut_ref { - err.span_label(sp, &format!("{} borrow occurs here", also)); - } - err.emit(); + // We now have `ref $mut_outer binding @ sub` (semantically). + // Recurse into each binding in `sub` and find mutability or move conflicts. + let mut conflicts_move = Vec::new(); + let mut conflicts_mut_mut = Vec::new(); + let mut conflicts_mut_ref = Vec::new(); + sub.each_binding(|_, hir_id, span, _| match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { + (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. + (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), // 2x `ref mut`. + _ => conflicts_mut_ref.push(span), // `ref` + `ref mut` in either direction. + }, + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + conflicts_move.push(span) // `ref mut?` + by-move conflict. } + Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. }); + + // Report errors if any. + if !conflicts_mut_mut.is_empty() { + // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. + let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, "first mutable borrow occurs here") + .span_labels(conflicts_mut_mut, "another mutable borrow occurs here") + .span_labels(conflicts_mut_ref, "also borrowed as immutable here") + .span_labels(conflicts_move, "also moved here") + .emit(); + } else if !conflicts_mut_ref.is_empty() { + // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. + let (primary, also) = match mut_outer { + Mutability::Mut => ("mutable", "immutable"), + Mutability::Not => ("immutable", "mutable"), + }; + let msg = &format!( + "cannot borrow `{}` as {} because it is also borrowed as {}", + name, also, primary, + ); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, format!("{} borrow occurs here", primary)) + .span_labels(conflicts_mut_ref, format!("{} borrow occurs here", also)) + .span_labels(conflicts_move, "also moved here") + .emit(); + } else if !conflicts_move.is_empty() { + // Report by-ref and by-move conflicts, e.g. `ref x @ y`. + let msg = &format!("cannot move out of `{}` because it is borrowed", name); + sess.struct_span_err(pat.span, msg) + .span_label(binding_span, format!("borrow of `{}` occurs here", name)) + .span_labels(conflicts_move, format!("move out of `{}` occurs here", name)) + .emit(); + } } /// Forbids bindings in `@` patterns. This used to be is necessary for memory safety, diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index e4f8b5a014389..a8cd027831d31 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -455,6 +455,7 @@ symbols! { module, module_path, more_struct_aliases, + move_ref_pattern, move_val_init, movbe_target_feature, mul_with_overflow, From d984f127f662f7a1fcf0472230a1b64fcc3325d5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 19 Jan 2020 02:47:01 +0100 Subject: [PATCH 0798/1253] move_ref_patterns: introduce tests bindings_after_at: harden tests --- ...her-can-live-while-the-other-survives-2.rs | 15 - ...can-live-while-the-other-survives-2.stderr | 11 - ...her-can-live-while-the-other-survives-3.rs | 18 - ...can-live-while-the-other-survives-3.stderr | 11 - ...her-can-live-while-the-other-survives-4.rs | 15 - ...can-live-while-the-other-survives-4.stderr | 11 - src/test/ui/drop/dynamic-drop-async.rs | 10 + src/test/ui/drop/dynamic-drop.rs | 8 + src/test/ui/error-codes/E0009.rs | 9 - src/test/ui/error-codes/E0009.stderr | 11 - src/test/ui/issues/issue-53840.stderr | 20 - src/test/ui/moves/move-out-of-slice-2.rs | 2 +- ...her-can-live-while-the-other-survives-1.rs | 23 +- ...can-live-while-the-other-survives-1.stderr | 59 +- .../bind-by-move-no-subbindings-fun-param.rs | 4 +- ...nd-by-move-no-subbindings-fun-param.stderr | 13 +- .../borrowck-move-and-move.rs | 36 +- .../borrowck-move-and-move.stderr | 69 +-- .../borrowck-pat-at-and-box-pass.rs | 11 + .../borrowck-pat-at-and-box.rs | 41 +- .../borrowck-pat-at-and-box.stderr | 109 ++-- ...k-pat-by-move-and-ref-inverse-promotion.rs | 10 + ...t-by-move-and-ref-inverse-promotion.stderr | 12 + .../borrowck-pat-by-move-and-ref-inverse.rs | 98 ++++ ...orrowck-pat-by-move-and-ref-inverse.stderr | 503 ++++++++++++++++++ .../borrowck-pat-by-move-and-ref.rs | 73 ++- .../borrowck-pat-by-move-and-ref.stderr | 243 ++++++++- .../borrowck-pat-ref-mut-and-ref.rs | 4 + .../borrowck-pat-ref-mut-and-ref.stderr | 111 ++-- .../borrowck-pat-ref-mut-twice.rs | 12 +- .../borrowck-pat-ref-mut-twice.stderr | 125 +++-- .../bindings-after-at/copy-and-move-mixed.rs | 8 +- .../copy-and-move-mixed.stderr | 25 +- ...lt-binding-modes-both-sides-independent.rs | 25 +- ...inding-modes-both-sides-independent.stderr | 74 ++- .../borrowck-move-ref-pattern-pass.rs | 31 ++ .../borrowck-move-ref-pattern.rs | 50 ++ .../borrowck-move-ref-pattern.stderr | 208 ++++++++ .../feature-gate-move_ref_pattern.rs | 23 + .../feature-gate-move_ref_pattern.stderr | 66 +++ .../move-ref-patterns}/issue-53840.rs | 8 +- ...move-ref-patterns-closure-captures-pass.rs | 30 ++ .../move-ref-patterns-closure-captures.rs | 34 ++ .../move-ref-patterns-closure-captures.stderr | 39 ++ ...move-ref-patterns-default-binding-modes.rs | 16 + ...-ref-patterns-default-binding-modes.stderr | 21 + .../move-ref-patterns-dynamic-semantics.rs | 81 +++ .../pattern/rest-pat-semantic-disallowed.rs | 2 +- .../ui/rfc-2005-default-binding-mode/for.rs | 7 +- .../rfc-2005-default-binding-mode/for.stderr | 15 +- 50 files changed, 1919 insertions(+), 541 deletions(-) delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs delete mode 100644 src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr delete mode 100644 src/test/ui/error-codes/E0009.rs delete mode 100644 src/test/ui/error-codes/E0009.stderr delete mode 100644 src/test/ui/issues/issue-53840.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs create mode 100644 src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr rename src/test/ui/{issues => pattern/move-ref-patterns}/issue-53840.rs (64%) create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs deleted file mode 100644 index 238f2d958c625..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -struct X { x: (), } - -impl Drop for X { - fn drop(&mut self) { - println!("destructor runs"); - } -} - -fn main() { - let x = Some((X { x: () }, X { x: () })); - match x { - Some((ref _y, _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr deleted file mode 100644 index ff00aa8caa8d3..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-2.rs:12:23 - | -LL | Some((ref _y, _z)) => { }, - | ------ ^^ by-move pattern here - | | - | by-ref pattern here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs deleted file mode 100644 index e8357e9178819..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct X { x: (), } - -impl Drop for X { - fn drop(&mut self) { - println!("destructor runs"); - } -} - -enum DoubleOption { Some2(T,U), None2 } - -fn main() { - let x = DoubleOption::Some2(X { x: () }, X { x: () }); - match x { - DoubleOption::Some2(ref _y, _z) => { }, - //~^ ERROR cannot bind by-move and by-ref in the same pattern - DoubleOption::None2 => panic!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr deleted file mode 100644 index 3e8358da3507d..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-3.rs:14:37 - | -LL | DoubleOption::Some2(ref _y, _z) => { }, - | ------ ^^ by-move pattern here - | | - | by-ref pattern here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs deleted file mode 100644 index 41dafd2b5bf72..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs +++ /dev/null @@ -1,15 +0,0 @@ -struct X { x: (), } - -impl Drop for X { - fn drop(&mut self) { - println!("destructor runs"); - } -} - -fn main() { - let x = Some((X { x: () }, X { x: () })); - match x { - Some((_y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() - } -} diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr deleted file mode 100644 index 00e0c70d6494b..0000000000000 --- a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-4.rs:12:15 - | -LL | Some((_y, ref _z)) => { }, - | ^^ ------ by-ref pattern here - | | - | by-move pattern here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 30a8960594493..88d36ab6aa664 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -7,6 +7,8 @@ // edition:2018 // ignore-wasm32-bare compiled with panic=abort by default +#![feature(move_ref_pattern)] + #![allow(unused)] use std::{ @@ -227,6 +229,12 @@ async fn subslice_pattern_reassign(a: Rc) { a.alloc().await; } +async fn move_ref_pattern(a: Rc) { + let mut tup = (a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await); + let (ref _a, ref mut _b, _c, mut _d) = tup; + a.alloc().await; +} + fn run_test(cx: &mut Context<'_>, ref f: F) where F: Fn(Rc) -> G, @@ -322,4 +330,6 @@ fn main() { run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true)); run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false)); run_test(context, |a| subslice_pattern_reassign(a)); + + run_test(context, |a| move_ref_pattern(a)); } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index b4406204a5db9..208a743ed1815 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -2,6 +2,7 @@ // ignore-wasm32-bare compiled with panic=abort by default #![feature(generators, generator_trait, untagged_unions)] +#![feature(move_ref_pattern)] #![allow(unused_assignments)] #![allow(unused_variables)] @@ -290,6 +291,11 @@ fn subslice_mixed_min_lengths(a: &Allocator, c: i32) { } } +fn move_ref_pattern(a: &Allocator) { + let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc()); + let (ref _a, ref mut _b, _c, mut _d) = tup; +} + fn panic_after_return(a: &Allocator) -> Ptr<'_> { // Panic in the drop of `p` or `q` can leak let exceptions = vec![8, 9]; @@ -453,6 +459,8 @@ fn main() { run_test(|a| subslice_mixed_min_lengths(a, 6)); run_test(|a| subslice_mixed_min_lengths(a, 7)); + run_test(|a| move_ref_pattern(a)); + run_test(|a| { panic_after_return(a); }); diff --git a/src/test/ui/error-codes/E0009.rs b/src/test/ui/error-codes/E0009.rs deleted file mode 100644 index 0610d03cfe96d..0000000000000 --- a/src/test/ui/error-codes/E0009.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - struct X { x: (), } - let x = Some((X { x: () }, X { x: () })); - match x { - Some((y, ref z)) => {}, - //~^ ERROR E0009 - None => panic!() - } -} diff --git a/src/test/ui/error-codes/E0009.stderr b/src/test/ui/error-codes/E0009.stderr deleted file mode 100644 index 446a436d64779..0000000000000 --- a/src/test/ui/error-codes/E0009.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/E0009.rs:5:15 - | -LL | Some((y, ref z)) => {}, - | ^ ----- by-ref pattern here - | | - | by-move pattern here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/issues/issue-53840.stderr b/src/test/ui/issues/issue-53840.stderr deleted file mode 100644 index 9cb034e7592da..0000000000000 --- a/src/test/ui/issues/issue-53840.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/issue-53840.rs:13:16 - | -LL | E::Foo(a, b, ref c) => {} - | ^ ^ ----- by-ref pattern here - | | | - | | by-move pattern here - | by-move pattern here - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/issue-53840.rs:17:14 - | -LL | Bar {a, ref b} => {} - | ^ ----- by-ref pattern here - | | - | by-move pattern here - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/moves/move-out-of-slice-2.rs b/src/test/ui/moves/move-out-of-slice-2.rs index e460246193e5b..5c1a61eb375a4 100644 --- a/src/test/ui/moves/move-out-of-slice-2.rs +++ b/src/test/ui/moves/move-out-of-slice-2.rs @@ -1,4 +1,4 @@ -#![feature(slice_patterns, unsized_locals)] +#![feature(unsized_locals)] struct A; #[derive(Clone, Copy)] diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 75d7af58e706d..1cad822382677 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -3,33 +3,38 @@ // where one side is by-ref and the other is by-move. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] -struct X { x: () } +struct X { + x: (), +} fn main() { let x = Some(X { x: () }); match x { - Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + None => panic!(), } let x = Some(X { x: () }); match x { - Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(ref mut _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(_z @ ref mut _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref mut _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 22d62ff4f003f..6ad0248fc6b2f 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -1,37 +1,45 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23 +error: cannot move out of `_y` because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14 | -LL | Some(ref _y @ _z) => { }, - | ---------^^ +LL | Some(ref _y @ _z) => {} + | ------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `_y` occurs here + | borrow of `_y` occurs here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14 +error: borrow of moved value: `_z` + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14 | -LL | Some(_z @ ref _y) => { }, - | ^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref _y) => {} + | --^^^------ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `_z` has type `X` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27 +error: cannot move out of `_y` because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14 | -LL | Some(ref mut _y @ _z) => { }, - | -------------^^ +LL | Some(ref mut _y @ _z) => {} + | ----------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `_y` occurs here + | borrow of `_y` occurs here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14 +error: borrow of moved value: `_z` + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14 | -LL | Some(_z @ ref mut _y) => { }, - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref mut _y) => {} + | --^^^---------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `_z` has type `X` which does implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:19 | -LL | Some(_z @ ref _y) => { }, +LL | Some(_z @ ref _y) => {} | -----^^^^^^ | | | | | value borrowed here after move @@ -40,9 +48,9 @@ LL | Some(_z @ ref _y) => { }, = note: move occurs because value has type `X`, which does not implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:19 | -LL | Some(_z @ ref mut _y) => { }, +LL | Some(_z @ ref mut _y) => {} | -----^^^^^^^^^^ | | | | | value borrowed here after move @@ -52,5 +60,4 @@ LL | Some(_z @ ref mut _y) => { }, error: aborting due to 6 previous errors -Some errors have detailed explanations: E0007, E0009, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs index 86fb04e2edf5b..7a2e5128b8537 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs @@ -1,14 +1,14 @@ // See issue #12534. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() {} struct A(Box); fn f(a @ A(u): A) -> Box { - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value drop(a); u } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr index b039708fd3e0a..cfd978e132709 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr @@ -1,11 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:6 - | -LL | fn f(a @ A(u): A) -> Box { - | ^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12 + --> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:12 | LL | fn f(a @ A(u): A) -> Box { | ------^- @@ -14,7 +8,6 @@ LL | fn f(a @ A(u): A) -> Box { | value moved here | move occurs because value has type `A`, which does not implement the `Copy` trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs index 2cd375da9a56f..10865b92393b6 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -1,46 +1,34 @@ // Test that moving on both sides of an `@` pattern is not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; // Not copy! // Prevent promotion: - fn u() -> U { U } + fn u() -> U { + U + } - let a @ b = U; - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ b = U; //~ ERROR use of moved value - let a @ (b, c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (U, U); //~ ERROR use of moved value - let a @ (b, c) = (u(), u()); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (u(), u()); //~ ERROR use of moved value match Ok(U) { - a @ Ok(b) | a @ Err(b) => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value + //~^ ERROR use of moved value } - fn fun(a @ b: U) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + fn fun(a @ b: U) {} //~ ERROR use of moved value match [u(), u(), u(), u()] { - xs @ [a, .., b] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [a, .., b] => {} //~ ERROR use of moved value } match [u(), u(), u(), u()] { - xs @ [_, ys @ .., _] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index 12ebcb72af11c..56613ee7618b4 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -1,53 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:11:9 - | -LL | let a @ b = U; - | ^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:15:9 - | -LL | let a @ (b, c) = (U, U); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:19:9 - | -LL | let a @ (b, c) = (u(), u()); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:9 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:21 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:36:9 - | -LL | xs @ [a, .., b] => {} - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:42:9 - | -LL | xs @ [_, ys @ .., _] => {} - | ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:31:12 - | -LL | fn fun(a @ b: U) {} - | ^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:11:13 + --> $DIR/borrowck-move-and-move.rs:14:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -56,7 +8,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:15:17 + --> $DIR/borrowck-move-and-move.rs:16:17 | LL | let a @ (b, c) = (U, U); | --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -65,7 +17,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:19:17 + --> $DIR/borrowck-move-and-move.rs:18:17 | LL | let a @ (b, c) = (u(), u()); | --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -74,7 +26,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:16 + --> $DIR/borrowck-move-and-move.rs:21:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -85,7 +37,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:29 + --> $DIR/borrowck-move-and-move.rs:21:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -96,7 +48,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:36:22 + --> $DIR/borrowck-move-and-move.rs:28:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -107,7 +59,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:42:18 + --> $DIR/borrowck-move-and-move.rs:32:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -118,7 +70,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:31:16 + --> $DIR/borrowck-move-and-move.rs:25:16 | LL | fn fun(a @ b: U) {} | ----^ @@ -127,7 +79,6 @@ LL | fn fun(a @ b: U) {} | value moved here | move occurs because value has type `main::U`, which does not implement the `Copy` trait -error: aborting due to 16 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index 092bd1133dd62..271f4bca0fcb8 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -3,6 +3,7 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] @@ -72,4 +73,14 @@ fn main() { } _ => {} } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(b)] => {} + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} + _ => {} + } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index 3b2f598dc0157..e90aeab2edb0b 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -1,39 +1,40 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] struct C; -fn c() -> C { C } +fn c() -> C { + C +} struct NC; -fn nc() -> NC { NC } +fn nc() -> NC { + NC +} fn main() { let a @ box &b = Box::new(&C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ box b = Box::new(C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f1(a @ box &b: Box<&C>) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f2(a @ box b: Box) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value - match Box::new(C) { a @ box b => {} } - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + match Box::new(C) { + a @ box b => {} //~ ERROR use of moved value + } - let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of `a` because it is borrowed let ref a @ box ref mut b = Box::new(nc()); //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable @@ -69,16 +70,4 @@ fn main() { drop(b); } } - - match Box::new([Ok(c()), Err(nc()), Ok(c())]) { - box [Ok(a), ref xs @ .., Err(b)] => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern - _ => {} - } - - match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { - [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern - _ => {} - } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index e96c15b0fa7dd..50185c1a017d3 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,32 +1,14 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:16:9 - | -LL | let a @ box &b = Box::new(&C); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:20:9 - | -LL | let a @ box b = Box::new(C); - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:32:25 - | -LL | match Box::new(C) { a @ box b => {} } - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:36:21 +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-at-and-box.rs:37:9 | LL | let ref a @ box b = Box::new(NC); - | ------------^ + | -----^^^^^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:38:9 + --> $DIR/borrowck-pat-at-and-box.rs:39:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -35,7 +17,7 @@ LL | let ref a @ box ref mut b = Box::new(nc()); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:40:9 + --> $DIR/borrowck-pat-at-and-box.rs:41:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -44,7 +26,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:42:9 + --> $DIR/borrowck-pat-at-and-box.rs:43:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -53,7 +35,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:45:9 + --> $DIR/borrowck-pat-at-and-box.rs:46:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -62,7 +44,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:51:9 + --> $DIR/borrowck-pat-at-and-box.rs:52:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -71,7 +53,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:65:9 + --> $DIR/borrowck-pat-at-and-box.rs:66:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- @@ -79,38 +61,8 @@ LL | ref mut a @ box ref b => { | | immutable borrow occurs here | mutable borrow occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:74:38 - | -LL | box [Ok(a), ref xs @ .., Err(b)] => {} - | ----------- ^ by-move pattern here - | | - | by-ref pattern here - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:80:46 - | -LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} - | ----- ----------- ^ --------- by-ref pattern here - | | | | - | | | by-move pattern here - | | by-ref pattern here - | by-ref pattern here - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:24:11 - | -LL | fn f1(a @ box &b: Box<&C>) {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:28:11 - | -LL | fn f2(a @ box b: Box) {} - | ^^^^^^^^^ binds an already bound by-move value by moving it - error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:57:11 + --> $DIR/borrowck-pat-at-and-box.rs:58:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -119,7 +71,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { | mutable borrow occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:16:18 + --> $DIR/borrowck-pat-at-and-box.rs:21:18 | LL | let a @ box &b = Box::new(&C); | ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait @@ -128,7 +80,7 @@ LL | let a @ box &b = Box::new(&C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:20:17 + --> $DIR/borrowck-pat-at-and-box.rs:24:17 | LL | let a @ box b = Box::new(C); | --------^ ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -137,17 +89,18 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:32:33 + --> $DIR/borrowck-pat-at-and-box.rs:34:17 | -LL | match Box::new(C) { a @ box b => {} } - | ----------- --------^ - | | | | - | | | value used here after move - | | value moved here - | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | match Box::new(C) { + | ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | a @ box b => {} + | --------^ + | | | + | | value used here after move + | value moved here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:45:21 + --> $DIR/borrowck-pat-at-and-box.rs:46:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -159,7 +112,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:51:25 + --> $DIR/borrowck-pat-at-and-box.rs:52:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -171,7 +124,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:65:25 + --> $DIR/borrowck-pat-at-and-box.rs:66:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -183,7 +136,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:24:20 + --> $DIR/borrowck-pat-at-and-box.rs:27:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -193,7 +146,7 @@ LL | fn f1(a @ box &b: Box<&C>) {} | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:28:19 + --> $DIR/borrowck-pat-at-and-box.rs:30:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -203,7 +156,7 @@ LL | fn f2(a @ box b: Box) {} | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:57:27 + --> $DIR/borrowck-pat-at-and-box.rs:58:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ @@ -214,7 +167,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { LL | *a = Box::new(NC); | -- mutable borrow later used here -error: aborting due to 24 previous errors +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0007, E0009, E0382, E0502. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs new file mode 100644 index 0000000000000..1479791719313 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs @@ -0,0 +1,10 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented even with promotion. +// Currently this logic exists in HAIR match checking as opposed to borrowck. + +#![feature(bindings_after_at)] +#![feature(move_ref_pattern)] + +fn main() { + struct U; + let a @ ref b = U; //~ ERROR borrow of moved value +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr new file mode 100644 index 0000000000000..dc9201d0d061f --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -0,0 +1,12 @@ +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:9:9 + | +LL | let a @ ref b = U; + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs new file mode 100644 index 0000000000000..7d9618c8df78d --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs @@ -0,0 +1,98 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented. + +#![feature(bindings_after_at)] +#![feature(move_ref_pattern)] + +fn main() { + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(a @ ref b: U) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + let a @ ref b = U; + //~^ ERROR borrow of moved value + let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + let a @ [ref mut b, ref c] = [U, U]; + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + let a @ ref b = u(); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + let a @ [ref mut b, ref c] = [u(), u()]; + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + match Some(U) { + a @ Some(ref b) => {} + //~^ ERROR borrow of moved value + None => {} + } + match Some((U, U)) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + None => {} + } + match Some([U, U]) { + mut a @ Some([ref b, ref mut c]) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } + match Some(u()) { + a @ Some(ref b) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } + match Some((u(), u())) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + None => {} + } + match Some([u(), u()]) { + mut a @ Some([ref b, ref mut c]) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr new file mode 100644 index 0000000000000..0c502cee7f6c9 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -0,0 +1,503 @@ +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9 + | +LL | let a @ ref b = U; + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -^^^^^^^^^^^^---------^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:14 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9 + | +LL | let a @ [ref mut b, ref c] = [U, U]; + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9 + | +LL | let a @ ref b = u(); + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -^^^^^^^^^^^^---------^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:14 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:9 + | +LL | let a @ [ref mut b, ref c] = [u(), u()]; + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:19 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:9 + | +LL | mut a @ Some([ref b, ref mut c]) => {} + | -----^^^^^^^^^-----^^---------^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:9 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:19 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:9 + | +LL | mut a @ Some([ref b, ref mut c]) => {} + | -----^^^^^^^^^-----^^---------^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 + | +LL | fn f1(a @ ref b: U) {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:11 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -----^^^^^^^^-----^^^^^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value: `b` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:20 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `d` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -----^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:11 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:22 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | ------------------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:37 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:25 + | +LL | let a @ [ref mut b, ref c] = [U, U]; + | ----------------^^^^^- ------ move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:13 + | +LL | let a @ ref b = u(); + | ----^^^^^ --- move occurs because value has type `main::U`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:22 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | ------------------------^^^^^^^^^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:37 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:25 + | +LL | let a @ [ref mut b, ref c] = [u(), u()]; + | ----------------^^^^^- ---------- move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:27 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 + | +LL | match Some((U, U)) { + | ------------ move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----------------------------^^^^^^^^^-- + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:42 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:30 + | +LL | match Some([U, U]) { + | ------------ move occurs because value has type `std::option::Option<[main::U; 2]>`, which does not implement the `Copy` trait +LL | mut a @ Some([ref b, ref mut c]) => {} + | ---------------------^^^^^^^^^-- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:18 + | +LL | match Some(u()) { + | --------- move occurs because value has type `std::option::Option`, which does not implement the `Copy` trait +LL | a @ Some(ref b) => {} + | ---------^^^^^- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:27 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 + | +LL | match Some((u(), u())) { + | ---------------- move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----------------------------^^^^^^^^^-- + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:42 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:30 + | +LL | match Some([u(), u()]) { + | ---------------- move occurs because value has type `std::option::Option<[main::U; 2]>`, which does not implement the `Copy` trait +LL | mut a @ Some([ref b, ref mut c]) => {} + | ---------------------^^^^^^^^^-- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:15 + | +LL | fn f1(a @ ref b: U) {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:24 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | --------------------^^^^^^^^^^^^^- + | | | + | | value used here after move + | value moved here + | move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:39 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | --------^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:27 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | ----------------^^^^^- + | | | + | | value borrowed here after move + | value moved here + | move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + +error: aborting due to 48 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs index abe5ed81b71a2..4ece55b07b080 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -1,9 +1,74 @@ +// Test that `ref mut? @ pat_with_by_move_bindings` is prevented. + #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { - match Some("hi".to_string()) { - ref op_string_ref @ Some(s) => {}, - //~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009] - None => {}, + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(ref a @ b: U) {} + //~^ ERROR cannot move out of `a` because it is borrowed + fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + //~^ ERROR cannot move out of `a` because it is borrowed + + let ref a @ b = U; + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + let ref mut a @ [b, mut c] = [U, U]; + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ b = u(); + //~^ ERROR cannot move out of `a` because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + let ref mut a @ [b, mut c] = [u(), u()]; + //~^ ERROR cannot move out of `a` because it is borrowed + + match Some(U) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some((U, U)) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + None => {} + } + match Some([U, U]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some(u()) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} + } + match Some((u(), u())) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR cannot move out of `b` because it is borrowed + //~| ERROR cannot move out of `d` because it is borrowed + None => {} + } + match Some([u(), u()]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of `a` because it is borrowed + None => {} } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 1f70a6c437e92..607bbd5f991c0 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -1,12 +1,237 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-by-move-and-ref.rs:5:34 +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9 | -LL | ref op_string_ref @ Some(s) => {}, - | -------------------------^- - | | | - | | by-move pattern here - | by-ref pattern here +LL | let ref a @ b = U; + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here -error: aborting due to previous error +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:9 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:18 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:33 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:29:9 + | +LL | let ref mut a @ [b, mut c] = [U, U]; + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:31:9 + | +LL | let ref a @ b = u(); + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:9 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:18 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:33 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:37:9 + | +LL | let ref mut a @ [b, mut c] = [u(), u()]; + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:41:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:9 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:23 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:38 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:53:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:58:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:9 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:23 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:38 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:70:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f1(ref a @ b: U) {} + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:11 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:20 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^----- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + +error: cannot move out of `d` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:35 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^- + | | | + | | move out of `d` occurs here + | borrow of `d` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 + | +LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + | ---------^^^^-^^-----^ + | | | | + | | | move out of `a` occurs here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: aborting due to 25 previous errors -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index e8510dfa64999..a921ad056d81f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -1,4 +1,5 @@ #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] enum Option { None, @@ -27,6 +28,9 @@ fn main() { //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + fn f4_also_moved(ref a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~| ERROR cannot move out of `b` because it is borrowed let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub //~^ ERROR cannot borrow `a` as mutable more than once at a time diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 0d7b703f1816b..4652fffe36a42 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,5 +1,5 @@ error: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ @@ -8,7 +8,7 @@ LL | ref mut z @ &mut Some(ref a) => { | mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ @@ -18,7 +18,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | first mutable borrow occurs here error: cannot borrow `b` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- @@ -27,7 +27,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -36,7 +36,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -45,7 +45,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -55,7 +55,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -65,7 +65,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -74,7 +74,7 @@ LL | let ref mut a @ ref b = u(); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -83,7 +83,7 @@ LL | let ref a @ ref mut b = u(); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -92,7 +92,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -101,7 +101,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -110,7 +110,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -119,7 +119,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -128,7 +128,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -137,7 +137,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -146,7 +146,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -155,7 +155,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -164,7 +164,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -173,7 +173,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ @@ -182,7 +182,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ @@ -191,7 +191,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -200,7 +200,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -209,7 +209,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -219,7 +219,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -229,7 +229,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -239,7 +239,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -249,7 +249,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- @@ -258,7 +258,7 @@ LL | fn f1(ref a @ ref mut b: U) {} | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- @@ -267,7 +267,7 @@ LL | fn f2(ref mut a @ ref b: U) {} | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ @@ -275,8 +275,27 @@ LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | | mutable borrow occurs here | immutable borrow occurs here +error: cannot borrow `a` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | -----^^^------------- + | | | | + | | | also moved here + | | mutable borrow occurs here + | immutable borrow occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:30 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ---------^^^- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -288,7 +307,7 @@ LL | **z = None; | ---------- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -300,7 +319,7 @@ LL | *a = u(); | -------- mutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -312,7 +331,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -324,7 +343,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -336,7 +355,7 @@ LL | drop(a); | - immutable borrow later used here error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -344,7 +363,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } = note: variables bound in patterns are immutable until the end of the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -352,7 +371,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa = note: variables bound in patterns are immutable until the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -360,7 +379,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -368,7 +387,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -376,7 +395,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -384,7 +403,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -396,7 +415,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -408,7 +427,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -420,7 +439,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -431,7 +450,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | drop(a); | - immutable borrow later used here -error: aborting due to 45 previous errors +error: aborting due to 47 previous errors Some errors have detailed explanations: E0502, E0507, E0594. For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index f425b35630d17..77cd779d7167f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -1,6 +1,7 @@ // Test that `ref mut x @ ref mut y` and varieties of that are not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; @@ -20,6 +21,9 @@ fn main() { [..], ] : [[U; 4]; 5] ) {} + fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~| ERROR cannot move out of `b` because it is borrowed let ref mut a @ ref mut b = U; //~^ ERROR cannot borrow `a` as mutable more than once at a time @@ -60,18 +64,18 @@ fn main() { ) = (u(), [u(), u(), u()]); let a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let mut val = (U, [U, U]); let a @ (b, [c, d]) = &mut val; // Same as ^-- - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut ref mut b = &mut U; - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value match Ok(U) { diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index d07ad140cc23a..a6d6678736475 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,5 +1,5 @@ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -8,7 +8,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -17,7 +17,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -26,7 +26,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -35,7 +35,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -44,7 +44,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9 | LL | let ref mut a @ ( | ^-------- @@ -66,7 +66,7 @@ LL | | ) = (U, [U, U, U]); | |_____^ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9 | LL | let ref mut a @ ( | ^-------- @@ -87,32 +87,52 @@ LL | | ] LL | | ) = (u(), [u(), u(), u()]); | |_________^ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^---------^^---------^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^-^^^-^^-^^ + | | | | | + | | | | value borrowed here after move + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 | LL | let a @ &mut ref mut b = &mut U; - | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^--------- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 +error: borrow of moved value: `a` + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^^---------^^---------^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved here + | move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -121,7 +141,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -130,7 +150,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -139,7 +159,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -148,7 +168,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -157,7 +177,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -166,7 +186,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -175,7 +195,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -184,7 +204,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -193,7 +213,7 @@ LL | fn f1(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -202,7 +222,7 @@ LL | fn f2(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 | LL | ref mut a @ [ | ^-------- @@ -219,8 +239,27 @@ LL | | [..], LL | | ] : [[U; 4]; 5] | |_________^ +error: cannot borrow `a` as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:22 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ---------^^^------------- + | | | | + | | | also moved here + | | another mutable borrow occurs here + | first mutable borrow occurs here + +error: cannot move out of `b` because it is borrowed + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:34 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ---------^^^- + | | | + | | move out of `b` occurs here + | borrow of `b` occurs here + error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -232,7 +271,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -244,7 +283,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:25 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -253,7 +292,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:21 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait @@ -262,7 +301,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:18 | LL | let a @ &mut ref mut b = &mut U; | ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait @@ -271,7 +310,7 @@ LL | let a @ &mut ref mut b = &mut U; | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:30 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait @@ -280,7 +319,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | value moved here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -292,7 +331,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -304,7 +343,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -316,7 +355,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -327,7 +366,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here -error: aborting due to 32 previous errors +error: aborting due to 34 previous errors -Some errors have detailed explanations: E0007, E0382, E0499. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0499. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs index db5aabc7a1453..821d4b42962bf 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs @@ -1,6 +1,7 @@ // Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #[derive(Copy, Clone)] struct C; @@ -9,12 +10,9 @@ struct NC(A, B); fn main() { let a @ NC(b, c) = NC(C, C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings + //~^ ERROR use of moved value //~| ERROR use of moved value } diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr index cfc35d6c32a72..7e89008a60496 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr @@ -1,23 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:11:9 - | -LL | let a @ NC(b, c) = NC(C, C); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:9 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:19 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/copy-and-move-mixed.rs:11:19 + --> $DIR/copy-and-move-mixed.rs:12:19 | LL | let a @ NC(b, c) = NC(C, C); | ----------^- -------- move occurs because value has type `NC`, which does not implement the `Copy` trait @@ -45,7 +27,6 @@ LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); | = note: move occurs because value has type `NC`, which does not implement the `Copy` trait -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs index 1127d114145cd..94becb9e8b8e3 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -8,6 +8,7 @@ // this would create problems for the generalization aforementioned. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct NotCopy; @@ -24,14 +25,26 @@ fn main() { let ref a @ b = &NotCopy; // OK let _: &&NotCopy = a; - let ref a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern - let ref mut a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + let ref mut a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of `_` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; match Ok(NotCopy) { - Ok(ref a @ b) | Err(ref a @ b) => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + Ok(ref a @ b) | Err(b @ ref a) => { + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR borrow of moved value: `b` + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } match NotCopy { - ref a @ b => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + ref a @ b => { + //~^ ERROR cannot move out of `a` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } } diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index b6709a8a40e23..dfc6e16600e2a 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -1,41 +1,61 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:27:17 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:28:9 | LL | let ref a @ b = NotCopy; - | --------^ + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:28:21 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:31:9 | LL | let ref mut a @ b = NotCopy; - | ------------^ + | ---------^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:36:12 + | +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -----^^^- + | | | + | | move out of `a` occurs here + | borrow of `a` occurs here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:30:20 +error: borrow of moved value: `b` + --> $DIR/default-binding-modes-both-sides-independent.rs:36:29 | -LL | Ok(ref a @ b) | Err(ref a @ b) => {} - | --------^ --------^ - | | | | | - | | | | by-move pattern here - | | | by-ref pattern here - | | by-move pattern here - | by-ref pattern here +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -^^^----- + | | | + | | value borrowed here after move + | value moved here + | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:34:17 +error: cannot move out of `a` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:44:9 | -LL | ref a @ b => {} - | --------^ +LL | ref a @ b => { + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | move out of `a` occurs here + | borrow of `a` occurs here + +error[E0505]: cannot move out of `_` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:31:21 + | +LL | let ref mut a @ b = NotCopy; + | ------------^ + | | | + | | move out of value occurs here + | borrow of value occurs here +LL | +LL | let _a: &NotCopy = a; + | - borrow later used here -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0009`. +For more information about this error, try `rustc --explain E0505`. diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs new file mode 100644 index 0000000000000..d2d4e61e049b2 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -0,0 +1,31 @@ +// check-pass + +#![feature(move_ref_pattern)] + +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U, U, U, U]; + let [ref _x0, _x1, _, mut _x3, .., ref _x6, _x7] = arr; + _x3 = U; + let [ref mut _x0, _, ref _x2, _, _x4, ref mut _x5, _x6, _] = arr; + *_x5 = U; + let [_, _, _x2, _, _, _x5, _, _] = arr; + *_x0 = U; + let [ref _x0, ..] = arr; + let [_x0, ..] = arr; +} + +fn tuple() { + let mut tup = (U, U, U, U, U); + let (ref _x0, mut _x1, ref _x2, ..) = tup; + _x1 = U; + let (ref mut _x0, _, _, ref _x3, _x4) = tup; + let (_, _, _, _x3, _) = tup; + *_x0 = U; + drop(_x2); + drop(tup.2); + let (_x0, _, _, ..) = tup; +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs new file mode 100644 index 0000000000000..3ee008fd84f09 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs @@ -0,0 +1,50 @@ +#![feature(move_ref_pattern)] + +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U]; + let hold_all = &arr; + let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; //~ ERROR cannot move out of `arr[..]` + _x1 = U; //~ ERROR cannot assign twice to immutable variable `_x1` + drop(hold_all); + let [_x0, ..] = arr; //~ ERROR cannot move out of `arr[..]` + drop(_x0_hold); + let [_, _, ref mut _x2, _x3, mut _x4] = arr; + //~^ ERROR cannot borrow `arr[..]` as mutable + //~| ERROR cannot move out of `arr[..]` because it is borrowed + //~| ERROR cannot move out of `arr[..]` because it is borrowed + drop(xs_hold); +} + +fn tuple() { + let mut tup = (U, U, U, U); + let (ref _x0, _x1, ref _x2, ..) = tup; + _x1 = U; //~ ERROR cannot assign twice to immutable variable + let _x0_hold = &mut tup.0; //~ ERROR cannot borrow `tup.0` as mutable because it is also + let (ref mut _x0_hold, ..) = tup; //~ ERROR cannot borrow `tup.0` as mutable because it is also + *_x0 = U; //~ ERROR cannot assign to `*_x0` which is behind a `&` reference + *_x2 = U; //~ ERROR cannot assign to `*_x2` which is behind a `&` reference + drop(tup.1); //~ ERROR use of moved value: `tup.1` + let _x1_hold = &tup.1; //~ ERROR borrow of moved value: `tup.1` + let (.., ref mut _x3) = tup; + let _x3_hold = &tup.3; //~ ERROR cannot borrow `tup.3` as immutable + let _x3_hold = &mut tup.3; //~ ERROR cannot borrow `tup.3` as mutable more + let (.., ref mut _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as mutable more + let (.., ref _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as immutable + drop(_x3); +} + +fn closure() { + let mut tup = (U, U, U); + let c1 = || { + let (ref _x0, _x1, _) = tup; + }; + let c2 = || { + //~^ ERROR use of moved value + let (ref mut _x0, _, _x2) = tup; + }; + drop(c1); +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr new file mode 100644 index 0000000000000..d718ee29cf9b5 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -0,0 +1,208 @@ +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:10:24 + | +LL | let hold_all = &arr; + | ---- borrow of `arr` occurs here +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ^^^ move out of `arr[..]` occurs here +LL | _x1 = U; +LL | drop(hold_all); + | -------- borrow later used here + +error[E0384]: cannot assign twice to immutable variable `_x1` + --> $DIR/borrowck-move-ref-pattern.rs:11:5 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | --- + | | + | first assignment to `_x1` + | help: make this binding mutable: `mut _x1` +LL | _x1 = U; + | ^^^^^^^ cannot assign twice to immutable variable + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:13:10 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ------------ borrow of `arr[..]` occurs here +... +LL | let [_x0, ..] = arr; + | ^^^ move out of `arr[..]` occurs here +LL | drop(_x0_hold); + | -------- borrow later used here + +error[E0502]: cannot borrow `arr[..]` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:15:16 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- immutable borrow occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^^^^^^^^^ mutable borrow occurs here +... +LL | drop(xs_hold); + | ------- immutable borrow later used here + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:15:29 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- borrow of `arr[..]` occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^ move out of `arr[..]` occurs here +... +LL | drop(xs_hold); + | ------- borrow later used here + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:15:34 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- borrow of `arr[..]` occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^^^^^ move out of `arr[..]` occurs here +... +LL | drop(xs_hold); + | ------- borrow later used here + +error[E0384]: cannot assign twice to immutable variable `_x1` + --> $DIR/borrowck-move-ref-pattern.rs:25:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | --- + | | + | first assignment to `_x1` + | help: make this binding mutable: `mut _x1` +LL | _x1 = U; + | ^^^^^^^ cannot assign twice to immutable variable + +error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:26:20 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- immutable borrow occurs here +LL | _x1 = U; +LL | let _x0_hold = &mut tup.0; + | ^^^^^^^^^^ mutable borrow occurs here +LL | let (ref mut _x0_hold, ..) = tup; +LL | *_x0 = U; + | -------- immutable borrow later used here + +error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:27:10 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- immutable borrow occurs here +... +LL | let (ref mut _x0_hold, ..) = tup; + | ^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | *_x0 = U; + | -------- immutable borrow later used here + +error[E0594]: cannot assign to `*_x0` which is behind a `&` reference + --> $DIR/borrowck-move-ref-pattern.rs:28:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- help: consider changing this to be a mutable reference: `ref mut _x0` +... +LL | *_x0 = U; + | ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written + +error[E0594]: cannot assign to `*_x2` which is behind a `&` reference + --> $DIR/borrowck-move-ref-pattern.rs:29:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- help: consider changing this to be a mutable reference: `ref mut _x2` +... +LL | *_x2 = U; + | ^^^^^^^^ `_x2` is a `&` reference, so the data it refers to cannot be written + +error[E0382]: use of moved value: `tup.1` + --> $DIR/borrowck-move-ref-pattern.rs:30:10 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | --- value moved here +... +LL | drop(tup.1); + | ^^^^^ value used here after move + | + = note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `tup.1` + --> $DIR/borrowck-move-ref-pattern.rs:31:20 + | +LL | drop(tup.1); + | ----- value moved here +LL | let _x1_hold = &tup.1; + | ^^^^^^ value borrowed here after move + | + = note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait + +error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-move-ref-pattern.rs:33:20 + | +LL | let (.., ref mut _x3) = tup; + | ----------- mutable borrow occurs here +LL | let _x3_hold = &tup.3; + | ^^^^^^ immutable borrow occurs here +... +LL | drop(_x3); + | --- mutable borrow later used here + +error[E0499]: cannot borrow `tup.3` as mutable more than once at a time + --> $DIR/borrowck-move-ref-pattern.rs:34:20 + | +LL | let (.., ref mut _x3) = tup; + | ----------- first mutable borrow occurs here +LL | let _x3_hold = &tup.3; +LL | let _x3_hold = &mut tup.3; + | ^^^^^^^^^^ second mutable borrow occurs here +... +LL | drop(_x3); + | --- first borrow later used here + +error[E0499]: cannot borrow `tup.3` as mutable more than once at a time + --> $DIR/borrowck-move-ref-pattern.rs:35:14 + | +LL | let (.., ref mut _x3) = tup; + | ----------- first mutable borrow occurs here +... +LL | let (.., ref mut _x4_hold) = tup; + | ^^^^^^^^^^^^^^^^ second mutable borrow occurs here +LL | let (.., ref _x4_hold) = tup; +LL | drop(_x3); + | --- first borrow later used here + +error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-move-ref-pattern.rs:36:14 + | +LL | let (.., ref mut _x3) = tup; + | ----------- mutable borrow occurs here +... +LL | let (.., ref _x4_hold) = tup; + | ^^^^^^^^^^^^ immutable borrow occurs here +LL | drop(_x3); + | --- mutable borrow later used here + +error[E0382]: use of moved value: `tup` + --> $DIR/borrowck-move-ref-pattern.rs:45:14 + | +LL | let mut tup = (U, U, U); + | ------- move occurs because `tup` has type `(U, U, U)`, which does not implement the `Copy` trait +LL | let c1 = || { + | -- value moved into closure here +LL | let (ref _x0, _x1, _) = tup; + | --- variable moved due to use in closure +LL | }; +LL | let c2 = || { + | ^^ value used here after move +LL | +LL | let (ref mut _x0, _, _x2) = tup; + | --- use occurs due to use in closure + +error: aborting due to 18 previous errors + +Some errors have detailed explanations: E0382, E0384, E0499, E0502, E0505, E0594. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs new file mode 100644 index 0000000000000..fb92eb1ba32e0 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs @@ -0,0 +1,23 @@ +fn main() { + #[derive(Clone)] + struct X { + x: (), + } + let mut tup = (X { x: () }, X { x: () }); + match Some(tup.clone()) { + Some((y, ref z)) => {} + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + None => panic!(), + } + + let (ref a, b) = tup.clone(); + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + + let (a, mut b) = &tup; + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + //~| ERROR cannot move out of a shared reference + + let (mut a, b) = &mut tup; + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + //~| ERROR cannot move out of a mutable reference +} diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr new file mode 100644 index 0000000000000..8aef220c37519 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr @@ -0,0 +1,66 @@ +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:8:15 + | +LL | Some((y, ref z)) => {} + | ^ ----- by-ref pattern here + | | + | by-move pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:13:17 + | +LL | let (ref a, b) = tup.clone(); + | ----- ^ by-move pattern here + | | + | by-ref pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:16:13 + | +LL | let (a, mut b) = &tup; + | - ^^^^^ by-move pattern here + | | + | by-ref pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:20:10 + | +LL | let (mut a, b) = &mut tup; + | ^^^^^ - by-ref pattern here + | | + | by-move pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0507]: cannot move out of a shared reference + --> $DIR/feature-gate-move_ref_pattern.rs:16:22 + | +LL | let (a, mut b) = &tup; + | ----- ^^^^ + | | + | data moved here + | move occurs because `b` has type `main::X`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of a mutable reference + --> $DIR/feature-gate-move_ref_pattern.rs:20:22 + | +LL | let (mut a, b) = &mut tup; + | ----- ^^^^^^^^ + | | + | data moved here + | move occurs because `a` has type `main::X`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0507, E0658. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/issues/issue-53840.rs b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs similarity index 64% rename from src/test/ui/issues/issue-53840.rs rename to src/test/ui/pattern/move-ref-patterns/issue-53840.rs index e854d24ab9756..ab7d10d9f837d 100644 --- a/src/test/ui/issues/issue-53840.rs +++ b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs @@ -1,3 +1,7 @@ +// check-pass + +#![feature(move_ref_pattern)] + enum E { Foo(String, String, String), } @@ -11,10 +15,8 @@ fn main() { let bar = Bar { a: "1".to_string(), b: "2".to_string() }; match E::Foo("".into(), "".into(), "".into()) { E::Foo(a, b, ref c) => {} -//~^ ERROR cannot bind by-move and by-ref in the same pattern } match bar { - Bar {a, ref b} => {} -//~^ ERROR cannot bind by-move and by-ref in the same pattern + Bar { a, ref b } => {} } } diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs new file mode 100644 index 0000000000000..e1844d36e4aa4 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(move_ref_pattern)] + +fn main() { + struct U; + fn accept_fn_once(_: impl FnOnce()) {} + fn accept_fn_mut(_: impl FnMut()) {} + fn accept_fn(_: impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { + drop::<&U>(_x0); + drop::(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(c1); + + let c2 = || { + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(c3); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs new file mode 100644 index 0000000000000..7f1c02c05cb0d --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs @@ -0,0 +1,34 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct U; + fn accept_fn_once(_: &impl FnOnce()) {} + fn accept_fn_mut(_: &impl FnMut()) {} + fn accept_fn(_: &impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { + //~^ ERROR expected a closure that implements the `FnMut` + //~| ERROR expected a closure that implements the `Fn` + drop::<&U>(_x0); + drop::(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(&c1); + accept_fn_mut(&c1); + accept_fn(&c1); + + let c2 = || { + //~^ ERROR expected a closure that implements the `Fn` + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(&c2); + accept_fn(&c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(&c3); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr new file mode 100644 index 0000000000000..ca82353c1c9ab --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -0,0 +1,39 @@ +error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce` + --> $DIR/move-ref-patterns-closure-captures.rs:11:14 + | +LL | let c1 = || { + | ^^ this closure implements `FnOnce`, not `FnMut` +... +LL | drop::(_x1); + | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment +... +LL | accept_fn_mut(&c1); + | ------------- the requirement to implement `FnMut` derives from here + +error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` + --> $DIR/move-ref-patterns-closure-captures.rs:11:14 + | +LL | let c1 = || { + | ^^ this closure implements `FnOnce`, not `Fn` +... +LL | drop::(_x1); + | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment +... +LL | accept_fn(&c1); + | --------- the requirement to implement `Fn` derives from here + +error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` + --> $DIR/move-ref-patterns-closure-captures.rs:22:14 + | +LL | let c2 = || { + | ^^ this closure implements `FnMut`, not `Fn` +... +LL | drop::<&mut U>(_x2); + | --- closure is `FnMut` because it mutates the variable `_x2` here +... +LL | accept_fn(&c2); + | --------- the requirement to implement `Fn` derives from here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0525`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs new file mode 100644 index 0000000000000..5c51c47d9798a --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs @@ -0,0 +1,16 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct U; + + // A tuple is a "non-reference pattern". + // A `mut` binding pattern resets the binding mode to by-value. + + let p = (U, U); + let (a, mut b) = &p; + //~^ ERROR cannot move out of a shared reference + + let mut p = (U, U); + let (a, mut b) = &mut p; + //~^ ERROR cannot move out of a mutable reference +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr new file mode 100644 index 0000000000000..fe7f71e6c46cd --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr @@ -0,0 +1,21 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/move-ref-patterns-default-binding-modes.rs:10:22 + | +LL | let (a, mut b) = &p; + | ----- ^^ + | | + | data moved here + | move occurs because `b` has type `main::U`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of a mutable reference + --> $DIR/move-ref-patterns-default-binding-modes.rs:14:22 + | +LL | let (a, mut b) = &mut p; + | ----- ^^^^^^ + | | + | data moved here + | move occurs because `b` has type `main::U`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs new file mode 100644 index 0000000000000..c78695390b598 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs @@ -0,0 +1,81 @@ +// run-pass + +// This test checks the dynamic semantics and drop order of pattern matching +// where a product pattern has both a by-move and by-ref binding. + +#![feature(move_ref_pattern)] + +use std::cell::RefCell; +use std::rc::Rc; + +struct X { + x: Box, + d: DropOrderListPtr, +} + +type DropOrderListPtr = Rc>>; + +impl Drop for X { + fn drop(&mut self) { + self.d.borrow_mut().push(*self.x); + } +} + +enum DoubleOption { + Some2(T, U), + _None2, +} + +fn main() { + let d: DropOrderListPtr = <_>::default(); + { + let mk = |v| X { x: Box::new(v), d: d.clone() }; + let check = |a1: &X, a2, b1: &X, b2| { + assert_eq!(*a1.x, a2); + assert_eq!(*b1.x, b2); + }; + + let x = DoubleOption::Some2(mk(1), mk(2)); + match x { + DoubleOption::Some2(ref a, b) => check(a, 1, &b, 2), + DoubleOption::_None2 => panic!(), + } + let x = DoubleOption::Some2(mk(3), mk(4)); + match x { + DoubleOption::Some2(a, ref b) => check(&a, 3, b, 4), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(5), mk(6)) { + DoubleOption::Some2(ref a, b) => check(a, 5, &b, 6), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(7), mk(8)) { + DoubleOption::Some2(a, ref b) => check(&a, 7, b, 8), + DoubleOption::_None2 => panic!(), + } + { + let (a, ref b) = (mk(9), mk(10)); + let (ref c, d) = (mk(11), mk(12)); + check(&a, 9, b, 10); + check(c, 11, &d, 12); + } + fn fun([a, ref mut b, ref xs @ .., ref c, d]: [X; 6]) { + assert_eq!(*a.x, 13); + assert_eq!(*b.x, 14); + assert_eq!(&[*xs[0].x, *xs[1].x], &[15, 16]); + assert_eq!(*c.x, 17); + assert_eq!(*d.x, 18); + } + fun([mk(13), mk(14), mk(15), mk(16), mk(17), mk(18)]); + + let lam = |(a, ref b, c, ref mut d): (X, X, X, X)| { + assert_eq!(*a.x, 19); + assert_eq!(*b.x, 20); + assert_eq!(*c.x, 21); + assert_eq!(*d.x, 22); + }; + lam((mk(19), mk(20), mk(21), mk(22))); + } + let expected = [2, 3, 6, 5, 7, 8, 12, 11, 9, 10, 18, 13, 14, 15, 16, 17, 21, 19, 20, 22, 4, 1]; + assert_eq!(&*d.borrow(), &expected); +} diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 31620216e82e1..84552f2e73315 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -2,7 +2,7 @@ // outside of slice (+ ident patterns witin those), tuple, // and tuple struct patterns and that duplicates are caught in these contexts. -#![feature(slice_patterns, box_patterns)] +#![feature(box_patterns)] fn main() {} diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs index 3bf053eb874ce..aa42c7bb9c2f1 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs @@ -1,10 +1,11 @@ +#![feature(move_ref_pattern)] + struct Foo {} pub fn main() { - let mut tups = vec![(Foo{}, Foo{})]; + let mut tups = vec![(Foo {}, Foo {})]; // The below desugars to &(ref n, mut m). for (n, mut m) in &tups { - //~^ ERROR cannot bind by-move and by-ref in the same pattern - //~| ERROR cannot move out of a shared reference + //~^ ERROR cannot move out of a shared reference } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr index ebc6ff5d8c3fe..ef62431388081 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr @@ -1,13 +1,5 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/for.rs:6:13 - | -LL | for (n, mut m) in &tups { - | - ^^^^^ by-move pattern here - | | - | by-ref pattern here - error[E0507]: cannot move out of a shared reference - --> $DIR/for.rs:6:23 + --> $DIR/for.rs:8:23 | LL | for (n, mut m) in &tups { | ----- ^^^^^ @@ -15,7 +7,6 @@ LL | for (n, mut m) in &tups { | data moved here | move occurs because `m` has type `Foo`, which does not implement the `Copy` trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0009, E0507. -For more information about an error, try `rustc --explain E0009`. +For more information about this error, try `rustc --explain E0507`. From 0253f868cab2c5be84d354589b4b833aedbc9987 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 20 Jan 2020 11:03:30 +0100 Subject: [PATCH 0799/1253] move_ref_pattern: adjust error index --- src/librustc_error_codes/error_codes/E0009.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0009.md b/src/librustc_error_codes/error_codes/E0009.md index abb7fe41ab7a2..aaabba0434993 100644 --- a/src/librustc_error_codes/error_codes/E0009.md +++ b/src/librustc_error_codes/error_codes/E0009.md @@ -1,3 +1,5 @@ +#### Note: this error code is no longer emitted by the compiler. + In a pattern, all values that don't implement the `Copy` trait have to be bound the same way. The goal here is to avoid binding simultaneously by-move and by-ref. @@ -6,7 +8,9 @@ This limitation may be removed in a future version of Rust. Erroneous code example: -```compile_fail,E0009 +``` +#![feature(move_ref_pattern)] + struct X { x: (), } let x = Some((X { x: () }, X { x: () })); From 8c5bec103fcbe24c2c3d9e03acdd1551c402c947 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 2 Feb 2020 14:51:30 +0100 Subject: [PATCH 0800/1253] bump Miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 83403581bb7a2..75417e5a66009 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 83403581bb7a2156f4752fc2d0ceef4b3ec75554 +Subproject commit 75417e5a660096929aa10f1072a21d6662c9c0dc From 019ca55b45f0b4e1de74c19bca06c20134ac9103 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 2 Feb 2020 15:28:18 +0100 Subject: [PATCH 0801/1253] Clean up E0263 explanation --- src/librustc_error_codes/error_codes/E0263.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0263.md b/src/librustc_error_codes/error_codes/E0263.md index bb4da43b3f58b..37271ac692d55 100644 --- a/src/librustc_error_codes/error_codes/E0263.md +++ b/src/librustc_error_codes/error_codes/E0263.md @@ -1,7 +1,16 @@ -A lifetime name cannot be declared more than once in the same scope. For -example: +A lifetime was declared more than once in the same scope. + +Erroneous code example: ```compile_fail,E0263 -// error, lifetime name `'a` declared twice in the same scope -fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } +fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error! +} +``` + +Two lifetimes cannot have the same name. To fix this example, change +the second `'a` lifetime into something else (`'c` for example): + +``` +fn foo<'a, 'b, 'c>(x: &'a str, y: &'b str, z: &'c str) { // ok! +} ``` From 8d4973f5871fd36b5946b9a06bd1157d4a87bbe0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 16:07:51 +0100 Subject: [PATCH 0802/1253] move_ref_pattern: don't ICE on unreachable 2xby-move conflicts --- .../hair/pattern/check_match.rs | 3 --- .../by-move-sub-pat-unreachable.rs | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index a563864b61b31..0b01c9a06f9d4 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -648,9 +648,6 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ let mut conflicts_ref = Vec::new(); sub.each_binding(|_, hir_id, span, _| { match tables.extract_binding_mode(sess, hir_id, span) { - Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { - sess.delay_span_bug(span, "by-move in subpat unchecked by borrowck"); - } Some(ty::BindByValue(_)) | None => {} Some(ty::BindByReference(_)) => conflicts_ref.push(span), } diff --git a/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs new file mode 100644 index 0000000000000..08fb5cd2e1688 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs @@ -0,0 +1,15 @@ +// When conflicts between by-move bindings in `by_move_1 @ has_by_move` patterns +// happen and that code is unreachable according to borrowck, we accept this code. +// In particular, we want to ensure here that an ICE does not happen, which it did originally. + +// check-pass + +#![feature(move_ref_pattern)] +#![feature(bindings_after_at)] + +fn main() { + return; + + struct S; + let a @ (b, c) = (S, S); +} From bd318be05dab2e1149595aacbf3d808559fa42dc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 17:58:15 +0100 Subject: [PATCH 0803/1253] move_ref_pattern: change pov in diagnostics & add binding names --- .../hair/pattern/check_match.rs | 76 ++++--- ...her-can-live-while-the-other-survives-1.rs | 4 +- ...can-live-while-the-other-survives-1.stderr | 20 +- .../borrowck-pat-at-and-box.rs | 16 +- .../borrowck-pat-at-and-box.stderr | 48 ++-- ...t-by-move-and-ref-inverse-promotion.stderr | 4 +- ...orrowck-pat-by-move-and-ref-inverse.stderr | 100 ++++----- .../borrowck-pat-by-move-and-ref.rs | 50 ++--- .../borrowck-pat-by-move-and-ref.stderr | 170 +++++++------- .../borrowck-pat-ref-mut-and-ref.rs | 64 +++--- .../borrowck-pat-ref-mut-and-ref.stderr | 208 +++++++++--------- .../borrowck-pat-ref-mut-twice.rs | 40 ++-- .../borrowck-pat-ref-mut-twice.stderr | 152 ++++++------- ...lt-binding-modes-both-sides-independent.rs | 10 +- ...inding-modes-both-sides-independent.stderr | 28 +-- 15 files changed, 501 insertions(+), 489 deletions(-) diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 0b01c9a06f9d4..b77bd4ecb8e1f 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -658,8 +658,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ name, tables.node_type(pat.hir_id), ); - sess.struct_span_err(pat.span, &format!("borrow of moved value: `{}`", name)) - .span_label(binding_span, "value moved here") + sess.struct_span_err(pat.span, "borrow of moved value") + .span_label(binding_span, format!("value moved into `{}` here", name)) .span_label(binding_span, occurs_because) .span_labels(conflicts_ref, "value borrowed here after move") .emit(); @@ -675,50 +675,62 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_ let mut conflicts_move = Vec::new(); let mut conflicts_mut_mut = Vec::new(); let mut conflicts_mut_ref = Vec::new(); - sub.each_binding(|_, hir_id, span, _| match tables.extract_binding_mode(sess, hir_id, span) { - Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { - (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. - (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), // 2x `ref mut`. - _ => conflicts_mut_ref.push(span), // `ref` + `ref mut` in either direction. - }, - Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { - conflicts_move.push(span) // `ref mut?` + by-move conflict. + sub.each_binding(|_, hir_id, span, name| { + match tables.extract_binding_mode(sess, hir_id, span) { + Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { + (Mutability::Not, Mutability::Not) => {} // Both sides are `ref`. + (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`. + _ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction. + }, + Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => { + conflicts_move.push((span, name)) // `ref mut?` + by-move conflict. + } + Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. } - Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine. }); // Report errors if any. if !conflicts_mut_mut.is_empty() { // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, "first mutable borrow occurs here") - .span_labels(conflicts_mut_mut, "another mutable borrow occurs here") - .span_labels(conflicts_mut_ref, "also borrowed as immutable here") - .span_labels(conflicts_move, "also moved here") - .emit(); + let mut err = sess + .struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time"); + err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name)); + for (span, name) in conflicts_mut_mut { + err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name)); + } + for (span, name) in conflicts_mut_ref { + err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name)); + } + for (span, name) in conflicts_move { + err.span_label(span, format!("also moved into `{}` here", name)); + } + err.emit(); } else if !conflicts_mut_ref.is_empty() { // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. let (primary, also) = match mut_outer { Mutability::Mut => ("mutable", "immutable"), Mutability::Not => ("immutable", "mutable"), }; - let msg = &format!( - "cannot borrow `{}` as {} because it is also borrowed as {}", - name, also, primary, - ); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, format!("{} borrow occurs here", primary)) - .span_labels(conflicts_mut_ref, format!("{} borrow occurs here", also)) - .span_labels(conflicts_move, "also moved here") - .emit(); + let msg = + format!("cannot borrow value as {} because it is also borrowed as {}", also, primary); + let mut err = sess.struct_span_err(pat.span, &msg); + err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name)); + for (span, name) in conflicts_mut_ref { + err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name)); + } + for (span, name) in conflicts_move { + err.span_label(span, format!("also moved into `{}` here", name)); + } + err.emit(); } else if !conflicts_move.is_empty() { // Report by-ref and by-move conflicts, e.g. `ref x @ y`. - let msg = &format!("cannot move out of `{}` because it is borrowed", name); - sess.struct_span_err(pat.span, msg) - .span_label(binding_span, format!("borrow of `{}` occurs here", name)) - .span_labels(conflicts_move, format!("move out of `{}` occurs here", name)) - .emit(); + let mut err = + sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed"); + err.span_label(binding_span, format!("value borrowed, by `{}`, here", name)); + for (span, name) in conflicts_move { + err.span_label(span, format!("value moved into `{}` here", name)); + } + err.emit(); } } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 1cad822382677..c00296c34c4e5 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -12,7 +12,7 @@ struct X { fn main() { let x = Some(X { x: () }); match x { - Some(ref _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed None => panic!(), } @@ -26,7 +26,7 @@ fn main() { let mut x = Some(X { x: () }); match x { - Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed + Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed None => panic!(), } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 6ad0248fc6b2f..026747c212a2c 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -1,39 +1,39 @@ -error: cannot move out of `_y` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14 | LL | Some(ref _y @ _z) => {} | ------^^^-- | | | - | | move out of `_y` occurs here - | borrow of `_y` occurs here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error: borrow of moved value: `_z` +error: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14 | LL | Some(_z @ ref _y) => {} | --^^^------ | | | | | value borrowed here after move - | value moved here + | value moved into `_z` here | move occurs because `_z` has type `X` which does implement the `Copy` trait -error: cannot move out of `_y` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14 | LL | Some(ref mut _y @ _z) => {} | ----------^^^-- | | | - | | move out of `_y` occurs here - | borrow of `_y` occurs here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error: borrow of moved value: `_z` +error: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14 | LL | Some(_z @ ref mut _y) => {} | --^^^---------- | | | | | value borrowed here after move - | value moved here + | value moved into `_z` here | move occurs because `_z` has type `X` which does implement the `Copy` trait error[E0382]: borrow of moved value diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index e90aeab2edb0b..32c638bcbcca3 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -34,29 +34,29 @@ fn main() { a @ box b => {} //~ ERROR use of moved value } - let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of `a` because it is borrowed + let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed let ref a @ box ref mut b = Box::new(nc()); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = NC; let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = NC; drop(a); let ref mut a @ box ref b = Box::new(NC); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); fn f5(ref mut a @ box ref b: Box) { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); @@ -64,7 +64,7 @@ fn main() { match Box::new(nc()) { ref mut a @ box ref b => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 50185c1a017d3..5534d0a75e63d 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,74 +1,74 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-at-and-box.rs:37:9 | LL | let ref a @ box b = Box::new(NC); | -----^^^^^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:39:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:41:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:43:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:46:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-at-and-box.rs:52:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-at-and-box.rs:66:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-at-and-box.rs:58:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here error[E0382]: use of moved value --> $DIR/borrowck-pat-at-and-box.rs:21:18 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr index dc9201d0d061f..91fdfd4f2abcc 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -1,11 +1,11 @@ -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:9:9 | LL | let a @ ref b = U; | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index 0c502cee7f6c9..ec86692dc6962 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -1,14 +1,14 @@ -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9 | LL | let a @ ref b = U; | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); @@ -16,30 +16,30 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:14 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | -----^^^--------- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9 | LL | let a @ [ref mut b, ref c] = [U, U]; @@ -47,20 +47,20 @@ LL | let a @ [ref mut b, ref c] = [U, U]; | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9 | LL | let a @ ref b = u(); | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); @@ -68,30 +68,30 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:14 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | -----^^^--------- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:9 | LL | let a @ [ref mut b, ref c] = [u(), u()]; @@ -99,20 +99,20 @@ LL | let a @ [ref mut b, ref c] = [u(), u()]; | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9 | LL | a @ Some(ref b) => {} | -^^^^^^^^-----^ | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} @@ -120,30 +120,30 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:19 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | -----^^^--------- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:9 | LL | mut a @ Some([ref b, ref mut c]) => {} @@ -151,20 +151,20 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9 | LL | a @ Some(ref b) => {} | -^^^^^^^^-----^ | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:9 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} @@ -172,30 +172,30 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:19 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | -----^^^--------- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 | LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:9 | LL | mut a @ Some([ref b, ref mut c]) => {} @@ -203,20 +203,20 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 | LL | fn f1(a @ ref b: U) {} | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:11 | LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} @@ -224,30 +224,30 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:20 | LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `d` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31 | LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | -----^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `d` here | move occurs because `d` has type `main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:11 | LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} @@ -255,7 +255,7 @@ LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait error[E0382]: borrow of moved value diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs index 4ece55b07b080..b7c8c8766c00a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -12,63 +12,63 @@ fn main() { } fn f1(ref a @ b: U) {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed fn f3(ref mut a @ [b, mut c]: [U; 2]) {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ b = U; - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ (ref b @ mut c, ref d @ e) = (U, U); - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ [b, mut c] = [U, U]; - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ b = u(); - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ [b, mut c] = [u(), u()]; - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed match Some(U) { ref a @ Some(b) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } match Some((U, U)) { ref a @ Some((ref b @ mut c, ref d @ e)) => {} - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed None => {} } match Some([U, U]) { ref mut a @ Some([b, mut c]) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } match Some(u()) { ref a @ Some(b) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } match Some((u(), u())) { ref a @ Some((ref b @ mut c, ref d @ e)) => {} - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR cannot move out of `b` because it is borrowed - //~| ERROR cannot move out of `d` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed None => {} } match Some([u(), u()]) { ref mut a @ Some([b, mut c]) => {} - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed None => {} } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 607bbd5f991c0..e5419efa00b36 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -1,237 +1,237 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9 | LL | let ref a @ b = U; | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:25:9 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:25:18 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:25:33 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:29:9 | LL | let ref mut a @ [b, mut c] = [U, U]; | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:31:9 | LL | let ref a @ b = u(); | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:33:9 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:33:18 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:33:33 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:37:9 | LL | let ref mut a @ [b, mut c] = [u(), u()]; | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:41:9 | LL | ref a @ Some(b) => {} | -----^^^^^^^^-^ | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:46:9 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:46:23 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:46:38 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:53:9 | LL | ref mut a @ Some([b, mut c]) => {} | ---------^^^^^^^^^-^^-----^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:58:9 | LL | ref a @ Some(b) => {} | -----^^^^^^^^-^ | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:63:9 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:63:23 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:63:38 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:70:9 | LL | ref mut a @ Some([b, mut c]) => {} | ---------^^^^^^^^^-^^-----^^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 | LL | fn f1(ref a @ b: U) {} | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:16:11 | LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:16:20 | LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | -----^^^----- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here -error: cannot move out of `d` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:16:35 | LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | -----^^^- | | | - | | move out of `d` occurs here - | borrow of `d` occurs here + | | value moved into `e` here + | value borrowed, by `d`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 | LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} | ---------^^^^-^^-----^ | | | | - | | | move out of `a` occurs here - | | move out of `a` occurs here - | borrow of `a` occurs here + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here error: aborting due to 25 previous errors diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index a921ad056d81f..58d4a9b018cee 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -9,7 +9,7 @@ enum Option { fn main() { match &mut Some(1) { ref mut z @ &mut Some(ref a) => { - //~^ ERROR cannot borrow `z` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable **z = None; println!("{}", *a); @@ -23,52 +23,52 @@ fn main() { fn u() -> U { U } fn f1(ref a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable fn f2(ref mut a @ ref b: U) {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable fn f4_also_moved(ref a @ ref mut b @ c: U) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot move out of `b` because it is borrowed + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `b` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref mut a @ ref b = u(); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = u(); drop(b); let ref a @ ref mut b = u(); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = u(); drop(a); let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = U; drop(b); let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; drop(a); match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = Err(U); drop(b); } @@ -76,8 +76,8 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; @@ -87,52 +87,52 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot assign to `*a`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot move out of `a` in pattern guard //~| ERROR cannot move out of `a` in pattern guard _ => {} } let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; *c = U; let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; drop(a); let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *c = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable drop(a); let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 4652fffe36a42..8c6ca888e0762 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,298 +1,298 @@ -error: cannot borrow `z` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `a`, occurs here + | mutable borrow, by `z`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ | | | | - | | | another mutable borrow occurs here - | | also borrowed as immutable here - | first mutable borrow occurs here + | | | another mutable borrow, by `c`, occurs here + | | also borrowed as immutable, by `b`, here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `b` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `c`, occurs here + | immutable borrow, by `b`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable +error: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `mid`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable +error: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 | LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} | -----^^^------------- | | | | - | | | also moved here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | also moved into `c` here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:30 | LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} | ---------^^^- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index 77cd779d7167f..f5c39a7ac5276 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -9,12 +9,12 @@ fn main() { fn u() -> U { U } fn f1(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f2(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f3( ref mut a @ [ - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time [ref b @ .., _], [_, ref mut mid @ ..], .., @@ -22,29 +22,29 @@ fn main() { ] : [[U; 4]; 5] ) {} fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot move out of `b` because it is borrowed + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time drop(b); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = U; let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time *b = U; let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -54,7 +54,7 @@ fn main() { ) = (U, [U, U, U]); let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -80,21 +80,21 @@ fn main() { match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time *b = U; } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = Err(U); @@ -105,8 +105,8 @@ fn main() { } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index a6d6678736475..4e96c6e1669c7 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,93 +1,93 @@ -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (U, [U, U, U]); | |_____^ -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (u(), [u(), u(), u()]); | |_________^ -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); @@ -95,10 +95,10 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- @@ -107,20 +107,20 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | | | | value borrowed here after move | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 | LL | let a @ &mut ref mut b = &mut U; | -^^^^^^^^--------- | | | | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait -error: borrow of moved value: `a` +error: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:77:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); @@ -128,135 +128,135 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | | | | | | | value borrowed here after move | | value borrowed here after move - | value moved here + | value moved into `a` here | move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 | LL | ref mut a @ [ | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | [ref b @ .., _], - | | ---------- also borrowed as immutable here + | | ---------- also borrowed as immutable, by `b`, here LL | | [_, ref mut mid @ ..], - | | ---------------- another mutable borrow occurs here + | | ---------------- another mutable borrow, by `mid`, occurs here LL | | .., LL | | [..], LL | | ] : [[U; 4]; 5] | |_________^ -error: cannot borrow `a` as mutable more than once at a time +error: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:24:22 | LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} | ---------^^^------------- | | | | - | | | also moved here - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | | also moved into `c` here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot move out of `b` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/borrowck-pat-ref-mut-twice.rs:24:34 | LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} | ---------^^^- | | | - | | move out of `b` occurs here - | borrow of `b` occurs here + | | value moved into `c` here + | value borrowed, by `b`, here error[E0499]: cannot borrow `_` as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:28:21 diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs index 94becb9e8b8e3..b40c3e3358aa3 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -25,24 +25,24 @@ fn main() { let ref a @ b = &NotCopy; // OK let _: &&NotCopy = a; - let ref a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let ref a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; - let ref mut a @ b = NotCopy; //~ ERROR cannot move out of `a` because it is borrowed + let ref mut a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed //~^ ERROR cannot move out of `_` because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; match Ok(NotCopy) { Ok(ref a @ b) | Err(b @ ref a) => { - //~^ ERROR cannot move out of `a` because it is borrowed - //~| ERROR borrow of moved value: `b` + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR borrow of moved value let _a: &NotCopy = a; let _b: NotCopy = b; } } match NotCopy { ref a @ b => { - //~^ ERROR cannot move out of `a` because it is borrowed + //~^ ERROR cannot move out of value because it is borrowed let _a: &NotCopy = a; let _b: NotCopy = b; } diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index dfc6e16600e2a..697a8b96e6318 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -1,48 +1,48 @@ -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:28:9 | LL | let ref a @ b = NotCopy; | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:31:9 | LL | let ref mut a @ b = NotCopy; | ---------^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:36:12 | LL | Ok(ref a @ b) | Err(b @ ref a) => { | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here -error: borrow of moved value: `b` +error: borrow of moved value --> $DIR/default-binding-modes-both-sides-independent.rs:36:29 | LL | Ok(ref a @ b) | Err(b @ ref a) => { | -^^^----- | | | | | value borrowed here after move - | value moved here + | value moved into `b` here | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait -error: cannot move out of `a` because it is borrowed +error: cannot move out of value because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:44:9 | LL | ref a @ b => { | -----^^^- | | | - | | move out of `a` occurs here - | borrow of `a` occurs here + | | value moved into `b` here + | value borrowed, by `a`, here error[E0505]: cannot move out of `_` because it is borrowed --> $DIR/default-binding-modes-both-sides-independent.rs:31:21 From ee601584403fa11563ed579d4c2cd5b747952056 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 2 Feb 2020 20:51:24 +0100 Subject: [PATCH 0804/1253] add raw-addr-of variant to mir_raw_fat_ptr --- src/test/ui/mir/mir_raw_fat_ptr.rs | 59 +++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/test/ui/mir/mir_raw_fat_ptr.rs b/src/test/ui/mir/mir_raw_fat_ptr.rs index 6583852aa9bb6..aa2b499b027dc 100644 --- a/src/test/ui/mir/mir_raw_fat_ptr.rs +++ b/src/test/ui/mir/mir_raw_fat_ptr.rs @@ -1,6 +1,7 @@ // run-pass // check raw fat pointer ops in mir // FIXME: please improve this when we get monomorphization support +#![feature(raw_ref_op)] use std::mem; @@ -104,7 +105,7 @@ impl Foo for T { struct S(u32, T); -fn main() { +fn main_ref() { let array = [0,1,2,3,4]; let array2 = [5,6,7,8,9]; @@ -156,3 +157,59 @@ fn main() { assert!(simple_eq(&0u8 as *const _, &0u8 as *const _)); assert!(!simple_eq(&0u8 as *const _, &1u8 as *const _)); } + +// similar to above, but using &raw +fn main_raw() { + let array = [0,1,2,3,4]; + let array2 = [5,6,7,8,9]; + + // fat ptr comparison: addr then extra + + // check ordering for arrays + let mut ptrs: Vec<*const [u8]> = vec![ + &raw const array[0..0], &raw const array[0..1], &raw const array, &raw const array[1..] + ]; + + let array_addr = &raw const array as *const u8 as usize; + let array2_addr = &raw const array2 as *const u8 as usize; + if array2_addr < array_addr { + ptrs.insert(0, &raw const array2); + } else { + ptrs.push(&raw const array2); + } + assert_inorder(&ptrs, compare_au8); + + let u8_ = (0u8, 1u8); + let u32_ = (4u32, 5u32); + + // check ordering for ptrs + let buf: &mut [*const dyn Foo] = &mut [ + &raw const u8_, &raw const u8_.0, + &raw const u32_, &raw const u32_.0, + ]; + buf.sort_by(|u,v| { + let u : [*const (); 2] = unsafe { mem::transmute(*u) }; + let v : [*const (); 2] = unsafe { mem::transmute(*v) }; + u.cmp(&v) + }); + assert_inorder(buf, compare_foo); + + // check ordering for structs containing arrays + let ss: (S<[u8; 2]>, + S<[u8; 3]>, + S<[u8; 2]>) = ( + S(7, [8, 9]), + S(10, [11, 12, 13]), + S(4, [5, 6]) + ); + assert_inorder(&[ + &raw const ss.0 as *const S<[u8]>, + &raw const ss.1 as *const S<[u8]>, + &raw const ss.2 as *const S<[u8]> + ], compare_su8); +} + +fn main() { + main_ref(); + main_raw(); +} From fca5c64abdf3422b3dc22910abd5460cca450d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 18 Jan 2020 14:57:56 -0800 Subject: [PATCH 0805/1253] Point at arguments or output when fn obligations come from them, or ident when they don't --- src/librustc_typeck/check/wfcheck.rs | 29 ++++++-- .../bad-bounds-on-assoc-in-trait.stderr | 67 +++++------------ ...ds-cant-promote-superkind-in-struct.stderr | 18 ++--- src/test/ui/error-codes/E0038.stderr | 4 +- ...ature-gate-object_safe_for_dispatch.stderr | 16 ++-- .../generic-associated-types/iterable.stderr | 26 +++---- src/test/ui/issues/issue-18919.stderr | 8 +- src/test/ui/issues/issue-18959.stderr | 4 +- src/test/ui/issues/issue-20005.stderr | 18 ++--- src/test/ui/issues/issue-20413.stderr | 13 ++-- src/test/ui/issues/issue-20433.stderr | 4 +- .../ui/issues/issue-20831-debruijn.stderr | 48 +++--------- src/test/ui/issues/issue-21974.stderr | 16 ++-- src/test/ui/issues/issue-23281.stderr | 4 +- src/test/ui/issues/issue-24204.stderr | 4 +- src/test/ui/issues/issue-27942.stderr | 8 +- .../lifetime-doesnt-live-long-enough.stderr | 74 +++++++------------ ...bject-safety-associated-consts.curr.stderr | 4 +- .../object-safety-generics.curr.stderr | 8 +- .../object-safety-mentions-Self.curr.stderr | 8 +- .../object-safety-no-static.curr.stderr | 4 +- .../object-safety-sized-2.curr.stderr | 4 +- .../object-safety-sized.curr.stderr | 4 +- ...gions-free-region-ordering-callee-4.stderr | 10 +-- ...-implied-bounds-projection-gap-hr-1.stderr | 9 +-- ...ions-normalize-in-where-clause-list.stderr | 22 ++---- src/test/ui/resolve/issue-3907-2.stderr | 4 +- ...-bounds-on-structs-and-enums-in-fns.stderr | 8 +- ...rait-bounds-on-structs-and-enums-xc.stderr | 8 +- .../generic_duplicate_lifetime_param.stderr | 8 +- .../ui/type/type-check/issue-40294.stderr | 16 ++-- src/test/ui/wf/wf-fn-where-clause.stderr | 25 +++---- src/test/ui/wf/wf-in-fn-arg.stderr | 17 ++--- src/test/ui/wf/wf-in-fn-ret.stderr | 17 ++--- src/test/ui/wf/wf-in-fn-where-clause.stderr | 16 ++-- ...f-inherent-impl-method-where-clause.stderr | 15 ++-- src/test/ui/wf/wf-trait-default-fn-arg.stderr | 19 ++--- src/test/ui/wf/wf-trait-default-fn-ret.stderr | 20 ++--- .../wf-trait-default-fn-where-clause.stderr | 19 ++--- src/test/ui/wf/wf-trait-fn-arg.stderr | 9 +-- src/test/ui/wf/wf-trait-fn-ret.stderr | 9 +-- .../ui/wf/wf-trait-fn-where-clause.stderr | 9 +-- 42 files changed, 261 insertions(+), 392 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 82811826ae7e7..ef3dcf1587301 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -219,9 +219,17 @@ fn check_associated_item( ty::AssocKind::Method => { let sig = fcx.tcx.fn_sig(item.def_id); let sig = fcx.normalize_associated_types_in(span, &sig); - check_fn_or_method(tcx, fcx, span, sig, item.def_id, &mut implied_bounds); - let sig_if_method = sig_if_method.expect("bad signature for method"); - check_method_receiver(fcx, sig_if_method, &item, self_ty); + let hir_sig = sig_if_method.expect("bad signature for method"); + check_fn_or_method( + tcx, + fcx, + item.ident.span, + sig, + hir_sig, + item.def_id, + &mut implied_bounds, + ); + check_method_receiver(fcx, hir_sig, &item, self_ty); } ty::AssocKind::Type => { if item.defaultness.has_value() { @@ -364,7 +372,11 @@ fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { let sig = fcx.tcx.fn_sig(def_id); let sig = fcx.normalize_associated_types_in(item.span, &sig); let mut implied_bounds = vec![]; - check_fn_or_method(tcx, fcx, item.span, sig, def_id, &mut implied_bounds); + let hir_sig = match &item.kind { + ItemKind::Fn(sig, ..) => sig, + _ => bug!("expected `ItemKind::Fn`, found `{:?}`", item.kind), + }; + check_fn_or_method(tcx, fcx, item.ident.span, sig, hir_sig, def_id, &mut implied_bounds); implied_bounds }) } @@ -609,18 +621,23 @@ fn check_fn_or_method<'fcx, 'tcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, sig: ty::PolyFnSig<'tcx>, + hir_sig: &hir::FnSig<'_>, def_id: DefId, implied_bounds: &mut Vec>, ) { let sig = fcx.normalize_associated_types_in(span, &sig); let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - for input_ty in sig.inputs() { + for (input_ty, span) in sig.inputs().iter().zip(hir_sig.decl.inputs.iter().map(|t| t.span)) { fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::ReturnType); + fcx.register_wf_obligation( + sig.output(), + hir_sig.decl.output.span(), + ObligationCauseCode::ReturnType, + ); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 5303a09644d50..33fe8a3124083 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -9,74 +9,47 @@ LL | impl Case1 for S1 { error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` is not an iterator +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` + | | + | `<::C as std::iter::Iterator>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` + | | + | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | fn assume_case1() { - | ^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` - | _| - | | -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely +LL | fn assume_case1() { + | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` + | | + | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | -LL | trait Case1 { - | ----------- required by `Case1` +LL | trait Case1 { + | ----------- required by `Case1` ... -LL | / fn assume_case1() { -LL | | -LL | | -LL | | -... | -LL | | assert_c::<_, _, _, T::C>(); -LL | | } - | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` +LL | fn assume_case1() { + | ^^^^^^^^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` diff --git a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr index 3c8f637e13369..0834014b31c35 100644 --- a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr +++ b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr @@ -1,17 +1,13 @@ error[E0277]: `F` cannot be sent between threads safely - --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:1 + --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:22 | -LL | struct X where F: FnOnce() + 'static + Send { - | ---------------------------------------------- required by `X` +LL | struct X where F: FnOnce() + 'static + Send { + | ---------------------------------------------- required by `X` ... -LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { - | ^ - help: consider further restricting type parameter `F`: `, F: std::marker::Send` - | _| - | | -LL | | -LL | | return X { field: blk }; -LL | | } - | |_^ `F` cannot be sent between threads safely +LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { + | ^^^^ - help: consider further restricting type parameter `F`: `, F: std::marker::Send` + | | + | `F` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `F` diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 5c4d6d53c4626..6eaf6e4a8aad1 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/E0038.rs:5:1 + --> $DIR/E0038.rs:5:16 | LL | fn foo(&self) -> Self; | --- method `foo` references the `Self` type in its parameters or return type ... LL | fn call_foo(x: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 54e64e2fc1bd4..a2409621db310 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -1,37 +1,37 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object | = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `NonObjectSafe2` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 | LL | fn static_fn() {} | --------- associated function `static_fn` has no `self` parameter ... LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object error[E0038]: the trait `NonObjectSafe3` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 | LL | fn foo(&self); | --- method `foo` has generic type parameters ... LL | fn takes_non_object_safe_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object error[E0038]: the trait `NonObjectSafe4` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:1 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 | LL | fn foo(&self, &Self); | --- method `foo` references the `Self` type in its parameters or return type ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index d0d75f3cc6336..ccb1c9bcc7f4e 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -25,16 +25,13 @@ LL | type Item<'a> where T: 'a = as Iterator>::Item = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` - --> $DIR/iterable.rs:19:5 + --> $DIR/iterable.rs:19:30 | -LL | trait Iterable { - | -------------- required by `Iterable` +LL | trait Iterable { + | -------------- required by `Iterable` ... -LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { -LL | | -LL | | self.iter() -LL | | } - | |_____^ expected associated type, found reference +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^^^^^^^^^^^^^ expected associated type, found reference | = note: expected associated type ` as Iterable>::Item<'_>` found reference `&T` @@ -42,16 +39,13 @@ LL | | } = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` - --> $DIR/iterable.rs:31:5 + --> $DIR/iterable.rs:31:30 | -LL | trait Iterable { - | -------------- required by `Iterable` +LL | trait Iterable { + | -------------- required by `Iterable` ... -LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { -LL | | -LL | | self.iter() -LL | | } - | |_____^ expected associated type, found reference +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^^^^^^^^^^^^^ expected associated type, found reference | = note: expected associated type `<[T] as Iterable>::Item<'_>` found reference `&T` diff --git a/src/test/ui/issues/issue-18919.stderr b/src/test/ui/issues/issue-18919.stderr index 87528652bd482..c8b9045efe6a0 100644 --- a/src/test/ui/issues/issue-18919.stderr +++ b/src/test/ui/issues/issue-18919.stderr @@ -1,10 +1,8 @@ error[E0277]: the size for values of type `dyn for<'r> std::ops::Fn(&'r isize) -> isize` cannot be known at compilation time - --> $DIR/issue-18919.rs:3:1 + --> $DIR/issue-18919.rs:3:15 | -LL | / fn ho_func(f: Option) { -LL | | -LL | | } - | |_^ doesn't have a size known at compile-time +LL | fn ho_func(f: Option) { + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `dyn for<'r> std::ops::Fn(&'r isize) -> isize` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index d5e7092801ecd..0c59486b416b8 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/issue-18959.rs:11:1 + --> $DIR/issue-18959.rs:11:11 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | --- method `foo` has generic type parameters ... LL | fn foo(b: &dyn Bar) { - | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr index 31376f2d1be0f..7c4115b4d3f7c 100644 --- a/src/test/ui/issues/issue-20005.stderr +++ b/src/test/ui/issues/issue-20005.stderr @@ -1,16 +1,14 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-20005.rs:8:5 + --> $DIR/issue-20005.rs:8:8 | -LL | trait From { - | --------------- required by `From` +LL | trait From { + | --------------- required by `From` ... -LL | / fn to( -LL | | self -LL | | ) -> >::Result where Dst: From { - | | - help: consider further restricting `Self`: `, Self: std::marker::Sized` -LL | | From::from(self) -LL | | } - | |_____^ doesn't have a size known at compile-time +LL | fn to( + | ^^ doesn't have a size known at compile-time +LL | self +LL | ) -> >::Result where Dst: From { + | - help: consider further restricting `Self`: `, Self: std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 6ecb4e736acd9..7aec4a847c9d4 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -151,16 +151,13 @@ LL | | } = note: required because of the requirements on the impl of `Foo` for `NoData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:10:3 + --> $DIR/issue-20413.rs:10:6 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / fn answer(self) { -LL | | -LL | | let val: NoData = NoData; -LL | | } - | |___^ +LL | fn answer(self) { + | ^^^^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-20433.stderr b/src/test/ui/issues/issue-20433.stderr index f7cb28edd6216..abd2290952baf 100644 --- a/src/test/ui/issues/issue-20433.stderr +++ b/src/test/ui/issues/issue-20433.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/issue-20433.rs:6:5 + --> $DIR/issue-20433.rs:6:18 | LL | fn iceman(c: Vec<[i32]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `[i32]` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index a4ea1cd9834c8..a785a956ca9f5 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -61,16 +61,10 @@ LL | | } | |_____^ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 @@ -89,30 +83,18 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `Publisher<'_>` found `Publisher<'_>` error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 @@ -131,16 +113,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `Publisher<'_>` found `Publisher<'_>` diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index b1536bd8ddb0a..ebaef10cfef5b 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,17 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-21974.rs:10:1 + --> $DIR/issue-21974.rs:10:4 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) -LL | | where &'a T : Foo, -LL | | &'b T : Foo -LL | | { -LL | | x.foo(); -LL | | y.foo(); -LL | | } - | |_^ cannot infer type for reference `&'a T` +LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/issues/issue-23281.stderr b/src/test/ui/issues/issue-23281.stderr index f1def47458368..68a90c6d80f3b 100644 --- a/src/test/ui/issues/issue-23281.stderr +++ b/src/test/ui/issues/issue-23281.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `(dyn std::ops::Fn() + 'static)` cannot be known at compilation time - --> $DIR/issue-23281.rs:4:5 + --> $DIR/issue-23281.rs:4:27 | LL | pub fn function(funs: Vec ()>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn() + 'static)` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr index 3eb1f1b4f6e81..a1a6960a3f7ae 100644 --- a/src/test/ui/issues/issue-24204.stderr +++ b/src/test/ui/issues/issue-24204.stderr @@ -1,11 +1,11 @@ error[E0271]: type mismatch resolving `<::A as MultiDispatch>::O == T` - --> $DIR/issue-24204.rs:14:1 + --> $DIR/issue-24204.rs:14:4 | LL | trait Trait: Sized { | ------------------ required by `Trait` ... LL | fn test>(b: i32) -> T where T::A: MultiDispatch { T::new(b) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type + | ^^^^ expected type parameter `T`, found associated type | = note: expected type parameter `T` found associated type `<::A as MultiDispatch>::O` diff --git a/src/test/ui/issues/issue-27942.stderr b/src/test/ui/issues/issue-27942.stderr index d290b176161be..6ce0fa37a8840 100644 --- a/src/test/ui/issues/issue-27942.stderr +++ b/src/test/ui/issues/issue-27942.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:5 + --> $DIR/issue-27942.rs:5:25 | LL | fn select(&self) -> BufferViewHandle; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected type `Resources<'_>` found type `Resources<'a>` @@ -18,10 +18,10 @@ LL | pub trait Buffer<'a, R: Resources<'a>> { | ^^ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:5 + --> $DIR/issue-27942.rs:5:25 | LL | fn select(&self) -> BufferViewHandle; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected type `Resources<'_>` found type `Resources<'a>` diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index 7b823f012b9f9..3154c502625a6 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -13,87 +13,69 @@ LL | foo: &'static T | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 | LL | trait X: Sized { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 | LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ error[E0309]: the parameter type `L` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 | -LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^ - help: consider adding an explicit lifetime bound `L: 'a`... - | _____| - | | -LL | | -LL | | } - | |_____^ +LL | fn baz<'a, L, M: X<&'a Nested>>() { + | ^^^ - help: consider adding an explicit lifetime bound `L: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 | -LL | / fn baz<'a, L, M: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | fn baz<'a, L, M: X<&'a Nested>>() { + | ^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 | -LL | impl Nested { - | - help: consider adding an explicit lifetime bound `K: 'a`... -LL | / fn generic_in_parent<'a, L: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | impl Nested { + | - help: consider adding an explicit lifetime bound `K: 'a`... +LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { + | ^^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 | -LL | / fn generic_in_parent<'a, L: X<&'a Nested>>() { -LL | | -LL | | } - | |_____^ +LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { + | ^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `M` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 | -LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^ -- help: consider adding an explicit lifetime bound `M: 'a`... - | _____| - | | -LL | | -LL | | } - | |_____^ +LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { + | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 | -LL | / fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { -LL | | -LL | | } - | |_____^ +LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { + | ^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 67ef7a62f1052..b67b0e4f40e8c 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-associated-consts.rs:12:1 + --> $DIR/object-safety-associated-consts.rs:12:30 | LL | const X: usize; | - the trait cannot contain associated consts like `X` ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 8ae9236a5c322..2469467f084a3 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:18:1 + --> $DIR/object-safety-generics.rs:18:30 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:24:1 + --> $DIR/object-safety-generics.rs:24:39 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters ... LL | fn make_bar_explicit(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 297cd876187fe..2123e306b16a4 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:22:1 + --> $DIR/object-safety-mentions-Self.rs:22:30 | LL | fn bar(&self, x: &Self); | --- method `bar` references the `Self` type in its parameters or return type ... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:28:1 + --> $DIR/object-safety-mentions-Self.rs:28:30 | LL | fn baz(&self) -> Self; | --- method `baz` references the `Self` type in its parameters or return type ... LL | fn make_baz(t: &T) -> &dyn Baz { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object + | ^^^^^^^^ the trait `Baz` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 1641ce577719e..099876c562aec 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-no-static.rs:12:1 + --> $DIR/object-safety-no-static.rs:12:18 | LL | fn foo() {} | --- associated function `foo` has no `self` parameter ... LL | fn diverges() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 1e1d2bf64c427..28fb4f36115f0 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized-2.rs:14:1 + --> $DIR/object-safety-sized-2.rs:14:30 | LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 1a67e79e83d32..0f284fc85073e 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:12:1 + --> $DIR/object-safety-sized.rs:12:30 | LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ the trait `Bar` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr index ad555efadf7ec..ad300f38ca5c1 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -1,12 +1,8 @@ error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references - --> $DIR/regions-free-region-ordering-callee-4.rs:5:1 + --> $DIR/regions-free-region-ordering-callee-4.rs:5:4 | -LL | / fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { -LL | | -LL | | // Do not infer ordering from closure argument types. -LL | | let z: Option<&'a &'b usize> = None; -LL | | } - | |_^ +LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { + | ^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14 --> $DIR/regions-free-region-ordering-callee-4.rs:5:14 diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index c4ca7e970749c..6470ebf541b5b 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -1,11 +1,8 @@ error[E0491]: in type `&'x (dyn for<'z> Trait1<>::Foo> + 'x)`, reference has a longer lifetime than the data it references - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 | -LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) -LL | | -LL | | { -LL | | } - | |_^ +LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'x` as defined on the function body at 21:11 --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:11 diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr index cc2245f81ace5..c35516d2c0871 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -67,15 +67,10 @@ LL | | } found `Project<'_, '_>` error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + --> $DIR/regions-normalize-in-where-clause-list.rs:22:4 | -LL | / fn bar<'a, 'b>() -LL | | -LL | | -LL | | where <() as Project<'a, 'b>>::Item : Eq -LL | | { -LL | | } - | |_^ +LL | fn bar<'a, 'b>() + | ^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8... --> $DIR/regions-normalize-in-where-clause-list.rs:22:8 @@ -88,15 +83,10 @@ note: ...but the lifetime must also be valid for the lifetime `'b` as defined on LL | fn bar<'a, 'b>() | ^^ note: ...so that the types are compatible - --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + --> $DIR/regions-normalize-in-where-clause-list.rs:22:4 | -LL | / fn bar<'a, 'b>() -LL | | -LL | | -LL | | where <() as Project<'a, 'b>>::Item : Eq -LL | | { -LL | | } - | |_^ +LL | fn bar<'a, 'b>() + | ^^^ = note: expected `Project<'a, 'b>` found `Project<'_, '_>` diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 63ac11dc8ae01..1d6b378b9c8a7 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object - --> $DIR/issue-3907-2.rs:11:1 + --> $DIR/issue-3907-2.rs:11:12 | LL | fn bar(_x: Foo) {} - | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object + | ^^^ the trait `issue_3907::Foo` cannot be made into an object | = note: associated function `bar` has no `self` parameter diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr index 3c68d461f80d6..a2253021a7f1f 100644 --- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr +++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr @@ -1,20 +1,20 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:13:1 + --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:13:15 | LL | struct Foo { | ------------------- required by `Foo` ... LL | fn explode(x: Foo) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u32` + | ^^^^^^^^ the trait `Trait` is not implemented for `u32` error[E0277]: the trait bound `f32: Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:16:1 + --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:16:14 | LL | enum Bar { | ----------------- required by `Bar` ... LL | fn kaboom(y: Bar) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `Trait` is not implemented for `f32` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr index 2f2c903a45c19..c5a7746afdfdb 100644 --- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr +++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-xc.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `usize: trait_bounds_on_structs_and_enums_xc::Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:7:1 + --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:7:15 | LL | fn explode(x: Foo) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `usize` + | ^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `usize` | = note: required by `trait_bounds_on_structs_and_enums_xc::Foo` error[E0277]: the trait bound `f32: trait_bounds_on_structs_and_enums_xc::Trait` is not satisfied - --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:10:1 + --> $DIR/trait-bounds-on-structs-and-enums-xc.rs:10:14 | LL | fn kaboom(y: Bar) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `trait_bounds_on_structs_and_enums_xc::Trait` is not implemented for `f32` | = note: required by `trait_bounds_on_structs_and_enums_xc::Bar` diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index a4d9a672154fb..8cc6f7c303787 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,10 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:1 + --> $DIR/generic_duplicate_lifetime_param.rs:7:4 | -LL | / fn one<'a>(t: &'a ()) -> Two<'a, 'a> { -LL | | t -LL | | } - | |_^ +LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { + | ^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_lifetime_param.rs:5:10 diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 4fc0285509149..4a04b71d82f71 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,17 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-40294.rs:5:1 + --> $DIR/issue-40294.rs:5:4 | -LL | trait Foo: Sized { - | ---------------- required by `Foo` +LL | trait Foo: Sized { + | ---------------- required by `Foo` ... -LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) -LL | | where &'a T : Foo, -LL | | &'b T : Foo -LL | | { -LL | | x.foo(); -LL | | y.foo(); -LL | | } - | |_^ cannot infer type for reference `&'a T` +LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 9b8b04a7b86a3..5d41dc77d8bc2 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -1,32 +1,29 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-fn-where-clause.rs:8:1 + --> $DIR/wf-fn-where-clause.rs:8:4 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | fn foo() where T: ExtraCopy - | ^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | fn foo() where T: ExtraCopy + | ^^^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time - --> $DIR/wf-fn-where-clause.rs:12:1 + --> $DIR/wf-fn-where-clause.rs:12:4 | LL | fn bar() where Vec:, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)` = note: to learn more, visit = note: required by `std::vec::Vec` error[E0038]: the trait `std::marker::Copy` cannot be made into an object - --> $DIR/wf-fn-where-clause.rs:12:1 + --> $DIR/wf-fn-where-clause.rs:12:4 | LL | fn bar() where Vec:, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object + | ^^^ the trait `std::marker::Copy` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr index 3798ba1ec6e75..b8e88de54c2f1 100644 --- a/src/test/ui/wf/wf-in-fn-arg.stderr +++ b/src/test/ui/wf/wf-in-fn-arg.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-arg.rs:10:1 + --> $DIR/wf-in-fn-arg.rs:10:14 | -LL | struct MustBeCopy { - | ------------------------- required by `MustBeCopy` +LL | struct MustBeCopy { + | ------------------------- required by `MustBeCopy` ... -LL | fn bar(_: &MustBeCopy) - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | fn bar(_: &MustBeCopy) + | - ^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr index 2e46ce4900033..6ca1626d3aef5 100644 --- a/src/test/ui/wf/wf-in-fn-ret.stderr +++ b/src/test/ui/wf/wf-in-fn-ret.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-ret.rs:10:1 + --> $DIR/wf-in-fn-ret.rs:10:16 | -LL | struct MustBeCopy { - | ------------------------- required by `MustBeCopy` +LL | struct MustBeCopy { + | ------------------------- required by `MustBeCopy` ... -LL | fn bar() -> MustBeCopy - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | fn bar() -> MustBeCopy + | - ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr index 979802dec4998..e1a281626b9b7 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-where-clause.rs:9:1 + --> $DIR/wf-in-fn-where-clause.rs:9:4 | -LL | trait MustBeCopy { - | ------------------------ required by `MustBeCopy` +LL | trait MustBeCopy { + | ------------------------ required by `MustBeCopy` ... -LL | / fn bar() -LL | | where T: MustBeCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | fn bar() + | ^^^ the trait `std::marker::Copy` is not implemented for `U` +LL | where T: MustBeCopy + | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr index 21f825ac9ef9a..16079c8197cb1 100644 --- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-method-where-clause.rs:12:5 + --> $DIR/wf-inherent-impl-method-where-clause.rs:12:8 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` ... -LL | impl Foo { - | - help: consider restricting this bound: `U: std::marker::Copy` -LL | / fn foo(self) where T: ExtraCopy -LL | | {} - | |______^ the trait `std::marker::Copy` is not implemented for `U` +LL | impl Foo { + | - help: consider restricting this bound: `U: std::marker::Copy` +LL | fn foo(self) where T: ExtraCopy + | ^^^ the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr index 9f3545b9c6a6b..6a97d31cf3e65 100644 --- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr @@ -1,18 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-arg.rs:11:5 + --> $DIR/wf-trait-default-fn-arg.rs:11:22 | -LL | struct Bar { value: Box } - | ----------------------- required by `Bar` +LL | struct Bar { value: Box } + | ----------------------- required by `Bar` ... -LL | fn bar(&self, x: &Bar) { - | ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self, x: &Bar) { + | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.stderr b/src/test/ui/wf/wf-trait-default-fn-ret.stderr index e32630a5a4a40..36c1e486269f6 100644 --- a/src/test/ui/wf/wf-trait-default-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-ret.stderr @@ -1,19 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-ret.rs:11:5 + --> $DIR/wf-trait-default-fn-ret.rs:11:22 | -LL | struct Bar { value: Box } - | ----------------------- required by `Bar` +LL | struct Bar { value: Box } + | ----------------------- required by `Bar` ... -LL | fn bar(&self) -> Bar { - | ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | loop { } -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self) -> Bar { + | ^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr index a443ff1bb6396..984237ce3b497 100644 --- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr @@ -1,18 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-where-clause.rs:11:5 + --> $DIR/wf-trait-default-fn-where-clause.rs:11:8 | -LL | trait Bar { } - | ---------------------- required by `Bar` +LL | trait Bar { } + | ---------------------- required by `Bar` ... -LL | fn bar(&self) where A: Bar { - | ^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | _____| - | | -LL | | -LL | | // -LL | | // Here, Eq ought to be implemented. -LL | | } - | |_____^ the trait `std::cmp::Eq` is not implemented for `Self` +LL | fn bar(&self) where A: Bar { + | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr index 42a28ee676373..69e2ab72912d4 100644 --- a/src/test/ui/wf/wf-trait-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-fn-arg.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-arg.rs:10:5 + --> $DIR/wf-trait-fn-arg.rs:10:22 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self, x: &Bar); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr index 7ec4dbe0056b4..bfc6265662e48 100644 --- a/src/test/ui/wf/wf-trait-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-fn-ret.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-ret.rs:10:5 + --> $DIR/wf-trait-fn-ret.rs:10:22 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) -> &Bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr index 256edb5b2ca1d..34cda077963b5 100644 --- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr @@ -1,14 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-where-clause.rs:10:5 + --> $DIR/wf-trait-fn-where-clause.rs:10:8 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error From 1c9242f83fdea3e4c7a452d1453370ee81a900af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 14:53:37 -0800 Subject: [PATCH 0806/1253] Point at `Sized` bound --- src/librustc/traits/object_safety.rs | 40 +++++++++++++++---- ...ature-gate-object_safe_for_dispatch.stderr | 6 +++ src/test/ui/issues/issue-20692.stderr | 6 +++ src/test/ui/issues/issue-50781.stderr | 3 +- .../object-safety-sized.curr.stderr | 3 ++ ...fety-sized.object_safe_for_dispatch.stderr | 3 ++ .../wf/wf-convert-unsafe-trait-obj-box.stderr | 9 +++++ .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 9 +++++ .../ui/wf/wf-unsafe-trait-obj-match.stderr | 6 +++ 9 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 15f81bb3f47ed..bca0ecb1e79dc 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -26,7 +26,7 @@ use std::iter::{self}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. - SizedSelf, + SizedSelf(Span), /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). @@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation { impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { - ObjectSafetyViolation::SizedSelf => { + ObjectSafetyViolation::SizedSelf(_) => { "the trait cannot require that `Self : Sized`".into() } ObjectSafetyViolation::SupertraitSelf => { @@ -80,6 +80,7 @@ impl ObjectSafetyViolation { // diagnostics use a `note` instead of a `span_label`. match *self { ObjectSafetyViolation::AssocConst(_, span) + | ObjectSafetyViolation::SizedSelf(span) | ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => { @@ -179,7 +180,7 @@ fn object_safety_violations_for_trait( { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.struct_span_lint_hir( + let mut err = tcx.struct_span_lint_hir( WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, *span, @@ -187,9 +188,12 @@ fn object_safety_violations_for_trait( "the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id) ), - ) - .note(&violation.error_msg()) - .emit(); + ); + match violation.span() { + Some(span) => err.span_label(span, violation.error_msg()), + None => err.note(&violation.error_msg()), + }; + err.emit(); false } else { true @@ -199,7 +203,8 @@ fn object_safety_violations_for_trait( // Check the trait itself. if trait_has_sized_self(tcx, trait_def_id) { - violations.push(ObjectSafetyViolation::SizedSelf); + let span = get_sized_bound(tcx, trait_def_id); + violations.push(ObjectSafetyViolation::SizedSelf(span)); } if predicates_reference_self(tcx, trait_def_id, false) { violations.push(ObjectSafetyViolation::SupertraitSelf); @@ -219,6 +224,27 @@ fn object_safety_violations_for_trait( violations } +fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span { + tcx.hir() + .get_if_local(trait_def_id) + .and_then(|node| match node { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds + .iter() + .filter_map(|b| match b { + hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + if Some(trait_ref.trait_ref.trait_def_id()) + == tcx.lang_items().sized_trait() => + { + Some(trait_ref.span) + } + _ => None, + }) + .next(), + _ => None, + }) + .unwrap_or(DUMMY_SP) +} + fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index a2409621db310..de362e1cef0fd 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | +LL | trait NonObjectSafe1: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object | @@ -36,6 +39,9 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc { error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | +LL | trait NonObjectSafe1: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object | diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 06c83f65be26c..4757742a707b1 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | +LL | trait Array: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object | @@ -9,6 +12,9 @@ LL | &dyn Array; error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | +LL | trait Array: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let _ = x | ^ the trait `Array` cannot be made into an object | diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index cb6ca24c7124a..c161e9efd1261 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -2,7 +2,7 @@ error: the trait `X` cannot be made into an object --> $DIR/issue-50781.rs:6:8 | LL | fn foo(&self) where Self: Trait; - | ^^^ + | ^^^ method `foo` references the `Self` type in where clauses | note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 @@ -11,7 +11,6 @@ LL | #![deny(where_clauses_object_safety)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 - = note: method `foo` references the `Self` type in where clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 0f284fc85073e..be0a2519a469b 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | +LL | trait Bar : Sized { + | ----- the trait cannot require that `Self : Sized` +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object | diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 3d88dfc40ed38..c20ddee54c07e 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | +LL | trait Bar : Sized { + | ----- the trait cannot require that `Self : Sized` +... LL | t | ^ the trait `Bar` cannot be made into an object | diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 0b63aef2bce10..4c033cfcd898b 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | @@ -11,6 +14,9 @@ LL | let t_box: Box = Box::new(S); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | @@ -21,6 +27,9 @@ LL | takes_box(Box::new(S)); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 7aeefd731fb28..ba3792c362e86 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -1,6 +1,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object | @@ -11,6 +14,9 @@ LL | let t: &dyn Trait = &S; error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object | @@ -21,6 +27,9 @@ LL | takes_trait(&S); error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object | diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 594fad4138505..a0082578d4d06 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -15,6 +15,9 @@ LL | | } error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object | @@ -25,6 +28,9 @@ LL | Some(()) => &S, error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | +LL | trait Trait: Sized {} + | ----- the trait cannot require that `Self : Sized` +... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | From d72bcdb42cc10a20c2eef49e5f8cd2782f44b922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 17:27:37 -0800 Subject: [PATCH 0807/1253] When object unsafe trait uses itself in associated item suggest using `Self` --- src/librustc_typeck/check/wfcheck.rs | 69 ++++++++++++++++++- .../object-unsafe-trait-should-use-self.rs | 16 +++++ ...object-unsafe-trait-should-use-self.stderr | 47 +++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ef3dcf1587301..faeaedce8d00d 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -10,10 +10,10 @@ use rustc::ty::{ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; -use rustc_span::symbol::sym; +use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use syntax::ast; @@ -176,9 +176,74 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None, }; + check_bare_self_trait_by_name(tcx, &trait_item); check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } +fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { + match ty.kind { + hir::TyKind::TraitObject([trait_ref], ..) => { + let mut p = trait_ref.trait_ref.path.segments.iter().map(|s| s.ident); + match (p.next(), p.next()) { + (Some(ident), None) => ident == trait_name, + _ => false, + } + } + _ => false, + } +} + +/// Detect when an object unsafe trait is referring to itself in one of its associated items. +/// When this is done, suggest using `Self` instead. +fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { + let (trait_name, trait_def_id) = match tcx.hir().get(tcx.hir().get_parent_item(item.hir_id)) { + hir::Node::Item(item) => match item.kind { + hir::ItemKind::Trait(..) => (item.ident, tcx.hir().local_def_id(item.hir_id)), + _ => return, + }, + _ => return, + }; + let mut trait_should_be_self = vec![]; + match &item.kind { + hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty)) + if could_be_self(trait_name, ty) => + { + trait_should_be_self.push(ty.span) + } + hir::TraitItemKind::Method(sig, _) => { + for ty in sig.decl.inputs { + if could_be_self(trait_name, ty) { + trait_should_be_self.push(ty.span); + } + } + match sig.decl.output { + hir::FunctionRetTy::Return(ty) if could_be_self(trait_name, ty) => { + trait_should_be_self.push(ty.span); + } + _ => {} + } + } + _ => {} + } + if !trait_should_be_self.is_empty() { + if rustc::traits::object_safety_violations(tcx, trait_def_id).is_empty() { + return; + } + let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect(); + let mut err = tcx.sess.struct_span_err( + trait_should_be_self, + "associated item referring to unboxed trait object for its own trait", + ); + err.span_label(trait_name.span, "in this trait"); + err.multipart_suggestion( + "you might have meant to use `Self` to refer to the materialized type", + sugg, + Applicability::MachineApplicable, + ); + err.emit(); + } +} + pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let impl_item = tcx.hir().expect_impl_item(hir_id); diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs new file mode 100644 index 0000000000000..75f99075eb18f --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.rs @@ -0,0 +1,16 @@ +#![allow(bare_trait_objects)] +trait A: Sized { + fn f(a: A) -> A; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `A` cannot be made into an object +} +trait B { + fn f(a: B) -> B; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `B` cannot be made into an object +} +trait C { + fn f(&self, a: C) -> C; +} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr new file mode 100644 index 0000000000000..70d069d2aa29b --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -0,0 +1,47 @@ +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 + | +LL | trait A: Sized { + | - in this trait +LL | fn f(a: A) -> A; + | ^ ^ + | +help: you might have meant to use `Self` to refer to the materialized type + | +LL | fn f(a: Self) -> Self; + | ^^^^ ^^^^ + +error[E0038]: the trait `A` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 + | +LL | trait A: Sized { + | ----- the trait cannot require that `Self : Sized` +LL | fn f(a: A) -> A; + | ^ the trait `A` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 + | +LL | trait B { + | - in this trait +LL | fn f(a: B) -> B; + | ^ ^ + | +help: you might have meant to use `Self` to refer to the materialized type + | +LL | fn f(a: Self) -> Self; + | ^^^^ ^^^^ + +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 + | +LL | fn f(a: B) -> B; + | - ^ the trait `B` cannot be made into an object + | | + | associated function `f` has no `self` parameter + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0038`. From 0eb29d1a441a47ea45970c01332ebe157dba7039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 19 Jan 2020 19:22:15 -0800 Subject: [PATCH 0808/1253] fix test --- ...bject-unsafe-trait-in-return-position-dyn-trait.stderr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 0c8d267c13434..ff4bfc30a4a62 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -1,20 +1,20 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:1 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | LL | fn foo() -> Self; | --- associated function `foo` has no `self` parameter ... LL | fn car() -> dyn NotObjectSafe { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:1 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 | LL | fn foo() -> Self; | --- associated function `foo` has no `self` parameter ... LL | fn cat() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object error: aborting due to 2 previous errors From d137b7ac1173e3bbed6a3d4dfb02c741b64077db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 25 Jan 2020 14:28:23 -0800 Subject: [PATCH 0809/1253] review comments --- src/librustc_typeck/check/wfcheck.rs | 27 ++++++++++--------- ...object-unsafe-trait-should-use-self.stderr | 4 +-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index faeaedce8d00d..214e7d066eabc 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -176,7 +176,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None, }; - check_bare_self_trait_by_name(tcx, &trait_item); + check_object_unsafe_self_trait_by_name(tcx, &trait_item); check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } @@ -195,7 +195,7 @@ fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { /// Detect when an object unsafe trait is referring to itself in one of its associated items. /// When this is done, suggest using `Self` instead. -fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { +fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { let (trait_name, trait_def_id) = match tcx.hir().get(tcx.hir().get_parent_item(item.hir_id)) { hir::Node::Item(item) => match item.kind { hir::ItemKind::Trait(..) => (item.ident, tcx.hir().local_def_id(item.hir_id)), @@ -230,17 +230,18 @@ fn check_bare_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { return; } let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect(); - let mut err = tcx.sess.struct_span_err( - trait_should_be_self, - "associated item referring to unboxed trait object for its own trait", - ); - err.span_label(trait_name.span, "in this trait"); - err.multipart_suggestion( - "you might have meant to use `Self` to refer to the materialized type", - sugg, - Applicability::MachineApplicable, - ); - err.emit(); + tcx.sess + .struct_span_err( + trait_should_be_self, + "associated item referring to unboxed trait object for its own trait", + ) + .span_label(trait_name.span, "in this trait") + .multipart_suggestion( + "you might have meant to use `Self` to refer to the implementing type", + sugg, + Applicability::MachineApplicable, + ) + .emit(); } } diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 70d069d2aa29b..f1c1a6bb9728b 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -6,7 +6,7 @@ LL | trait A: Sized { LL | fn f(a: A) -> A; | ^ ^ | -help: you might have meant to use `Self` to refer to the materialized type +help: you might have meant to use `Self` to refer to the implementing type | LL | fn f(a: Self) -> Self; | ^^^^ ^^^^ @@ -29,7 +29,7 @@ LL | trait B { LL | fn f(a: B) -> B; | ^ ^ | -help: you might have meant to use `Self` to refer to the materialized type +help: you might have meant to use `Self` to refer to the implementing type | LL | fn f(a: Self) -> Self; | ^^^^ ^^^^ From 4b2f1db6e464b74067557b1748e79cb11a2c5e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 12:59:04 -0800 Subject: [PATCH 0810/1253] Tweak `Self: Sized` restriction diagnostic output --- src/librustc/traits/error_reporting/mod.rs | 19 ++++-- src/librustc/traits/object_safety.rs | 63 ++++++++++--------- ...ature-gate-object_safe_for_dispatch.stderr | 4 -- src/test/ui/issues/issue-20692.rs | 2 +- src/test/ui/issues/issue-20692.stderr | 15 ++--- .../kindck-inherited-copy-bound.curr.stderr | 9 ++- ...copy-bound.object_safe_for_dispatch.stderr | 4 +- .../object-safety-sized.curr.stderr | 2 - ...fety-sized.object_safe_for_dispatch.stderr | 1 - ...object-unsafe-trait-should-use-self.stderr | 2 - .../wf/wf-convert-unsafe-trait-obj-box.stderr | 3 - .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 3 - .../ui/wf/wf-unsafe-trait-obj-match.stderr | 2 - 13 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 28084c9d4ac49..f15fa779534e0 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1046,11 +1046,22 @@ pub fn report_object_safety_error( let mut reported_violations = FxHashSet::default(); for violation in violations { + if let ObjectSafetyViolation::SizedSelf(sp) = &violation { + if !sp.is_empty() { + // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations + // with a `Span`. + reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into())); + } + } if reported_violations.insert(violation.clone()) { - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; + let spans = violation.spans(); + if spans.is_empty() { + err.note(&violation.error_msg()); + } else { + for span in spans { + err.span_label(span, violation.error_msg()); + } + } } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index bca0ecb1e79dc..8ceefb0abf038 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -18,15 +18,16 @@ use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; +use smallvec::SmallVec; use syntax::ast; use std::borrow::Cow; use std::iter::{self}; -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. - SizedSelf(Span), + SizedSelf(SmallVec<[Span; 1]>), /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). @@ -75,18 +76,18 @@ impl ObjectSafetyViolation { } } - pub fn span(&self) -> Option { + pub fn spans(&self) -> SmallVec<[Span; 1]> { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. - match *self { + match self { + ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), ObjectSafetyViolation::AssocConst(_, span) - | ObjectSafetyViolation::SizedSelf(span) | ObjectSafetyViolation::Method(_, _, span) - if span != DUMMY_SP => + if *span != DUMMY_SP => { - Some(span) + vec![*span].into() } - _ => None, + _ => vec![].into(), } } } @@ -189,10 +190,14 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; + let spans = violation.spans(); + if spans.is_empty() { + err.note(&violation.error_msg()); + } else { + for span in spans { + err.span_label(span, violation.error_msg()); + } + } err.emit(); false } else { @@ -203,8 +208,9 @@ fn object_safety_violations_for_trait( // Check the trait itself. if trait_has_sized_self(tcx, trait_def_id) { - let span = get_sized_bound(tcx, trait_def_id); - violations.push(ObjectSafetyViolation::SizedSelf(span)); + // We don't want to include the requirement from `Sized` itself to be `Sized` in the list. + let spans = get_sized_bounds(tcx, trait_def_id); + violations.push(ObjectSafetyViolation::SizedSelf(spans)); } if predicates_reference_self(tcx, trait_def_id, false) { violations.push(ObjectSafetyViolation::SupertraitSelf); @@ -224,25 +230,26 @@ fn object_safety_violations_for_trait( violations } -fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span { +fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { tcx.hir() .get_if_local(trait_def_id) .and_then(|node| match node { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds - .iter() - .filter_map(|b| match b { - hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) - if Some(trait_ref.trait_ref.trait_def_id()) - == tcx.lang_items().sized_trait() => - { - Some(trait_ref.span) - } - _ => None, - }) - .next(), + hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => Some( + bounds + .iter() + .filter_map(|b| match b { + hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) => + { + Some(trait_ref.span) + } + _ => None, + }) + .collect::>(), + ), _ => None, }) - .unwrap_or(DUMMY_SP) + .unwrap_or_else(SmallVec::new) } fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index de362e1cef0fd..237c22d3bf09a 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -6,8 +6,6 @@ LL | trait NonObjectSafe1: Sized {} ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `NonObjectSafe2` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 @@ -44,8 +42,6 @@ LL | trait NonObjectSafe1: Sized {} ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to 5 previous errors diff --git a/src/test/ui/issues/issue-20692.rs b/src/test/ui/issues/issue-20692.rs index 2a05bba7b1632..1cb2d8c7302a0 100644 --- a/src/test/ui/issues/issue-20692.rs +++ b/src/test/ui/issues/issue-20692.rs @@ -1,4 +1,4 @@ -trait Array: Sized {} +trait Array: Sized + Copy {} fn f(x: &T) { let _ = x diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 4757742a707b1..62efdfb2e91bf 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -1,24 +1,25 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | -LL | trait Array: Sized {} - | ----- the trait cannot require that `Self : Sized` +LL | trait Array: Sized + Copy {} + | ----- ---- the trait cannot require that `Self : Sized` + | | + | the trait cannot require that `Self : Sized` ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | -LL | trait Array: Sized {} - | ----- the trait cannot require that `Self : Sized` +LL | trait Array: Sized + Copy {} + | ----- ---- the trait cannot require that `Self : Sized` + | | + | the trait cannot require that `Self : Sized` ... LL | let _ = x | ^ the trait `Array` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T` = note: required by cast to type `&dyn Array` diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index da1a7a7520e07..a0ecca3020e15 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -12,18 +12,21 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box<{integer}>` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index f272f829ba600..5694150ed7cc5 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -12,10 +12,12 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | trait Foo : Copy { + | ---- the trait cannot require that `Self : Sized` +... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index be0a2519a469b..473c8f8e6faaf 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -6,8 +6,6 @@ LL | trait Bar : Sized { ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index c20ddee54c07e..217e2aa00da16 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -7,7 +7,6 @@ LL | trait Bar : Sized { LL | t | ^ the trait `Bar` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index f1c1a6bb9728b..91fa144032fc9 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -18,8 +18,6 @@ LL | trait A: Sized { | ----- the trait cannot require that `Self : Sized` LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: associated item referring to unboxed trait object for its own trait --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 4c033cfcd898b..461ad97f2f0ac 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -7,7 +7,6 @@ LL | trait Trait: Sized {} LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` @@ -20,7 +19,6 @@ LL | trait Trait: Sized {} LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box<(dyn Trait + 'static)>` @@ -33,7 +31,6 @@ LL | trait Trait: Sized {} LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index ba3792c362e86..6fc57369b4e73 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -7,7 +7,6 @@ LL | trait Trait: Sized {} LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -20,7 +19,6 @@ LL | trait Trait: Sized {} LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -33,7 +31,6 @@ LL | trait Trait: Sized {} LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index a0082578d4d06..36c60aefa6bb5 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -21,7 +21,6 @@ LL | trait Trait: Sized {} LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` @@ -34,7 +33,6 @@ LL | trait Trait: Sized {} LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&R` = note: required by cast to type `&dyn Trait` From 972ae5afe5c38cbf80552179fc9051d78f983ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 13:27:53 -0800 Subject: [PATCH 0811/1253] Point at the `Sized` obligation in `where` clauses --- src/librustc/traits/object_safety.rs | 39 +++++++++++++++++-- .../object-safety-sized-2.curr.stderr | 5 ++- ...ty-sized-2.object_safe_for_dispatch.stderr | 4 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 8ceefb0abf038..08b980480c576 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -234,17 +234,48 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> tcx.hir() .get_if_local(trait_def_id) .and_then(|node| match node { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => Some( - bounds + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Trait(.., generics, bounds, _), + .. + }) => Some( + generics + .where_clause + .predicates .iter() - .filter_map(|b| match b { + .filter_map(|pred| { + match pred { + hir::WherePredicate::BoundPredicate(pred) + if pred.bounded_ty.hir_id.owner_def_id() == trait_def_id => + { + // Fetch spans for trait bounds that are Sized: + // `trait T where Self: Pred` + Some(pred.bounds.iter().filter_map(|b| match b { + hir::GenericBound::Trait( + trait_ref, + hir::TraitBoundModifier::None, + ) if trait_has_sized_self( + tcx, + trait_ref.trait_ref.trait_def_id(), + ) => + { + Some(trait_ref.span) + } + _ => None, + })) + } + _ => None, + } + }) + .flatten() + .chain(bounds.iter().filter_map(|b| match b { hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) => { + // Fetch spans for supertraits that are `Sized`: `trait T: Super` Some(trait_ref.span) } _ => None, - }) + })) .collect::>(), ), _ => None, diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 28fb4f36115f0..1ab33261111f8 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,10 +1,11 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | +LL | where Self : Sized + | ----- the trait cannot require that `Self : Sized` +... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 06ecfd019c841..fa1c89575198c 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -1,10 +1,12 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | +LL | where Self : Sized + | ----- the trait cannot require that `Self : Sized` +... LL | t | ^ the trait `Bar` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` From 8d48597b76ef656a1a1f600c96176d1aaeab32ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 14:16:31 -0800 Subject: [PATCH 0812/1253] Point at return type obligations instead of at `fn` ident --- src/librustc_typeck/check/wfcheck.rs | 6 +++--- .../generic_duplicate_lifetime_param.stderr | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 214e7d066eabc..3a4a015c14a50 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -530,7 +530,7 @@ fn check_where_clauses<'tcx, 'fcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, def_id: DefId, - return_ty: Option>, + return_ty: Option<(Ty<'tcx>, Span)>, ) { debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty); @@ -664,7 +664,7 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); - if let Some(return_ty) = return_ty { + if let Some((return_ty, span)) = return_ty { predicates.predicates.extend(check_opaque_types(tcx, fcx, def_id, span, return_ty)); } @@ -708,7 +708,7 @@ fn check_fn_or_method<'fcx, 'tcx>( // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); - check_where_clauses(tcx, fcx, span, def_id, Some(sig.output())); + check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_sig.decl.output.span()))); } /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 8cc6f7c303787..08b26b8fc1307 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:4 + --> $DIR/generic_duplicate_lifetime_param.rs:7:26 | LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - | ^^^ + | ^^^^^^^^^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_lifetime_param.rs:5:10 From 6870f79e9c06c6e3a80654a07301e23c705e1408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jan 2020 16:55:37 -0800 Subject: [PATCH 0813/1253] Use more accurate failed predicate spans --- src/librustc/ty/mod.rs | 9 +++- src/librustc_traits/lowering/environment.rs | 2 +- src/librustc_ty/ty.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 15 ++++--- .../bad-bounds-on-assoc-in-trait.stderr | 20 ++++----- ...associated-types-overridden-binding.stderr | 8 ++-- src/test/ui/error-codes/E0275.stderr | 4 +- .../issue-62326-parameter-out-of-range.rs | 2 +- .../issue-62326-parameter-out-of-range.stderr | 15 +++---- src/test/ui/issues/issue-20005.rs | 4 +- src/test/ui/issues/issue-20005.stderr | 9 ++-- src/test/ui/issues/issue-20413.rs | 4 +- src/test/ui/issues/issue-20413.stderr | 22 ++++------ src/test/ui/issues/issue-21974.rs | 4 +- src/test/ui/issues/issue-21974.stderr | 6 +-- src/test/ui/issues/issue-24204.stderr | 4 +- src/test/ui/issues/issue-24424.stderr | 4 +- .../lifetime-doesnt-live-long-enough.stderr | 42 ++++++++++--------- ...gions-free-region-ordering-callee-4.stderr | 4 +- ...issing-assoc-type-bound-restriction.stderr | 21 ++++------ .../traits/trait-alias/trait-alias-wf.stderr | 9 ++-- src/test/ui/type/type-check-defaults.stderr | 9 ++-- src/test/ui/type/type-check/issue-40294.rs | 4 +- .../ui/type/type-check/issue-40294.stderr | 6 +-- src/test/ui/wf/wf-enum-bound.rs | 4 +- src/test/ui/wf/wf-enum-bound.stderr | 19 ++++----- src/test/ui/wf/wf-fn-where-clause.stderr | 16 +++---- src/test/ui/wf/wf-in-fn-where-clause.rs | 4 +- src/test/ui/wf/wf-in-fn-where-clause.stderr | 8 ++-- ...f-inherent-impl-method-where-clause.stderr | 4 +- .../wf/wf-inherent-impl-where-clause.stderr | 17 ++++---- src/test/ui/wf/wf-struct-bound.rs | 4 +- src/test/ui/wf/wf-struct-bound.stderr | 19 ++++----- .../ui/wf/wf-trait-associated-type-bound.rs | 4 +- .../wf/wf-trait-associated-type-bound.stderr | 17 ++++---- src/test/ui/wf/wf-trait-bound.rs | 4 +- src/test/ui/wf/wf-trait-bound.stderr | 18 ++++---- .../wf-trait-default-fn-where-clause.stderr | 8 ++-- .../ui/wf/wf-trait-fn-where-clause.stderr | 8 ++-- src/test/ui/wf/wf-trait-superbound.stderr | 16 ++++--- 40 files changed, 187 insertions(+), 212 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..0781feee84541 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1015,6 +1015,7 @@ impl<'tcx> GenericPredicates<'tcx> { ) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(), + spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), } } @@ -1028,6 +1029,7 @@ impl<'tcx> GenericPredicates<'tcx> { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); } instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs))); + instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp)); } pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { @@ -1044,7 +1046,8 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p)) + instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p)); + instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } pub fn instantiate_supertrait( @@ -1059,6 +1062,7 @@ impl<'tcx> GenericPredicates<'tcx> { .iter() .map(|(pred, _)| pred.subst_supertrait(tcx, poly_trait_ref)) .collect(), + spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), } } } @@ -1511,11 +1515,12 @@ impl<'tcx> Predicate<'tcx> { #[derive(Clone, Debug, TypeFoldable)] pub struct InstantiatedPredicates<'tcx> { pub predicates: Vec>, + pub spans: Vec, } impl<'tcx> InstantiatedPredicates<'tcx> { pub fn empty() -> InstantiatedPredicates<'tcx> { - InstantiatedPredicates { predicates: vec![] } + InstantiatedPredicates { predicates: vec![], spans: vec![] } } pub fn is_empty(&self) -> bool { diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 7df27e67d5b1c..0e26e9461f4c3 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -161,7 +161,7 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { } // Compute the bounds on `Self` and the type parameters. - let ty::InstantiatedPredicates { predicates } = + let ty::InstantiatedPredicates { predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); let clauses = predicates diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 8f882be1a090e..9f867cf8ab464 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -228,7 +228,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { } // Compute the bounds on Self and the type parameters. - let ty::InstantiatedPredicates { predicates } = + let ty::InstantiatedPredicates { predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); // Finally, we have to normalize the bounds in the environment, in diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 3a4a015c14a50..41171117b47d4 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -665,16 +665,21 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); if let Some((return_ty, span)) = return_ty { - predicates.predicates.extend(check_opaque_types(tcx, fcx, def_id, span, return_ty)); + let opaque_types = check_opaque_types(tcx, fcx, def_id, span, return_ty); + for _ in 0..opaque_types.len() { + predicates.spans.push(span); + } + predicates.predicates.extend(opaque_types); } let predicates = fcx.normalize_associated_types_in(span, &predicates); debug!("check_where_clauses: predicates={:?}", predicates.predicates); - let wf_obligations = predicates - .predicates - .iter() - .flat_map(|p| traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, span)); + assert_eq!(predicates.predicates.len(), predicates.spans.len()); + let wf_obligations = + predicates.predicates.iter().zip(predicates.spans.iter()).flat_map(|(p, sp)| { + traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, *sp) + }); for obligation in wf_obligations.chain(default_obligations) { debug!("next obligation cause: {:?}", obligation.cause); diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 33fe8a3124083..5713e259362fd 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -10,9 +10,9 @@ error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterato --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 | LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` - | | - | `<::C as std::iter::Iterator>::Item` is not an iterator + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` + | | + | `<::C as std::iter::Iterator>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -23,9 +23,9 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` - | | - | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` + | | + | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -36,9 +36,9 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` - | | - | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` + | | + | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` @@ -49,7 +49,7 @@ LL | trait Case1 { | ----------- required by `Case1` ... LL | fn assume_case1() { - | ^^^^^^^^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr index 069da955b674e..9e10ed7b72952 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr @@ -1,20 +1,20 @@ error[E0284]: type annotations needed - --> $DIR/associated-types-overridden-binding.rs:4:1 + --> $DIR/associated-types-overridden-binding.rs:4:12 | LL | trait Foo: Iterator {} | ------------------------------- required by `Foo` LL | trait Bar: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` + | ^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` | = note: cannot resolve `::Item == i32` error[E0284]: type annotations needed - --> $DIR/associated-types-overridden-binding.rs:7:1 + --> $DIR/associated-types-overridden-binding.rs:7:21 | LL | trait I32Iterator = Iterator; | ----------------------------------------- required by `I32Iterator` LL | trait U32Iterator = I32Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self` | = note: cannot resolve `::Item == i32` diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index f607a9fbbf269..1d087a465942e 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/E0275.rs:5:1 + --> $DIR/E0275.rs:5:33 | LL | trait Foo {} | --------- required by `Foo` ... LL | impl Foo for T where Bar: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs index 60466d0bcd040..1a79dbf2279a0 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs @@ -4,8 +4,8 @@ // FIXME(generic-associated-types) Investigate why this doesn't compile. trait Iterator { - //~^ ERROR the requirement `for<'a> ::Item<'a>: 'a` is not satisfied type Item<'a>: 'a; + //~^ ERROR the requirement `for<'a> ::Item<'a>: 'a` is not satisfied } fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr index 4dc69cdd1dcf0..687423962361b 100644 --- a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr @@ -1,15 +1,10 @@ error[E0280]: the requirement `for<'a> ::Item<'a>: 'a` is not satisfied - --> $DIR/issue-62326-parameter-out-of-range.rs:6:1 + --> $DIR/issue-62326-parameter-out-of-range.rs:7:20 | -LL | trait Iterator { - | ^------------- - | | - | _required by `Iterator` - | | -LL | | -LL | | type Item<'a>: 'a; -LL | | } - | |_^ +LL | trait Iterator { + | -------------- required by `Iterator` +LL | type Item<'a>: 'a; + | ^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20005.rs b/src/test/ui/issues/issue-20005.rs index 6d63c9e5b613a..36350bff100dd 100644 --- a/src/test/ui/issues/issue-20005.rs +++ b/src/test/ui/issues/issue-20005.rs @@ -5,9 +5,9 @@ trait From { } trait To { - fn to( //~ ERROR the size for values of type + fn to( self - ) -> >::Result where Dst: From { + ) -> >::Result where Dst: From { //~ ERROR the size for values of type From::from(self) } } diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr index 7c4115b4d3f7c..529571a6b74dd 100644 --- a/src/test/ui/issues/issue-20005.stderr +++ b/src/test/ui/issues/issue-20005.stderr @@ -1,14 +1,13 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-20005.rs:8:8 + --> $DIR/issue-20005.rs:10:49 | LL | trait From { | --------------- required by `From` ... -LL | fn to( - | ^^ doesn't have a size known at compile-time -LL | self LL | ) -> >::Result where Dst: From { - | - help: consider further restricting `Self`: `, Self: std::marker::Sized` + | ^^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::marker::Sized` + | | + | doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-20413.rs b/src/test/ui/issues/issue-20413.rs index 7eb6d5c0ecbaa..19ef52af65736 100644 --- a/src/test/ui/issues/issue-20413.rs +++ b/src/test/ui/issues/issue-20413.rs @@ -6,9 +6,9 @@ struct NoData; //~^ ERROR: parameter `T` is never used impl Foo for T where NoData: Foo { -//~^ ERROR: overflow evaluating the requirement - fn answer(self) { //~^ ERROR: overflow evaluating the requirement + //~| ERROR: overflow evaluating the requirement + fn answer(self) { let val: NoData = NoData; } } diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 7aec4a847c9d4..e765144ff0b48 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -7,19 +7,13 @@ LL | struct NoData; = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:8:1 + --> $DIR/issue-20413.rs:8:36 | -LL | trait Foo { - | --------- required by `Foo` +LL | trait Foo { + | --------- required by `Foo` ... -LL | / impl Foo for T where NoData: Foo { -LL | | -LL | | fn answer(self) { -LL | | -LL | | let val: NoData = NoData; -LL | | } -LL | | } - | |_^ +LL | impl Foo for T where NoData: Foo { + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` @@ -151,13 +145,13 @@ LL | | } = note: required because of the requirements on the impl of `Foo` for `NoData` error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:10:6 + --> $DIR/issue-20413.rs:8:36 | LL | trait Foo { | --------- required by `Foo` ... -LL | fn answer(self) { - | ^^^^^^ +LL | impl Foo for T where NoData: Foo { + | ^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-21974.rs b/src/test/ui/issues/issue-21974.rs index 0cbe38d6ec0b6..f7c659be148db 100644 --- a/src/test/ui/issues/issue-21974.rs +++ b/src/test/ui/issues/issue-21974.rs @@ -7,8 +7,8 @@ trait Foo { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed - where &'a T : Foo, +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { x.foo(); diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index ebaef10cfef5b..19823499066eb 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-21974.rs:10:4 + --> $DIR/issue-21974.rs:11:19 | LL | trait Foo { | --------- required by `Foo` ... -LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) - | ^^^ cannot infer type for reference `&'a T` +LL | where &'a T : Foo, + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr index a1a6960a3f7ae..2a714861da1fd 100644 --- a/src/test/ui/issues/issue-24204.stderr +++ b/src/test/ui/issues/issue-24204.stderr @@ -1,11 +1,11 @@ error[E0271]: type mismatch resolving `<::A as MultiDispatch>::O == T` - --> $DIR/issue-24204.rs:14:4 + --> $DIR/issue-24204.rs:14:12 | LL | trait Trait: Sized { | ------------------ required by `Trait` ... LL | fn test>(b: i32) -> T where T::A: MultiDispatch { T::new(b) } - | ^^^^ expected type parameter `T`, found associated type + | ^^^^^^^^^^^^ expected type parameter `T`, found associated type | = note: expected type parameter `T` found associated type `<::A as MultiDispatch>::O` diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr index 8f0850328b446..538d44c3b2ef3 100644 --- a/src/test/ui/issues/issue-24424.stderr +++ b/src/test/ui/issues/issue-24424.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-24424.rs:4:1 + --> $DIR/issue-24424.rs:4:57 | LL | trait Trait0<'l0> {} | ----------------- required by `Trait0` LL | LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T0` + | ^^^^^^^^^^^ cannot infer type for type parameter `T0` | = note: cannot resolve `T0: Trait0<'l0>` diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index 3154c502625a6..4e50064efb4ec 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -13,69 +13,71 @@ LL | foo: &'static T | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19 | LL | trait X: Sized { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:24:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19 | LL | fn foo<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19 | LL | fn bar<'a, L: X<&'a Nested>>(); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `L` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22 | LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^^^ - help: consider adding an explicit lifetime bound `L: 'a`... + | - ^^^^^^^^^^^^^^^^ + | | + | help: consider adding an explicit lifetime bound `L: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22 | LL | fn baz<'a, L, M: X<&'a Nested>>() { - | ^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33 | LL | impl Nested { | - help: consider adding an explicit lifetime bound `K: 'a`... LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33 | LL | fn generic_in_parent<'a, L: X<&'a Nested>>() { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `M` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36 | LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... + | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound `M: 'a`... | note: ...so that the reference type `&'a Nested` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:44:8 + --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36 | LL | fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr index ad300f38ca5c1..5ab423d9e2077 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -1,8 +1,8 @@ error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references - --> $DIR/regions-free-region-ordering-callee-4.rs:5:4 + --> $DIR/regions-free-region-ordering-callee-4.rs:5:68 | LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14 --> $DIR/regions-free-region-ordering-callee-4.rs:5:14 diff --git a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr index c6f2e5cda66af..31d974ed43d99 100644 --- a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr +++ b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr @@ -1,20 +1,13 @@ error[E0277]: the trait bound `::Assoc: Child` is not satisfied - --> $DIR/missing-assoc-type-bound-restriction.rs:17:1 + --> $DIR/missing-assoc-type-bound-restriction.rs:17:19 | -LL | trait Parent { - | ------------ required by `Parent` +LL | trait Parent { + | ------------ required by `Parent` ... -LL | impl> Parent for ParentWrapper { - | ^ - help: consider further restricting the associated type: `where ::Assoc: Child` - | _| - | | -LL | | -LL | | type Ty = A; -LL | | type Assoc = ChildWrapper; -LL | | -LL | | -LL | | } - | |_^ the trait `Child` is not implemented for `::Assoc` +LL | impl> Parent for ParentWrapper { + | ^^^^^^ - help: consider further restricting the associated type: `where ::Assoc: Child` + | | + | the trait `Child` is not implemented for `::Assoc` error[E0277]: the trait bound `::Assoc: Child` is not satisfied --> $DIR/missing-assoc-type-bound-restriction.rs:20:5 diff --git a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr index 4355a517bd724..b71c0d719ff3f 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr @@ -1,13 +1,12 @@ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/trait-alias-wf.rs:5:1 + --> $DIR/trait-alias-wf.rs:5:14 | LL | trait A {} | --------------- required by `A` LL | trait B = A; - | ^^^^^^^^-^^^^^^^^^ - | | | - | | help: consider restricting this bound: `T: Foo` - | the trait `Foo` is not implemented for `T` + | - ^^^^ the trait `Foo` is not implemented for `T` + | | + | help: consider restricting this bound: `T: Foo` error: aborting due to previous error diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr index 6f84b37d61249..e5d2ebda31858 100644 --- a/src/test/ui/type/type-check-defaults.stderr +++ b/src/test/ui/type/type-check-defaults.stderr @@ -47,15 +47,14 @@ LL | trait TraitBound {} | required by `TraitBound` error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:21:1 + --> $DIR/type-check-defaults.rs:21:25 | LL | trait Super { } | -------------------- required by `Super` LL | trait Base: Super { } - | ^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | help: consider restricting this bound: `T: std::marker::Copy` - | the trait `std::marker::Copy` is not implemented for `T` + | - ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error[E0277]: cannot add `u8` to `i32` --> $DIR/type-check-defaults.rs:24:66 diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs index 7e6429ccfbe30..5493a4e5f10a8 100644 --- a/src/test/ui/type/type-check/issue-40294.rs +++ b/src/test/ui/type/type-check/issue-40294.rs @@ -2,8 +2,8 @@ trait Foo: Sized { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed - where &'a T : Foo, +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { x.foo(); diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 4a04b71d82f71..2c889b6c2ca0a 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/issue-40294.rs:5:4 + --> $DIR/issue-40294.rs:6:19 | LL | trait Foo: Sized { | ---------------- required by `Foo` ... -LL | fn foo<'a,'b,T>(x: &'a T, y: &'b T) - | ^^^ cannot infer type for reference `&'a T` +LL | where &'a T : Foo, + | ^^^ cannot infer type for reference `&'a T` | = note: cannot resolve `&'a T: Foo` diff --git a/src/test/ui/wf/wf-enum-bound.rs b/src/test/ui/wf/wf-enum-bound.rs index c9eb9d894331e..042a2cb09d27b 100644 --- a/src/test/ui/wf/wf-enum-bound.rs +++ b/src/test/ui/wf/wf-enum-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -enum SomeEnum //~ ERROR E0277 - where T: ExtraCopy +enum SomeEnum + where T: ExtraCopy //~ ERROR E0277 { SomeVariant(T,U) } diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr index eaacd6b6881ef..0d22d18bf6fd9 100644 --- a/src/test/ui/wf/wf-enum-bound.stderr +++ b/src/test/ui/wf/wf-enum-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-enum-bound.rs:9:1 + --> $DIR/wf-enum-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / enum SomeEnum -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | SomeVariant(T,U) -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 5d41dc77d8bc2..3bef38d2fd2c3 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -1,29 +1,29 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-fn-where-clause.rs:8:4 + --> $DIR/wf-fn-where-clause.rs:8:24 | LL | trait ExtraCopy { } | ----------------------- required by `ExtraCopy` LL | LL | fn foo() where T: ExtraCopy - | ^^^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | | - | the trait `std::marker::Copy` is not implemented for `U` + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time - --> $DIR/wf-fn-where-clause.rs:12:4 + --> $DIR/wf-fn-where-clause.rs:12:16 | LL | fn bar() where Vec:, {} - | ^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)` = note: to learn more, visit = note: required by `std::vec::Vec` error[E0038]: the trait `std::marker::Copy` cannot be made into an object - --> $DIR/wf-fn-where-clause.rs:12:4 + --> $DIR/wf-fn-where-clause.rs:12:16 | LL | fn bar() where Vec:, {} - | ^^^ the trait `std::marker::Copy` cannot be made into an object + | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/wf/wf-in-fn-where-clause.rs b/src/test/ui/wf/wf-in-fn-where-clause.rs index 65a1771d41a48..e55295a3b2578 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.rs +++ b/src/test/ui/wf/wf-in-fn-where-clause.rs @@ -6,8 +6,8 @@ trait MustBeCopy { } -fn bar() //~ ERROR E0277 - where T: MustBeCopy +fn bar() + where T: MustBeCopy //~ ERROR E0277 { } diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr index e1a281626b9b7..495041b7dadf8 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-in-fn-where-clause.rs:9:4 + --> $DIR/wf-in-fn-where-clause.rs:10:14 | LL | trait MustBeCopy { | ------------------------ required by `MustBeCopy` ... -LL | fn bar() - | ^^^ the trait `std::marker::Copy` is not implemented for `U` LL | where T: MustBeCopy - | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | ^^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr index 16079c8197cb1..e9c1c8ddaf640 100644 --- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-method-where-clause.rs:12:8 + --> $DIR/wf-inherent-impl-method-where-clause.rs:12:27 | LL | trait ExtraCopy { } | ----------------------- required by `ExtraCopy` @@ -7,7 +7,7 @@ LL | trait ExtraCopy { } LL | impl Foo { | - help: consider restricting this bound: `U: std::marker::Copy` LL | fn foo(self) where T: ExtraCopy - | ^^^ the trait `std::marker::Copy` is not implemented for `U` + | ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr index 35b9093381329..a4e6dce39cdcd 100644 --- a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-inherent-impl-where-clause.rs:11:1 + --> $DIR/wf-inherent-impl-where-clause.rs:11:29 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` ... -LL | impl Foo where T: ExtraCopy - | ^ - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` - | _| - | | -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | impl Foo where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-struct-bound.rs b/src/test/ui/wf/wf-struct-bound.rs index 69be71cd130b0..6e558ca8ff0b0 100644 --- a/src/test/ui/wf/wf-struct-bound.rs +++ b/src/test/ui/wf/wf-struct-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -struct SomeStruct //~ ERROR E0277 - where T: ExtraCopy +struct SomeStruct + where T: ExtraCopy //~ ERROR E0277 { data: (T,U) } diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr index 2155977349256..3f4047d9b5609 100644 --- a/src/test/ui/wf/wf-struct-bound.stderr +++ b/src/test/ui/wf/wf-struct-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-struct-bound.rs:9:1 + --> $DIR/wf-struct-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / struct SomeStruct -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | data: (T,U) -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.rs b/src/test/ui/wf/wf-trait-associated-type-bound.rs index 29e305577acbc..2f20e65e5021a 100644 --- a/src/test/ui/wf/wf-trait-associated-type-bound.rs +++ b/src/test/ui/wf/wf-trait-associated-type-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -trait SomeTrait { //~ ERROR E0277 - type Type1: ExtraCopy; +trait SomeTrait { + type Type1: ExtraCopy; //~ ERROR E0277 } diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr index af0433fd22f6e..3370cfc86939d 100644 --- a/src/test/ui/wf/wf-trait-associated-type-bound.stderr +++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr @@ -1,16 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-associated-type-bound.rs:9:1 + --> $DIR/wf-trait-associated-type-bound.rs:10:17 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | trait SomeTrait { - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | type Type1: ExtraCopy; -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | trait SomeTrait { + | - help: consider restricting this bound: `T: std::marker::Copy` +LL | type Type1: ExtraCopy; + | ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-bound.rs b/src/test/ui/wf/wf-trait-bound.rs index d8746ba4d6e52..62a1eb5b08864 100644 --- a/src/test/ui/wf/wf-trait-bound.rs +++ b/src/test/ui/wf/wf-trait-bound.rs @@ -6,8 +6,8 @@ trait ExtraCopy { } -trait SomeTrait //~ ERROR E0277 - where T: ExtraCopy +trait SomeTrait + where T: ExtraCopy //~ ERROR E0277 { } diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr index 13e2f8f590149..87c33714ff879 100644 --- a/src/test/ui/wf/wf-trait-bound.stderr +++ b/src/test/ui/wf/wf-trait-bound.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-bound.rs:9:1 + --> $DIR/wf-trait-bound.rs:10:14 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` -LL | -LL | / trait SomeTrait -LL | | where T: ExtraCopy - | | - help: consider further restricting type parameter `U`: `, U: std::marker::Copy` -LL | | { -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `U` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` +... +LL | where T: ExtraCopy + | ^^^^^^^^^^^^- help: consider further restricting type parameter `U`: `, U: std::marker::Copy` + | | + | the trait `std::marker::Copy` is not implemented for `U` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr index 984237ce3b497..6b63feaba89a3 100644 --- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-default-fn-where-clause.rs:11:8 + --> $DIR/wf-trait-default-fn-where-clause.rs:11:31 | LL | trait Bar { } | ---------------------- required by `Bar` ... LL | fn bar(&self) where A: Bar { - | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr index 34cda077963b5..ec8f02c9c4fed 100644 --- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied - --> $DIR/wf-trait-fn-where-clause.rs:10:8 + --> $DIR/wf-trait-fn-where-clause.rs:10:49 | LL | struct Bar { value: Box } | ----------------------- required by `Bar` ... LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` + | | + | the trait `std::cmp::Eq` is not implemented for `Self` error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr index a61b8dd3a3849..9ea9d046b2602 100644 --- a/src/test/ui/wf/wf-trait-superbound.stderr +++ b/src/test/ui/wf/wf-trait-superbound.stderr @@ -1,15 +1,13 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/wf-trait-superbound.rs:9:1 + --> $DIR/wf-trait-superbound.rs:9:21 | -LL | trait ExtraCopy { } - | ----------------------- required by `ExtraCopy` +LL | trait ExtraCopy { } + | ----------------------- required by `ExtraCopy` LL | -LL | trait SomeTrait: ExtraCopy { - | ^ - help: consider restricting this bound: `T: std::marker::Copy` - | _| - | | -LL | | } - | |_^ the trait `std::marker::Copy` is not implemented for `T` +LL | trait SomeTrait: ExtraCopy { + | - ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | | + | help: consider restricting this bound: `T: std::marker::Copy` error: aborting due to previous error From 144e2594458fedc5c62f760f30789c21e3e0198e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 10:20:47 -0800 Subject: [PATCH 0814/1253] Slight rewording of diagnostic message --- src/librustc/traits/object_safety.rs | 2 +- ...rait-object-reference-without-parens-suggestion.stderr | 2 +- .../feature-gate-object_safe_for_dispatch.stderr | 4 ++-- src/test/ui/issues/issue-20692.stderr | 8 ++++---- .../ui/kindck/kindck-inherited-copy-bound.curr.stderr | 4 ++-- ...k-inherited-copy-bound.object_safe_for_dispatch.stderr | 2 +- .../ui/object-safety/object-safety-sized-2.curr.stderr | 2 +- .../object-safety-sized-2.object_safe_for_dispatch.stderr | 2 +- src/test/ui/object-safety/object-safety-sized.curr.stderr | 2 +- .../object-safety-sized.object_safe_for_dispatch.stderr | 2 +- .../object-unsafe-trait-should-use-self.stderr | 2 +- src/test/ui/traits/trait-object-macro-matcher.stderr | 2 +- src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr | 6 +++--- src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr | 6 +++--- src/test/ui/wf/wf-fn-where-clause.stderr | 2 +- src/test/ui/wf/wf-unsafe-trait-obj-match.stderr | 4 ++-- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 08b980480c576..50d355f9d0a0d 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -44,7 +44,7 @@ impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { ObjectSafetyViolation::SizedSelf(_) => { - "the trait cannot require that `Self : Sized`".into() + "traits that require `Self: Sized` cannot be made into an object".into() } ObjectSafetyViolation::SupertraitSelf => { "the trait cannot use `Self` as a type parameter \ diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 8c6c33b11865b..070917f2db98a 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | let _: &Copy + 'static; | ^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 237c22d3bf09a..ce98306940512 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | trait NonObjectSafe1: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object @@ -38,7 +38,7 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | LL | trait NonObjectSafe1: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 62efdfb2e91bf..552b65b362094 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -2,9 +2,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | LL | trait Array: Sized + Copy {} - | ----- ---- the trait cannot require that `Self : Sized` + | ----- ---- traits that require `Self: Sized` cannot be made into an object | | - | the trait cannot require that `Self : Sized` + | traits that require `Self: Sized` cannot be made into an object ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object @@ -13,9 +13,9 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | LL | trait Array: Sized + Copy {} - | ----- ---- the trait cannot require that `Self : Sized` + | ----- ---- traits that require `Self: Sized` cannot be made into an object | | - | the trait cannot require that `Self : Sized` + | traits that require `Self: Sized` cannot be made into an object ... LL | let _ = x | ^ the trait `Array` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index a0ecca3020e15..728a5ea6faa9f 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -13,7 +13,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object @@ -22,7 +22,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 5694150ed7cc5..b4fba9706bc0d 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -13,7 +13,7 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- the trait cannot require that `Self : Sized` + | ---- traits that require `Self: Sized` cannot be made into an object ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 1ab33261111f8..49f98e0085082 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | LL | where Self : Sized - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index fa1c89575198c..9b189c48f9301 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | LL | where Self : Sized - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 473c8f8e6faaf..3b588034e3322 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | LL | trait Bar : Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 217e2aa00da16..6b60eef30d3d3 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | LL | trait Bar : Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 91fa144032fc9..4a9242b1f4fac 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -15,7 +15,7 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 | LL | trait A: Sized { - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index 6b5effaad9bc4..f41ebf4166d06 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -10,7 +10,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | m!(dyn Copy + Send + 'static); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 461ad97f2f0ac..7e055d746f676 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -14,7 +14,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -26,7 +26,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 6fc57369b4e73..9e7fe7f3e1dfc 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object @@ -14,7 +14,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object @@ -26,7 +26,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 3bef38d2fd2c3..f17391520a32c 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -25,7 +25,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | fn bar() where Vec:, {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: the trait cannot require that `Self : Sized` + = note: traits that require `Self: Sized` cannot be made into an object error: aborting due to 3 previous errors diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 36c60aefa6bb5..452a2a5e58b7f 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object @@ -28,7 +28,7 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | LL | trait Trait: Sized {} - | ----- the trait cannot require that `Self : Sized` + | ----- traits that require `Self: Sized` cannot be made into an object ... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object From 132921bc521ef351192019f9336ae7a6f5809b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 10:34:38 -0800 Subject: [PATCH 0815/1253] Remove duplicated code --- src/librustc/traits/object_safety.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 50d355f9d0a0d..9128851b91cf3 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -190,14 +190,7 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - let spans = violation.spans(); - if spans.is_empty() { - err.note(&violation.error_msg()); - } else { - for span in spans { - err.span_label(span, violation.error_msg()); - } - } + err.span_label(*span, violation.error_msg()); err.emit(); false } else { From 06fea9235642cec6e360da5654db9262245dc862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 19:35:48 -0800 Subject: [PATCH 0816/1253] review comments --- src/librustc/traits/object_safety.rs | 6 +++--- src/librustc_typeck/check/wfcheck.rs | 21 +++++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 9128851b91cf3..dec9ef4f4216f 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -18,7 +18,7 @@ use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use syntax::ast; use std::borrow::Cow; @@ -85,9 +85,9 @@ impl ObjectSafetyViolation { | ObjectSafetyViolation::Method(_, _, span) if *span != DUMMY_SP => { - vec![*span].into() + smallvec![*span] } - _ => vec![].into(), + _ => smallvec![], } } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 41171117b47d4..fc194e3af97f2 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast; @@ -180,15 +180,12 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } -fn could_be_self(trait_name: Ident, ty: &hir::Ty<'_>) -> bool { +fn could_be_self(trait_def_id: DefId, ty: &hir::Ty<'_>) -> bool { match ty.kind { - hir::TyKind::TraitObject([trait_ref], ..) => { - let mut p = trait_ref.trait_ref.path.segments.iter().map(|s| s.ident); - match (p.next(), p.next()) { - (Some(ident), None) => ident == trait_name, - _ => false, - } - } + hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments { + [s] => s.res.and_then(|r| r.opt_def_id()) == Some(trait_def_id), + _ => false, + }, _ => false, } } @@ -206,18 +203,18 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem let mut trait_should_be_self = vec![]; match &item.kind { hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty)) - if could_be_self(trait_name, ty) => + if could_be_self(trait_def_id, ty) => { trait_should_be_self.push(ty.span) } hir::TraitItemKind::Method(sig, _) => { for ty in sig.decl.inputs { - if could_be_self(trait_name, ty) { + if could_be_self(trait_def_id, ty) { trait_should_be_self.push(ty.span); } } match sig.decl.output { - hir::FunctionRetTy::Return(ty) if could_be_self(trait_name, ty) => { + hir::FunctionRetTy::Return(ty) if could_be_self(trait_def_id, ty) => { trait_should_be_self.push(ty.span); } _ => {} From 3ca1c5d5b5e0d19f55570f5d49d97100e9b524b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 20:12:46 -0800 Subject: [PATCH 0817/1253] Point at `Sized` requirements Make #47990 easier to understand --- src/librustc_typeck/check/method/confirm.rs | 24 ++++++++++++------- src/librustc_typeck/check/method/mod.rs | 6 ++--- src/librustc_typeck/check/method/suggest.rs | 3 ++- src/test/ui/issues/issue-35976.stderr | 3 +++ .../suggestions/imm-ref-trait-object.stderr | 5 ++++ .../by-value-trait-object-safety.stderr | 3 +++ 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 832aa9f62ff4d..eee9dc99d35b4 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> { pub struct ConfirmResult<'tcx> { pub callee: MethodCallee<'tcx>, - pub illegal_sized_bound: bool, + pub illegal_sized_bound: Option, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -112,7 +112,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // Add any trait/regions obligations specified on the method's type parameters. // We won't add these if we encountered an illegal sized bound, so that we can use // a custom error in that case. - if !illegal_sized_bound { + if illegal_sized_bound.is_none() { let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig)); self.add_obligations(method_ty, all_substs, &method_predicates); } @@ -561,23 +561,31 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn predicates_require_illegal_sized_bound( &self, predicates: &ty::InstantiatedPredicates<'tcx>, - ) -> bool { + ) -> Option { let sized_def_id = match self.tcx.lang_items().sized_trait() { Some(def_id) => def_id, - None => return false, + None => return None, }; traits::elaborate_predicates(self.tcx, predicates.predicates.clone()) .filter_map(|predicate| match predicate { ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { - Some(trait_pred) + let span = predicates + .predicates + .iter() + .zip(predicates.spans.iter()) + .filter_map(|(p, span)| if *p == predicate { Some(*span) } else { None }) + .next() + .unwrap_or(rustc_span::DUMMY_SP); + Some((trait_pred, span)) } _ => None, }) - .any(|trait_pred| match trait_pred.skip_binder().self_ty().kind { - ty::Dynamic(..) => true, - _ => false, + .filter_map(|(trait_pred, span)| match trait_pred.skip_binder().self_ty().kind { + ty::Dynamic(..) => Some(span), + _ => None, }) + .next() } fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index c1cf3522b5d9c..e90c2ef5e4361 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -58,7 +58,7 @@ pub enum MethodError<'tcx> { // Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have // forgotten to import a trait. - IllegalSizedBound(Vec, bool), + IllegalSizedBound(Vec, bool, Span), // Found a match, but the return type is wrong BadReturnType, @@ -204,7 +204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self.confirm_method(span, self_expr, call_expr, self_ty, pick.clone(), segment); - if result.illegal_sized_bound { + if let Some(span) = result.illegal_sized_bound { let mut needs_mut = false; if let ty::Ref(region, t_type, mutability) = self_ty.kind { let trait_type = self @@ -249,7 +249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Vec::new(), }; - return Err(IllegalSizedBound(candidates, needs_mut)); + return Err(IllegalSizedBound(candidates, needs_mut, span)); } Ok(result.callee) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 490c69b55362b..789bac2705b07 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -640,9 +640,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - MethodError::IllegalSizedBound(candidates, needs_mut) => { + MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => { let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); let mut err = self.sess().struct_span_err(span, &msg); + err.span_label(bound_span, "this has a `Sized` requirement"); if !candidates.is_empty() { let help = format!( "{an}other candidate{s} {were} found in the following trait{s}, perhaps \ diff --git a/src/test/ui/issues/issue-35976.stderr b/src/test/ui/issues/issue-35976.stderr index 99b243a077792..f9b9b7dbd34bb 100644 --- a/src/test/ui/issues/issue-35976.stderr +++ b/src/test/ui/issues/issue-35976.stderr @@ -1,6 +1,9 @@ error: the `wait` method cannot be invoked on a trait object --> $DIR/issue-35976.rs:14:9 | +LL | fn wait(&self) where Self: Sized; + | ----- this has a `Sized` requirement +... LL | arg.wait(); | ^^^^ | diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 9185eaa65c06d..37c2053522961 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -3,6 +3,11 @@ error: the `min` method cannot be invoked on a trait object | LL | t.min().unwrap() | ^^^ + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | Self: Sized, + | ----- this has a `Sized` requirement | = note: you need `&mut dyn std::iter::Iterator` instead of `&dyn std::iter::Iterator` diff --git a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr index 7e9a2316be2bf..4cd2098eef256 100644 --- a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr @@ -1,6 +1,9 @@ error: the `foo` method cannot be invoked on a trait object --> $DIR/by-value-trait-object-safety.rs:18:7 | +LL | fn foo(self) -> String where Self: Sized; + | ----- this has a `Sized` requirement +... LL | x.foo(); | ^^^ From 413bfa4b98ac3a59c57ea9fa8cff2d87062fdc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 16:47:00 -0800 Subject: [PATCH 0818/1253] Wording changes to object unsafe trait errors Stemming from the thread at https://twitter.com/indygreg/status/1223279056398929920 --- src/librustc/traits/error_reporting/mod.rs | 22 +++++++- src/librustc/traits/object_safety.rs | 53 ++++++++++++++++--- .../associated-const-in-trait.stderr | 6 ++- .../ui/associated-item/issue-48027.stderr | 6 ++- ...ce-impl-trait-for-trait-object-safe.stderr | 6 ++- ...reference-without-parens-suggestion.stderr | 2 +- src/test/ui/error-codes/E0033-teach.stderr | 6 ++- src/test/ui/error-codes/E0033.stderr | 6 ++- src/test/ui/error-codes/E0038.stderr | 6 ++- ...ature-gate-object_safe_for_dispatch.stderr | 26 +++++++-- ...-trait-in-return-position-dyn-trait.stderr | 12 ++++- src/test/ui/issues/issue-18959.stderr | 6 ++- src/test/ui/issues/issue-19380.stderr | 6 ++- src/test/ui/issues/issue-19538.stderr | 13 ++++- src/test/ui/issues/issue-20692.stderr | 14 ++--- src/test/ui/issues/issue-26056.stderr | 2 +- src/test/ui/issues/issue-28576.stderr | 2 +- src/test/ui/issues/issue-38404.stderr | 2 +- src/test/ui/issues/issue-38604.stderr | 4 +- src/test/ui/issues/issue-50781.stderr | 5 +- .../kindck-inherited-copy-bound.curr.stderr | 8 ++- ...copy-bound.object_safe_for_dispatch.stderr | 4 +- ...bject-safety-associated-consts.curr.stderr | 6 ++- ...ted-consts.object_safe_for_dispatch.stderr | 5 +- .../object-safety-generics.curr.stderr | 12 ++++- ...y-generics.object_safe_for_dispatch.stderr | 10 +++- .../object-safety-issue-22040.stderr | 2 +- .../object-safety-mentions-Self.curr.stderr | 12 ++++- ...tions-Self.object_safe_for_dispatch.stderr | 10 +++- .../object-safety-no-static.curr.stderr | 6 ++- ...-no-static.object_safe_for_dispatch.stderr | 5 +- .../object-safety-sized-2.curr.stderr | 4 +- ...ty-sized-2.object_safe_for_dispatch.stderr | 4 +- .../object-safety-sized.curr.stderr | 4 +- ...fety-sized.object_safe_for_dispatch.stderr | 4 +- ...ect-safety-supertrait-mentions-Self.stderr | 2 +- src/test/ui/resolve/issue-3907-2.stderr | 2 +- ...ary-self-types-not-object-safe.curr.stderr | 11 +++- ...bject-safe.object_safe_for_dispatch.stderr | 5 +- ...object-unsafe-trait-should-use-self.stderr | 10 +++- .../trait-alias-object-fail.stderr | 2 +- src/test/ui/traits/trait-item-privacy.stderr | 12 +++-- .../traits/trait-object-macro-matcher.stderr | 2 +- src/test/ui/traits/trait-object-safety.stderr | 11 +++- src/test/ui/traits/trait-test-2.stderr | 19 ++++--- ...ter-defaults-referencing-Self-ppaux.stderr | 6 ++- .../wf/wf-convert-unsafe-trait-obj-box.stderr | 12 +++-- .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 12 +++-- src/test/ui/wf/wf-fn-where-clause.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 6 ++- .../ui/wf/wf-unsafe-trait-obj-match.stderr | 8 ++- 51 files changed, 332 insertions(+), 91 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f15fa779534e0..f2cc8a303a952 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1034,6 +1034,10 @@ pub fn report_object_safety_error( violations: Vec, ) -> DiagnosticBuilder<'tcx> { let trait_str = tcx.def_path_str(trait_def_id); + let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node { + hir::Node::Item(item) => Some(item.ident.span), + _ => None, + }); let span = tcx.sess.source_map().def_span(span); let mut err = struct_span_err!( tcx.sess, @@ -1045,6 +1049,7 @@ pub fn report_object_safety_error( err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); let mut reported_violations = FxHashSet::default(); + let mut had_span_label = false; for violation in violations { if let ObjectSafetyViolation::SizedSelf(sp) = &violation { if !sp.is_empty() { @@ -1055,15 +1060,28 @@ pub fn report_object_safety_error( } if reported_violations.insert(violation.clone()) { let spans = violation.spans(); + let msg = if trait_span.is_none() || spans.is_empty() { + format!("the trait cannot be made into an object because {}", violation.error_msg()) + } else { + had_span_label = true; + format!("...because {}", violation.error_msg()) + }; if spans.is_empty() { - err.note(&violation.error_msg()); + err.note(&msg); } else { for span in spans { - err.span_label(span, violation.error_msg()); + err.span_label(span, &msg); } } + if let (Some(_), Some(note)) = (trait_span, violation.solution()) { + // Only provide the help if its a local trait, otherwise it's not actionable. + err.help(¬e); + } } } + if let (Some(trait_span), true) = (trait_span, had_span_label) { + err.span_label(trait_span, "this trait cannot be made into an object..."); + } if tcx.sess.trait_methods_not_found.borrow().contains(&span) { // Avoid emitting error caused by non-existing method (#58734) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index dec9ef4f4216f..ac9e4950b72cf 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -43,12 +43,9 @@ pub enum ObjectSafetyViolation { impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { - ObjectSafetyViolation::SizedSelf(_) => { - "traits that require `Self: Sized` cannot be made into an object".into() - } + ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), ObjectSafetyViolation::SupertraitSelf => { - "the trait cannot use `Self` as a type parameter \ - in the supertraits or where-clauses" + "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" .into() } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => { @@ -63,19 +60,45 @@ impl ObjectSafetyViolation { name, MethodViolationCode::WhereClauseReferencesSelf, _, - ) => format!("method `{}` references the `Self` type in where clauses", name).into(), + ) => { + format!("method `{}` references the `Self` type in its `where` clause", name).into() + } ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => { format!("method `{}` has generic type parameters", name).into() } ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { format!("method `{}`'s `self` parameter cannot be dispatched on", name).into() } + ObjectSafetyViolation::AssocConst(_, DUMMY_SP) => { + "it cannot contain associated consts".into() + } ObjectSafetyViolation::AssocConst(name, _) => { - format!("the trait cannot contain associated consts like `{}`", name).into() + format!("it cannot contain associated consts like `{}`", name).into() } } } + pub fn solution(&self) -> Option { + Some(match *self { + ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { + return None; + } + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => format!( + "consider turning `{}` into a method by giving it a `&self` argument or \ + constraining it with `where Self: Sized`", + name + ), + ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { + format!("consider changing method `{}`'s `self` parameter to be `&self`", name) + .into() + } + ObjectSafetyViolation::AssocConst(name, _) + | ObjectSafetyViolation::Method(name, ..) => { + format!("consider moving `{}` to another trait", name) + } + }) + } + pub fn spans(&self) -> SmallVec<[Span; 1]> { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. @@ -190,7 +213,21 @@ fn object_safety_violations_for_trait( tcx.def_path_str(trait_def_id) ), ); - err.span_label(*span, violation.error_msg()); + let node = tcx.hir().get_if_local(trait_def_id); + let msg = if let Some(hir::Node::Item(item)) = node { + err.span_label(item.ident.span, "this trait cannot be made into an object..."); + format!("...because {}", violation.error_msg()) + } else { + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ) + }; + err.span_label(*span, &msg); + if let (Some(_), Some(note)) = (node, violation.solution()) { + // Only provide the help if its a local trait, otherwise it's not actionable. + err.help(¬e); + } err.emit(); false } else { diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr index a5d7fc5b70246..b9101c86d218a 100644 --- a/src/test/ui/associated-const/associated-const-in-trait.stderr +++ b/src/test/ui/associated-const/associated-const-in-trait.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/associated-const-in-trait.rs:9:6 | +LL | trait Trait { + | ----- this trait cannot be made into an object... LL | const N: usize; - | - the trait cannot contain associated consts like `N` + | - ...because it cannot contain associated consts like `N` ... LL | impl dyn Trait { | ^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `N` to another trait error: aborting due to previous error diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index ddabd552897a8..e8442c6c9ac14 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-48027.rs:6:6 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | impl dyn Bar {} | ^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `X` to another trait error[E0283]: type annotations needed --> $DIR/issue-48027.rs:3:32 diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index ed6be60de460c..c999cabcc1413 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -2,9 +2,13 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6 | LL | trait NotObjectSafe { fn eq(&self, other: Self); } - | -- method `eq` references the `Self` type in its parameters or return type + | ------------- -- ...because method `eq` references the `Self` type in its parameters or return type + | | + | this trait cannot be made into an object... LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider moving `eq` to another trait error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 070917f2db98a..333754891c164 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -16,7 +16,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | let _: &Copy + 'static; | ^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index 80f3d4441bd9f..050ea63aa4fa8 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -7,11 +7,15 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033-teach.rs:8:20 | +LL | trait SomeTrait { + | --------- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033-teach.rs:12:9 diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index c2843796cc851..c736fbcf92a8e 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -7,11 +7,15 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033.rs:6:20 | +LL | trait SomeTrait { + | --------- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033.rs:10:9 diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 6eaf6e4a8aad1..62b6f4cf24692 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/E0038.rs:5:16 | +LL | trait Trait { + | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | fn call_foo(x: Box) { | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index ce98306940512..2905988066898 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | LL | trait NonObjectSafe1: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | -------------- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object @@ -10,35 +12,49 @@ LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { error[E0038]: the trait `NonObjectSafe2` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 | +LL | trait NonObjectSafe2 { + | -------------- this trait cannot be made into an object... LL | fn static_fn() {} - | --------- associated function `static_fn` has no `self` parameter + | --------- ...because associated function `static_fn` has no `self` parameter ... LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + | + = help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0038]: the trait `NonObjectSafe3` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 | +LL | trait NonObjectSafe3 { + | -------------- this trait cannot be made into an object... LL | fn foo(&self); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters ... LL | fn takes_non_object_safe_box(obj: Box) { | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe4` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 | +LL | trait NonObjectSafe4 { + | -------------- this trait cannot be made into an object... LL | fn foo(&self, &Self); - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 | LL | trait NonObjectSafe1: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | -------------- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | impl Trait for dyn NonObjectSafe1 {} | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index ff4bfc30a4a62..1443be0b30ebe 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn car() -> dyn NotObjectSafe { | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn cat() -> Box { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 0c59486b416b8..b3ba7aecad0db 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -2,10 +2,14 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-18959.rs:11:11 | LL | pub trait Foo { fn foo(&self, ext_thing: &T); } - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | fn foo(b: &dyn Bar) { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 92bfdf1f26e93..22e744f884171 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Qiz` cannot be made into an object --> $DIR/issue-19380.rs:11:3 | +LL | trait Qiz { + | --- this trait cannot be made into an object... LL | fn qiz(); - | --- associated function `qiz` has no `self` parameter + | --- ...because associated function `qiz` has no `self` parameter ... LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object + | + = help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 83c03b514ddcc..b6033e47b1a44 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -2,20 +2,29 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:15 | LL | fn foo(&self, val: T); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 | LL | fn foo(&self, val: T); - | --- method `foo` has generic type parameters + | --- ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... ... LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ the trait `Bar` cannot be made into an object | + = help: consider moving `foo` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing` = note: required by cast to type `&mut dyn Bar` diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 552b65b362094..ca2611e0f9eb5 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -2,9 +2,10 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | LL | trait Array: Sized + Copy {} - | ----- ---- traits that require `Self: Sized` cannot be made into an object - | | - | traits that require `Self: Sized` cannot be made into an object + | ----- ----- ---- ...because it requires `Self: Sized` + | | | + | | ...because it requires `Self: Sized` + | this trait cannot be made into an object... ... LL | &dyn Array; | ^^^^^^^^^^ the trait `Array` cannot be made into an object @@ -13,9 +14,10 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | LL | trait Array: Sized + Copy {} - | ----- ---- traits that require `Self: Sized` cannot be made into an object - | | - | traits that require `Self: Sized` cannot be made into an object + | ----- ----- ---- ...because it requires `Self: Sized` + | | | + | | ...because it requires `Self: Sized` + | this trait cannot be made into an object... ... LL | let _ = x | ^ the trait `Array` cannot be made into an object diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr index 9c4cf0b18acfe..2744fb91d6fe1 100644 --- a/src/test/ui/issues/issue-26056.stderr +++ b/src/test/ui/issues/issue-26056.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Map` cannot be made into an object LL | as &dyn Map; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr index 3249d76e69b57..5bed9a77d1891 100644 --- a/src/test/ui/issues/issue-28576.stderr +++ b/src/test/ui/issues/issue-28576.stderr @@ -5,7 +5,7 @@ LL | / dyn Bar LL | | | |________________________^ the trait `Bar` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr index d18a26b3a7638..613888758cab4 100644 --- a/src/test/ui/issues/issue-38404.stderr +++ b/src/test/ui/issues/issue-38404.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `B` cannot be made into an object LL | trait C: A> {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index 8b923a2c6b23f..b3ad71e174a97 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | let _f: Box = | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 @@ -12,7 +12,7 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | Box::new(()); | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<()>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index c161e9efd1261..03e3a7f227a23 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -1,8 +1,10 @@ error: the trait `X` cannot be made into an object --> $DIR/issue-50781.rs:6:8 | +LL | trait X { + | - this trait cannot be made into an object... LL | fn foo(&self) where Self: Trait; - | ^^^ method `foo` references the `Self` type in where clauses + | ^^^ ...because method `foo` references the `Self` type in its `where` clause | note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 @@ -11,6 +13,7 @@ LL | #![deny(where_clauses_object_safety)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 728a5ea6faa9f..2a9fd13be5f01 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -13,7 +13,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object @@ -22,7 +24,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index b4fba9706bc0d..6227ada4dc938 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -13,7 +13,9 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | trait Foo : Copy { - | ---- traits that require `Self: Sized` cannot be made into an object + | --- ---- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index b67b0e4f40e8c..e0e0344af7591 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:12:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `X` to another trait error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index 20993a680ba48..ff0bd17dccce5 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:14:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | const X: usize; - | - the trait cannot contain associated consts like `X` + | - ...because it cannot contain associated consts like `X` ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `X` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 2469467f084a3..9e70abbd32fc6 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:18:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:24:39 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | fn make_bar_explicit(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index d3d8d36888836..7443d38470c03 100644 --- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -1,24 +1,30 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:20:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:26:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- method `bar` has generic type parameters + | --- ...because method `bar` has generic type parameters ... LL | t as &dyn Bar | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr index 1f5c472ddc25a..55baf69401b0a 100644 --- a/src/test/ui/object-safety/object-safety-issue-22040.stderr +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Expr` cannot be made into an object LL | elements: Vec>, | ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 2123e306b16a4..e90f9b6d0a0cc 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,20 +1,28 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:22:30 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- method `bar` references the `Self` type in its parameters or return type + | --- ...because method `bar` references the `Self` type in its parameters or return type ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object + | + = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:28:30 | +LL | trait Baz { + | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- method `baz` references the `Self` type in its parameters or return type + | --- ...because method `baz` references the `Self` type in its parameters or return type ... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ the trait `Baz` cannot be made into an object + | + = help: consider moving `baz` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 03b2b8da07533..4a23fb56e91a9 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -1,24 +1,30 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:24:5 | +LL | trait Bar { + | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- method `bar` references the `Self` type in its parameters or return type + | --- ...because method `bar` references the `Self` type in its parameters or return type ... LL | t | ^ the trait `Bar` cannot be made into an object | + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:30:5 | +LL | trait Baz { + | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- method `baz` references the `Self` type in its parameters or return type + | --- ...because method `baz` references the `Self` type in its parameters or return type ... LL | t | ^ the trait `Baz` cannot be made into an object | + = help: consider moving `baz` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Baz>` for `&T` = note: required by cast to type `&dyn Baz` diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 099876c562aec..2f79d53d1c124 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:12:18 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo() {} - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | fn diverges() -> Box { | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index 91a9285b63ccc..bed6757fc6803 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:22:27 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo() {} - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let b: Box = Box::new(Bar); | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 49f98e0085082..2f605d8e904c5 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,8 +1,10 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | +LL | trait Bar + | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ...because it requires `Self: Sized` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 9b189c48f9301..2f1f06f4cf5fa 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -1,8 +1,10 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | +LL | trait Bar + | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ...because it requires `Self: Sized` ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 3b588034e3322..54f65c43d9cde 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | LL | trait Bar : Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | --- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 6b60eef30d3d3..58c2b7721474f 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | LL | trait Bar : Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | --- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 8ae89832703d1..04f630d5dacb7 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^ the trait `Baz` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 1d6b378b9c8a7..d0c278d12d70a 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object LL | fn bar(_x: Foo) {} | ^^^ the trait `issue_3907::Foo` cannot be made into an object | - = note: associated function `bar` has no `self` parameter + = note: the trait cannot be made into an object because associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 653ccb9db949a..c06538fae3b4e 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -1,21 +1,28 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = help: consider changing method `foo`'s `self` parameter to be `&self` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index 33f1fa2e51be3..bebd5cbcf780c 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -1,12 +1,15 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | +LL | trait Foo { + | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on + | --- ...because method `foo`'s `self` parameter cannot be dispatched on ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | + = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 4a9242b1f4fac..55185a2c8cdd1 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -15,7 +15,9 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 | LL | trait A: Sized { - | ----- traits that require `Self: Sized` cannot be made into an object + | - ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... LL | fn f(a: A) -> A; | ^ the trait `A` cannot be made into an object @@ -35,10 +37,14 @@ LL | fn f(a: Self) -> Self; error[E0038]: the trait `B` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 | +LL | trait B { + | - this trait cannot be made into an object... LL | fn f(a: B) -> B; | - ^ the trait `B` cannot be made into an object | | - | associated function `f` has no `self` parameter + | ...because associated function `f` has no `self` parameter + | + = help: consider turning `f` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 5551b1303b927..1f9ffb6a4cfbf 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object | - = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses + = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified --> $DIR/trait-alias-object-fail.rs:9:17 diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 4df8845de279a..e050d6940abc3 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -111,16 +111,22 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | LL | const A: u8 = 0; - | - the trait cannot contain associated consts like `A` + | - ...because it cannot contain associated consts like `A` ... LL | const B: u8 = 0; - | - the trait cannot contain associated consts like `B` + | - ...because it cannot contain associated consts like `B` ... +LL | pub trait C: A + B { + | - this trait cannot be made into an object... LL | const C: u8 = 0; - | - the trait cannot contain associated consts like `C` + | - ...because it cannot contain associated consts like `C` ... LL | C::A; | ^^^^ the trait `assoc_const::C` cannot be made into an object + | + = help: consider moving `C` to another trait + = help: consider moving `B` to another trait + = help: consider moving `A` to another trait error[E0223]: ambiguous associated type --> $DIR/trait-item-privacy.rs:115:12 diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index f41ebf4166d06..a8511f63c16a5 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -10,7 +10,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | m!(dyn Copy + Send + 'static); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 028e9eedd641a..5eb8cd0d80636 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -1,23 +1,30 @@ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:22 | +LL | trait Tr { + | -- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` = note: required by cast to type `&dyn Tr` error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 | +LL | trait Tr { + | -- this trait cannot be made into an object... LL | fn foo(); - | --- associated function `foo` has no `self` parameter + | --- ...because associated function `foo` has no `self` parameter ... LL | let _: &dyn Tr = &St; | ^^^^^^^ the trait `Tr` cannot be made into an object + | + = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 9b750d382ec96..5b2b7b51f3dae 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -14,24 +14,31 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- method `blah` has generic type parameters - | | - | method `dup` references the `Self` type in its parameters or return type + | --- --- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its parameters or return type + | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); | ^^^^^^^^^^^^ the trait `bar` cannot be made into an object + | + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:6 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- method `blah` has generic type parameters - | | - | method `dup` references the `Self` type in its parameters or return type + | --- --- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its parameters or return type + | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); | ^^^^^^ the trait `bar` cannot be made into an object | + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<{integer}>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index b315fe9df8afd..fa6c5a92fb437 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -14,10 +14,14 @@ error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } - | --- method `add` references the `Self` type in its parameters or return type + | ----- --- ...because method `add` references the `Self` type in its parameters or return type + | | + | this trait cannot be made into an object... ... LL | let y = x as dyn MyAdd; | ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object + | + = help: consider moving `add` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 7e055d746f676..eefb450155cdb 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t_box: Box = Box::new(S); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -14,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | takes_box(Box::new(S)); | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object @@ -26,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | Box::new(S) as Box; | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 9e7fe7f3e1dfc..5e645382d1b21 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -2,7 +2,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t: &dyn Trait = &S; | ^^ the trait `Trait` cannot be made into an object @@ -14,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | takes_trait(&S); | ^^ the trait `Trait` cannot be made into an object @@ -26,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | &S as &dyn Trait; | ^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index f17391520a32c..1c530ece29580 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -25,7 +25,7 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object LL | fn bar() where Vec:, {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object | - = note: traits that require `Self: Sized` cannot be made into an object + = note: the trait cannot be made into an object because it requires `Self: Sized` error: aborting due to 3 previous errors diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 0d8441f87e7e7..2ff6383bc80eb 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -1,11 +1,15 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/wf-object-safe.rs:9:13 | +LL | trait A { + | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); - | --- method `foo` references the `Self` type in its parameters or return type + | --- ...because method `foo` references the `Self` type in its parameters or return type ... LL | let _x: &dyn A; | ^^^^^^ the trait `A` cannot be made into an object + | + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 452a2a5e58b7f..9319e3382c2d4 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -16,7 +16,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | Some(()) => &S, | ^^ the trait `Trait` cannot be made into an object @@ -28,7 +30,9 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | LL | trait Trait: Sized {} - | ----- traits that require `Self: Sized` cannot be made into an object + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... ... LL | let t: &dyn Trait = match opt() { | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object From a52ec87a1720bda5a2aac437a909af01cd35e3f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 18:48:35 -0800 Subject: [PATCH 0819/1253] Use more appropriate spans on object unsafe traits and provide structured suggestions when possible --- src/librustc/traits/error_reporting/mod.rs | 10 +- src/librustc/traits/object_safety.rs | 103 +++++++++++++----- src/librustc_hir/hir.rs | 21 ++++ src/librustc_parse/parser/generics.rs | 2 +- ...ce-impl-trait-for-trait-object-safe.stderr | 2 +- src/test/ui/error-codes/E0033-teach.stderr | 5 +- src/test/ui/error-codes/E0033.stderr | 5 +- src/test/ui/error-codes/E0038.stderr | 2 +- ...ature-gate-object_safe_for_dispatch.stderr | 7 +- ...-trait-in-return-position-dyn-trait.stderr | 10 +- src/test/ui/issues/issue-19380.stderr | 5 +- .../object-safety-mentions-Self.curr.stderr | 4 +- ...tions-Self.object_safe_for_dispatch.stderr | 4 +- .../object-safety-no-static.curr.stderr | 5 +- ...-no-static.object_safe_for_dispatch.stderr | 5 +- ...ary-self-types-not-object-safe.curr.stderr | 13 ++- ...bject-safe.object_safe_for_dispatch.stderr | 6 +- ...object-unsafe-trait-should-use-self.stderr | 5 +- src/test/ui/traits/trait-object-safety.stderr | 10 +- src/test/ui/traits/trait-test-2.stderr | 12 +- ...ter-defaults-referencing-Self-ppaux.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 2 +- 22 files changed, 178 insertions(+), 62 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f2cc8a303a952..0ea0f271fd60e 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1073,9 +1073,15 @@ pub fn report_object_safety_error( err.span_label(span, &msg); } } - if let (Some(_), Some(note)) = (trait_span, violation.solution()) { + match (trait_span, violation.solution()) { + (Some(_), Some((note, None))) => { + err.help(¬e); + } + (Some(_), Some((note, Some((sugg, span))))) => { + err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable); + } // Only provide the help if its a local trait, otherwise it's not actionable. - err.help(¬e); + _ => {} } } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ac9e4950b72cf..efb46a1b8d3ee 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -13,6 +13,7 @@ use super::elaborate_predicates; use crate::traits::{self, Obligation, ObligationCause}; use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -48,14 +49,20 @@ impl ObjectSafetyViolation { "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" .into() } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => { + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => { format!("associated function `{}` has no `self` parameter", name).into() } - ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!( - "method `{}` references the `Self` type in its parameters or return type", + ObjectSafetyViolation::Method( name, - ) - .into(), + MethodViolationCode::ReferencesSelfInput(_), + DUMMY_SP, + ) => format!("method `{}` references the `Self` type in its parameters", name).into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfInput(_), _) => { + format!("method `{}` references the `Self` type in this parameter", name).into() + } + ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => { + format!("method `{}` references the `Self` type in its return type", name).into() + } ObjectSafetyViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -78,23 +85,31 @@ impl ObjectSafetyViolation { } } - pub fn solution(&self) -> Option { + pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> { Some(match *self { ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { return None; } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => format!( - "consider turning `{}` into a method by giving it a `&self` argument or \ - constraining it with `where Self: Sized`", - name + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => ( + format!( + "consider turning `{}` into a method by giving it a `&self` argument or \ + constraining it so it does not apply to trait objects", + name + ), + sugg.map(|(sugg, sp)| (sugg.to_string(), sp)), ), - ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { + ObjectSafetyViolation::Method( + name, + MethodViolationCode::UndispatchableReceiver, + span, + ) => ( format!("consider changing method `{}`'s `self` parameter to be `&self`", name) - .into() - } + .into(), + Some(("&Self".to_string(), span)), + ), ObjectSafetyViolation::AssocConst(name, _) | ObjectSafetyViolation::Method(name, ..) => { - format!("consider moving `{}` to another trait", name) + (format!("consider moving `{}` to another trait", name), None) } }) } @@ -119,10 +134,13 @@ impl ObjectSafetyViolation { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum MethodViolationCode { /// e.g., `fn foo()` - StaticMethod, + StaticMethod(Option<(&'static str, Span)>), + + /// e.g., `fn foo(&self, x: Self)` + ReferencesSelfInput(usize), - /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self` - ReferencesSelf, + /// e.g., `fn foo(&self) -> Self` + ReferencesSelfOutput, /// e.g., `fn foo(&self) where Self: Clone` WhereClauseReferencesSelf, @@ -193,7 +211,7 @@ fn object_safety_violations_for_trait( .filter(|item| item.kind == ty::AssocKind::Method) .filter_map(|item| { object_safety_violation_for_method(tcx, trait_def_id, &item) - .map(|code| ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)) + .map(|(code, span)| ObjectSafetyViolation::Method(item.ident.name, code, span)) }) .filter(|violation| { if let ObjectSafetyViolation::Method( @@ -224,9 +242,15 @@ fn object_safety_violations_for_trait( ) }; err.span_label(*span, &msg); - if let (Some(_), Some(note)) = (node, violation.solution()) { + match (node, violation.solution()) { + (Some(_), Some((note, None))) => { + err.help(¬e); + } + (Some(_), Some((note, Some((sugg, span))))) => { + err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable); + } // Only provide the help if its a local trait, otherwise it's not actionable. - err.help(¬e); + _ => {} } err.emit(); false @@ -398,7 +422,7 @@ fn object_safety_violation_for_method( tcx: TyCtxt<'_>, trait_def_id: DefId, method: &ty::AssocItem, -) -> Option { +) -> Option<(MethodViolationCode, Span)> { debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self : Sized` requisite is otherwise // exempt from the regulations. @@ -406,7 +430,26 @@ fn object_safety_violation_for_method( return None; } - virtual_call_violation_for_method(tcx, trait_def_id, method) + let violation = virtual_call_violation_for_method(tcx, trait_def_id, method); + // Get an accurate span depending on the violation. + violation.map(|v| { + let node = tcx.hir().get_if_local(method.def_id); + let span = match (v, node) { + (MethodViolationCode::ReferencesSelfInput(arg), Some(node)) => node + .fn_decl() + .and_then(|decl| decl.inputs.get(arg + 1)) + .map_or(method.ident.span, |arg| arg.span), + (MethodViolationCode::UndispatchableReceiver, Some(node)) => node + .fn_decl() + .and_then(|decl| decl.inputs.get(0)) + .map_or(method.ident.span, |arg| arg.span), + (MethodViolationCode::ReferencesSelfOutput, Some(node)) => { + node.fn_decl().map_or(method.ident.span, |decl| decl.output.span()) + } + _ => method.ident.span, + }; + (v, span) + }) } /// Returns `Some(_)` if this method cannot be called on a trait @@ -420,18 +463,26 @@ fn virtual_call_violation_for_method<'tcx>( ) -> Option { // The method's first parameter must be named `self` if !method.method_has_self_argument { - return Some(MethodViolationCode::StaticMethod); + // We'll attempt to provide a structured suggestion for `Self: Sized`. + let sugg = + tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map( + |generics| match generics.where_clause.predicates { + [] => (" where Self: Sized", generics.where_clause.span), + [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()), + }, + ); + return Some(MethodViolationCode::StaticMethod(sugg)); } let sig = tcx.fn_sig(method.def_id); - for input_ty in &sig.skip_binder().inputs()[1..] { + for (i, input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() { if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) { - return Some(MethodViolationCode::ReferencesSelf); + return Some(MethodViolationCode::ReferencesSelfInput(i)); } } if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) { - return Some(MethodViolationCode::ReferencesSelf); + return Some(MethodViolationCode::ReferencesSelfOutput); } // We can't monomorphize things like `fn foo(...)`. diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 0db75454aee38..3ed0ad16eebf2 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2631,4 +2631,25 @@ impl Node<'_> { _ => None, } } + + pub fn fn_decl(&self) -> Option<&FnDecl<'_>> { + match self { + Node::TraitItem(TraitItem { kind: TraitItemKind::Method(fn_sig, _), .. }) + | Node::ImplItem(ImplItem { kind: ImplItemKind::Method(fn_sig, _), .. }) + | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl), + Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => { + Some(fn_decl) + } + _ => None, + } + } + + pub fn generics(&self) -> Option<&Generics<'_>> { + match self { + Node::TraitItem(TraitItem { generics, .. }) + | Node::ImplItem(ImplItem { generics, .. }) + | Node::Item(Item { kind: ItemKind::Fn(_, generics, _), .. }) => Some(generics), + _ => None, + } + } } diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 075583711f5d3..0984263bb283e 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -172,7 +172,7 @@ impl<'a> Parser<'a> { /// ``` pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { let mut where_clause = - WhereClause { predicates: Vec::new(), span: self.prev_span.to(self.prev_span) }; + WhereClause { predicates: Vec::new(), span: self.prev_span.shrink_to_hi() }; if !self.eat_keyword(kw::Where) { return Ok(where_clause); diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index c999cabcc1413..85ed360a1f74a 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -2,7 +2,7 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6 | LL | trait NotObjectSafe { fn eq(&self, other: Self); } - | ------------- -- ...because method `eq` references the `Self` type in its parameters or return type + | ------------- ---- ...because method `eq` references the `Self` type in this parameter | | | this trait cannot be made into an object... LL | impl NotObjectSafe for dyn NotObjectSafe { } diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index 050ea63aa4fa8..f323a9904557a 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -15,7 +15,10 @@ LL | fn foo(); LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033-teach.rs:12:9 diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index c736fbcf92a8e..84481ff16c07e 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -15,7 +15,10 @@ LL | fn foo(); LL | let trait_obj: &dyn SomeTrait = SomeTrait; | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0033]: type `&dyn SomeTrait` cannot be dereferenced --> $DIR/E0033.rs:10:9 diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 62b6f4cf24692..638e924b0eb43 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ---- ...because method `foo` references the `Self` type in its return type ... LL | fn call_foo(x: Box) { | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 2905988066898..c66bbb0c5045f 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -20,7 +20,10 @@ LL | fn static_fn() {} LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object | - = help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn static_fn() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 @@ -41,7 +44,7 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object LL | trait NonObjectSafe4 { | -------------- this trait cannot be made into an object... LL | fn foo(&self, &Self); - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ----- ...because method `foo` references the `Self` type in this parameter ... LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 1443be0b30ebe..9df5188bbdd08 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -9,7 +9,10 @@ LL | fn foo() -> Self; LL | fn car() -> dyn NotObjectSafe { | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 @@ -22,7 +25,10 @@ LL | fn foo() -> Self; LL | fn cat() -> Box { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 22e744f884171..0a080171a7951 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -9,7 +9,10 @@ LL | fn qiz(); LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object | - = help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn qiz() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index e90f9b6d0a0cc..4dbb27b425b32 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- ...because method `bar` references the `Self` type in its parameters or return type + | ----- ...because method `bar` references the `Self` type in this parameter ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object @@ -17,7 +17,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- ...because method `baz` references the `Self` type in its parameters or return type + | ---- ...because method `baz` references the `Self` type in its return type ... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ the trait `Baz` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 4a23fb56e91a9..89b273fb8adde 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); - | --- ...because method `bar` references the `Self` type in its parameters or return type + | ----- ...because method `bar` references the `Self` type in this parameter ... LL | t | ^ the trait `Bar` cannot be made into an object @@ -19,7 +19,7 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; - | --- ...because method `baz` references the `Self` type in its parameters or return type + | ---- ...because method `baz` references the `Self` type in its return type ... LL | t | ^ the trait `Baz` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index 2f79d53d1c124..f878cf8b46241 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -9,7 +9,10 @@ LL | fn foo() {} LL | fn diverges() -> Box { | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index bed6757fc6803..de56843962bea 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -9,9 +9,12 @@ LL | fn foo() {} LL | let b: Box = Box::new(Bar); | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` = note: required by cast to type `std::boxed::Box` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index c06538fae3b4e..7948f7e9d6bc6 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -4,12 +4,13 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = help: consider changing method `foo`'s `self` parameter to be `&self` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 @@ -17,12 +18,14 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index bebd5cbcf780c..74e76b8265f70 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -4,12 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --- ...because method `foo`'s `self` parameter cannot be dispatched on + | --------- + | | + | ...because method `foo`'s `self` parameter cannot be dispatched on + | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = help: consider changing method `foo`'s `self` parameter to be `&self` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` = note: required by cast to type `std::rc::Rc` diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 55185a2c8cdd1..58be59602b9c5 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -44,7 +44,10 @@ LL | fn f(a: B) -> B; | | | ...because associated function `f` has no `self` parameter | - = help: consider turning `f` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `f` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn f(a: B) -> B where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 5eb8cd0d80636..162e9249b880e 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -9,9 +9,12 @@ LL | fn foo(); LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` = note: required by cast to type `&dyn Tr` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 @@ -24,7 +27,10 @@ LL | fn foo(); LL | let _: &dyn Tr = &St; | ^^^^^^^ the trait `Tr` cannot be made into an object | - = help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized` +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Sized; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 5b2b7b51f3dae..9d1eef547568e 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -14,9 +14,9 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- --- ---- ...because method `blah` has generic type parameters - | | | - | | ...because method `dup` references the `Self` type in its parameters or return type + | --- ---- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); @@ -29,9 +29,9 @@ error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:6 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- --- ---- ...because method `blah` has generic type parameters - | | | - | | ...because method `dup` references the `Self` type in its parameters or return type + | --- ---- ---- ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... ... LL | (box 10 as Box).dup(); diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index fa6c5a92fb437..539189982a8d7 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -14,7 +14,7 @@ error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } - | ----- --- ...because method `add` references the `Self` type in its parameters or return type + | ----- ---- ...because method `add` references the `Self` type in its return type | | | this trait cannot be made into an object... ... diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 2ff6383bc80eb..8935d766354fe 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `A` cannot be made into an object LL | trait A { | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); - | --- ...because method `foo` references the `Self` type in its parameters or return type + | ----- ...because method `foo` references the `Self` type in this parameter ... LL | let _x: &dyn A; | ^^^^^^ the trait `A` cannot be made into an object From 542130bde94decf458cdeec2a6d61314fb1f427a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2020 19:04:58 -0800 Subject: [PATCH 0820/1253] add tests for structured suggestion --- .../object-unsafe-trait-references-self.rs | 12 +++++++ ...object-unsafe-trait-references-self.stderr | 30 ++++++++++++++++ ...-unsafe-trait-should-use-where-sized.fixed | 13 +++++++ ...ect-unsafe-trait-should-use-where-sized.rs | 13 +++++++ ...unsafe-trait-should-use-where-sized.stderr | 35 +++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 src/test/ui/suggestions/object-unsafe-trait-references-self.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-references-self.stderr create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs create mode 100644 src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.rs b/src/test/ui/suggestions/object-unsafe-trait-references-self.rs new file mode 100644 index 0000000000000..07bf053e99665 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.rs @@ -0,0 +1,12 @@ +trait Trait { + fn baz(&self, _: Self) {} + fn bat(&self) -> Self {} +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other: Sized {} + +fn foo(x: &dyn Other) {} //~ ERROR the trait `Other` cannot be made into an object + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr new file mode 100644 index 0000000000000..c3cfad70bf430 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -0,0 +1,30 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/object-unsafe-trait-references-self.rs:6:11 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | fn baz(&self, _: Self) {} + | ---- ...because method `baz` references the `Self` type in this parameter +LL | fn bat(&self) -> Self {} + | ---- ...because method `bat` references the `Self` type in its return type +... +LL | fn bar(x: &dyn Trait) {} + | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = help: consider moving `baz` to another trait + = help: consider moving `bat` to another trait + +error[E0038]: the trait `Other` cannot be made into an object + --> $DIR/object-unsafe-trait-references-self.rs:10:11 + | +LL | trait Other: Sized {} + | ----- ----- ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... +LL | +LL | fn foo(x: &dyn Other) {} + | ^^^^^^^^^^ the trait `Other` cannot be made into an object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed new file mode 100644 index 0000000000000..c4b8960b65e4a --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed @@ -0,0 +1,13 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] + +trait Trait { + fn foo() where Self: Other, Self: Sized, { } + fn bar(self: &Self) {} //~ ERROR invalid `self` parameter type +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other {} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs new file mode 100644 index 0000000000000..38d9aea16ebf6 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs @@ -0,0 +1,13 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] + +trait Trait { + fn foo() where Self: Other, { } + fn bar(self: ()) {} //~ ERROR invalid `self` parameter type +} + +fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object + +trait Other {} + +fn main() {} diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr new file mode 100644 index 0000000000000..6466a768ecbe9 --- /dev/null +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | fn foo() where Self: Other, { } + | --- ...because associated function `foo` has no `self` parameter +LL | fn bar(self: ()) {} + | -- ...because method `bar`'s `self` parameter cannot be dispatched on +... +LL | fn bar(x: &dyn Trait) {} + | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | +help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | fn foo() where Self: Other, Self: Sized, { } + | ^^^^^^^^^^^^^ +help: consider changing method `bar`'s `self` parameter to be `&self` + | +LL | fn bar(self: &Self) {} + | ^^^^^ + +error[E0307]: invalid `self` parameter type: () + --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18 + | +LL | fn bar(self: ()) {} + | ^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0307. +For more information about an error, try `rustc --explain E0038`. From cb6dfeaf61ae7e0ef5f0d2d1637fa9c385874117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 00:54:13 -0800 Subject: [PATCH 0821/1253] Suggest `?Sized` on type parameters --- src/librustc/traits/error_reporting/mod.rs | 38 +++++++++++++++++++ .../ui/extern/extern-types-unsized.stderr | 4 +- src/test/ui/str/str-mut-idx.stderr | 4 +- src/test/ui/unsized3.stderr | 20 ++++++++-- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 0ea0f271fd60e..0b627f9d15e0a 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1340,6 +1340,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &obligation.cause.code, &mut vec![], ); + self.suggest_unsized_bound_if_applicable(err, obligation); + } + } + + fn suggest_unsized_bound_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + if let ( + ty::Predicate::Trait(pred, _), + ObligationCauseCode::BindingObligation(item_def_id, span), + ) = (&obligation.predicate, &obligation.cause.code) + { + if let (Some(generics), true) = ( + self.tcx.hir().get_if_local(*item_def_id).as_ref().and_then(|n| n.generics()), + Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), + ) { + for param in generics.params { + if param.span == *span + && !param.bounds.iter().any(|bound| { + bound.trait_def_id() == self.tcx.lang_items().sized_trait() + }) + { + let (span, separator) = match param.bounds { + [] => (span.shrink_to_hi(), ":"), + [.., bound] => (bound.span().shrink_to_hi(), " + "), + }; + err.span_suggestion( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{} ?Sized", separator), + Applicability::MachineApplicable, + ); + return; + } + } + } } } diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr index 0417186eed346..0c9165fd9585d 100644 --- a/src/test/ui/extern/extern-types-unsized.stderr +++ b/src/test/ui/extern/extern-types-unsized.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim --> $DIR/extern-types-unsized.rs:22:20 | LL | fn assert_sized() { } - | ------------ - required by this bound in `assert_sized` + | ------------ -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `assert_sized` ... LL | assert_sized::(); | ^ doesn't have a size known at compile-time diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 3c957970e51c2..a9ec6b9c02fe8 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/str-mut-idx.rs:4:15 | LL | fn bot() -> T { loop {} } - | --- - required by this bound in `bot` + | --- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `bot` ... LL | s[1..2] = bot(); | ^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 232296ad09126..0c37828229e34 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -1,8 +1,6 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:7:13 | -LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f2::(x); | ^ doesn't have a size known at compile-time ... @@ -11,12 +9,18 @@ LL | fn f2(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f1(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f2(x: &X) { + | ^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:18:13 | -LL | fn f3(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f4::(x); | ^ doesn't have a size known at compile-time ... @@ -25,6 +29,14 @@ LL | fn f4(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f3(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f4(x: &X) { + | ^^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:33:8 From d216b731f61d85a5cc6cddfdd7f91628bc594b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 01:38:12 -0800 Subject: [PATCH 0822/1253] Remove duplicated code --- src/librustc/traits/error_reporting/mod.rs | 72 ------------------- .../diagnostics/conflict_errors.rs | 2 +- 2 files changed, 1 insertion(+), 73 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 0b627f9d15e0a..6d3719b32d07e 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -27,7 +27,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::source_map::SourceMap; use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; use syntax::ast; @@ -1427,74 +1426,3 @@ impl ArgKind { } } } - -/// Suggest restricting a type param with a new bound. -pub fn suggest_constraining_type_param( - generics: &hir::Generics<'_>, - err: &mut DiagnosticBuilder<'_>, - param_name: &str, - constraint: &str, - source_map: &SourceMap, - span: Span, -) -> bool { - let restrict_msg = "consider further restricting this bound"; - if let Some(param) = - generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() - { - if param_name.starts_with("impl ") { - // `impl Trait` in argument: - // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` - err.span_suggestion( - param.span, - restrict_msg, - // `impl CurrentTrait + MissingTrait` - format!("{} + {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() { - // If there are no bounds whatsoever, suggest adding a constraint - // to the type parameter: - // `fn foo(t: T) {}` → `fn foo(t: T) {}` - err.span_suggestion( - param.span, - "consider restricting this bound", - format!("{}: {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else if !generics.where_clause.predicates.is_empty() { - // There is a `where` clause, so suggest expanding it: - // `fn foo(t: T) where T: Debug {}` → - // `fn foo(t: T) where T: Debug, T: Trait {}` - err.span_suggestion( - generics.where_clause.span().unwrap().shrink_to_hi(), - &format!("consider further restricting type parameter `{}`", param_name), - format!(", {}: {}", param_name, constraint), - Applicability::MachineApplicable, - ); - } else { - // If there is no `where` clause lean towards constraining to the - // type parameter: - // `fn foo(t: T, x: X) {}` → `fn foo(t: T) {}` - // `fn foo(t: T) {}` → `fn foo(t: T) {}` - let sp = param.span.with_hi(span.hi()); - let span = source_map.span_through_char(sp, ':'); - if sp != param.span && sp != span { - // Only suggest if we have high certainty that the span - // covers the colon in `foo`. - err.span_suggestion( - span, - restrict_msg, - format!("{}: {} + ", param_name, constraint), - Applicability::MachineApplicable, - ); - } else { - err.span_label( - param.span, - &format!("consider adding a `where {}: {}` bound", param_name, constraint), - ); - } - } - return true; - } - false -} diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index a8e534a9f650c..810882d3bbdb8 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -3,7 +3,7 @@ use rustc::mir::{ FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; -use rustc::traits::error_reporting::suggest_constraining_type_param; +use rustc::traits::error_reporting::suggestions::suggest_constraining_type_param; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; From 342db717e2aa52decc812084c31fdcbeaf03b255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 02:03:54 -0800 Subject: [PATCH 0823/1253] Account for `?Sized` type parameter bounds --- .../traits/error_reporting/suggestions.rs | 12 ++++++- .../diagnostics/conflict_errors.rs | 2 ++ .../ui/consts/too_generic_eval_ice.stderr | 4 +-- .../dst/dst-object-from-unsized-type.stderr | 4 +-- src/test/ui/issues/issue-27060-2.stderr | 2 +- .../traits/trait-suggest-where-clause.stderr | 4 +-- src/test/ui/union/union-sized-field.stderr | 6 ++-- .../ui/unsized/unsized-bare-typaram.stderr | 4 +-- src/test/ui/unsized/unsized-enum.stderr | 4 +-- src/test/ui/unsized/unsized-enum2.stderr | 8 ++--- .../unsized-inherent-impl-self-type.stderr | 4 +-- src/test/ui/unsized/unsized-struct.stderr | 8 ++--- .../unsized-trait-impl-self-type.stderr | 4 +-- .../unsized-trait-impl-trait-arg.stderr | 4 +-- src/test/ui/unsized3.stderr | 36 ++++++++----------- src/test/ui/unsized5.stderr | 8 ++--- src/test/ui/unsized6.stderr | 30 ++++++++-------- src/test/ui/unsized7.stderr | 4 +-- 18 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 72629c6a3cffa..c1facd34dfee5 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -145,12 +145,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let param_name = self_ty.to_string(); let constraint = trait_ref.print_only_trait_path().to_string(); if suggest_constraining_type_param( + self.tcx, generics, &mut err, ¶m_name, &constraint, self.tcx.sess.source_map(), *span, + Some(trait_ref.def_id()), ) { return; } @@ -1652,18 +1654,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Suggest restricting a type param with a new bound. pub fn suggest_constraining_type_param( + tcx: TyCtxt<'_>, generics: &hir::Generics<'_>, err: &mut DiagnosticBuilder<'_>, param_name: &str, constraint: &str, source_map: &SourceMap, span: Span, + def_id: Option, ) -> bool { let restrict_msg = "consider further restricting this bound"; if let Some(param) = generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() { - if param_name.starts_with("impl ") { + if def_id == tcx.lang_items().sized_trait() { + // Type parameters are already `Sized` by default. + err.span_label( + param.span, + &format!("this type parameter needs to be `{}`", constraint), + ); + } else if param_name.starts_with("impl ") { // `impl Trait` in argument: // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` err.span_suggestion( diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 810882d3bbdb8..b0b9790abb12a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -217,12 +217,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) { suggest_constraining_type_param( + tcx, generics, &mut err, ¶m.name.as_str(), "Copy", tcx.sess.source_map(), span, + None, ); } } diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 599d1d79e7555..fd68cb9c6cf85 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -18,7 +18,7 @@ LL | pub struct Foo(A, B); | --------------------------- required by `Foo` LL | LL | impl Foo { - | - help: consider restricting this bound: `A: std::marker::Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -33,7 +33,7 @@ LL | pub struct Foo(A, B); | --------------------------- required by `Foo` LL | LL | impl Foo { - | - help: consider restricting this bound: `B: std::marker::Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr index 40db575eabd38..80d188bf2f89b 100644 --- a/src/test/ui/dst/dst-object-from-unsized-type.stderr +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:8:23 | LL | fn test1(t: &T) { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:13:23 | LL | fn test2(t: &T) { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/issues/issue-27060-2.stderr b/src/test/ui/issues/issue-27060-2.stderr index 553041c5106c5..1ddea73e00ae0 100644 --- a/src/test/ui/issues/issue-27060-2.stderr +++ b/src/test/ui/issues/issue-27060-2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/issue-27060-2.rs:3:5 | LL | pub struct Bad { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | data: T, | ^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr index 831dd439298d9..9680d58b8c0c7 100644 --- a/src/test/ui/traits/trait-suggest-where-clause.stderr +++ b/src/test/ui/traits/trait-suggest-where-clause.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/trait-suggest-where-clause.rs:11:20 | LL | fn check() { - | -- help: consider further restricting this bound: `U: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | // suggest a where-clause, if needed LL | mem::size_of::(); | ^ doesn't have a size known at compile-time @@ -19,7 +19,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/trait-suggest-where-clause.rs:14:5 | LL | fn check() { - | -- help: consider further restricting this bound: `U: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | mem::size_of::>(); | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index c9fec1d21d152..62dacd064bed0 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:4:5 | LL | union Foo { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:9:5 | LL | struct Foo2 { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | @@ -26,7 +26,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:15:11 | LL | enum Foo3 { - | -- help: consider further restricting this bound: `T: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | Value(T), | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr index bd97b0203b510..772de23e64cf0 100644 --- a/src/test/ui/unsized/unsized-bare-typaram.stderr +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -4,9 +4,9 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim LL | fn bar() { } | --- - required by this bound in `bar` LL | fn foo() { bar::() } - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 341d3e4cc2df2..88f7b1f77aee0 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -5,9 +5,9 @@ LL | enum Foo { FooSome(U), FooNone } | ----------- required by `Foo` LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } - | -- ^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr index e85b6d662f9d5..bc3b3831f3269 100644 --- a/src/test/ui/unsized/unsized-enum2.stderr +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `W` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:23:8 | LL | enum E { - | -- help: consider further restricting this bound: `W: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | // parameter LL | VA(W), | ^ doesn't have a size known at compile-time @@ -15,7 +15,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:25:8 | LL | enum E { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VB{x: X}, | ^^^^ doesn't have a size known at compile-time @@ -28,7 +28,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:27:15 | LL | enum E { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VC(isize, Y), | ^ doesn't have a size known at compile-time @@ -41,7 +41,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:29:18 | LL | enum E { - | -- help: consider further restricting this bound: `Z: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | VD{u: isize, x: Z}, | ^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 280b8fd43cab0..5688ae5b89a04 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -5,9 +5,9 @@ LL | struct S5(Y); | ---------------- required by `S5` LL | LL | impl S5 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index 2894d5d56710d..653fb5c1ae8dc 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -5,9 +5,9 @@ LL | struct Foo { data: T } | ------------- required by `Foo` LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } - | -- ^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit @@ -19,9 +19,9 @@ LL | fn is_sized() { } | -------- - required by this bound in `is_sized` ... LL | fn bar2() { is_sized::>() } - | -- ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `T: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: within `Bar`, the trait `std::marker::Sized` is not implemented for `T` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index ba1550439c0d9..3597073e7e6c6 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -5,9 +5,9 @@ LL | struct S5(Y); | ---------------- required by `S5` LL | LL | impl T3 for S5 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr index 41371d63f9e53..b37d9f9d5369e 100644 --- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -2,9 +2,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized-trait-impl-trait-arg.rs:8:17 | LL | impl T2 for S4 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 0c37828229e34..e97d00fc4741d 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -1,42 +1,34 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:7:13 | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` LL | f2::(x); | ^ doesn't have a size known at compile-time ... LL | fn f2(x: &X) { - | -- - required by this bound in `f2` + | -- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `f2` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit -help: consider further restricting this bound - | -LL | fn f1(x: &X) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider relaxing the implicit `Sized` restriction - | -LL | fn f2(x: &X) { - | ^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:18:13 | +LL | fn f3(x: &X) { + | - this type parameter needs to be `std::marker::Sized` LL | f4::(x); | ^ doesn't have a size known at compile-time ... LL | fn f4(x: &X) { - | -- - required by this bound in `f4` + | -- - - help: consider relaxing the implicit `Sized` restriction: `+ ?Sized` + | | + | required by this bound in `f4` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit -help: consider further restricting this bound - | -LL | fn f3(x: &X) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider relaxing the implicit `Sized` restriction - | -LL | fn f4(x: &X) { - | ^^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:33:8 @@ -45,7 +37,7 @@ LL | fn f5(x: &Y) {} | -- - required by this bound in `f5` ... LL | fn f8(x1: &S, x2: &S) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(x1); | ^^ doesn't have a size known at compile-time | @@ -57,7 +49,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:40:8 | LL | fn f9(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(*x1, 34)); | ^^^^^^^^^^ doesn't have a size known at compile-time | @@ -70,7 +62,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:45:9 | LL | fn f10(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^ doesn't have a size known at compile-time | @@ -87,7 +79,7 @@ LL | fn f5(x: &Y) {} | -- - required by this bound in `f5` ... LL | fn f10(x1: Box>) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized5.stderr b/src/test/ui/unsized5.stderr index bfd3f4aa691eb..de4da309791c0 100644 --- a/src/test/ui/unsized5.stderr +++ b/src/test/ui/unsized5.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:4:5 | LL | struct S1 { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f1: X, | ^^^^^ doesn't have a size known at compile-time | @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:10:5 | LL | struct S2 { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | f: isize, LL | g: X, | ^^^^ doesn't have a size known at compile-time @@ -47,7 +47,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:25:8 | LL | enum E { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | V1(X, isize), | ^ doesn't have a size known at compile-time | @@ -59,7 +59,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:29:8 | LL | enum F { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | V2{f1: X, f: isize}, | ^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr index 95acd987a5a27..337afd2ee7e10 100644 --- a/src/test/ui/unsized6.stderr +++ b/src/test/ui/unsized6.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:9:9 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: Y; | ^ doesn't have a size known at compile-time @@ -16,7 +16,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:7:12 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let _: W; // <-- this is OK, no bindings created, no initializer. LL | let _: (isize, (X, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -29,7 +29,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized6.rs:11:12 | LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `Z: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Z, usize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -42,7 +42,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:15:9 | LL | fn f2(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X; | ^ doesn't have a size known at compile-time | @@ -55,7 +55,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:17:12 | LL | fn f2(x: &X) { - | -- help: consider further restricting this bound: `Y: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Y, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -68,7 +68,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:22:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -81,7 +81,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:24:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -95,7 +95,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:26:10 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -109,7 +109,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:30:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -122,7 +122,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:32:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -136,7 +136,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:34:10 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -150,9 +150,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:38:18 | LL | fn g1(x: X) {} - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit @@ -163,9 +163,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:40:22 | LL | fn g2(x: X) {} - | -- ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit diff --git a/src/test/ui/unsized7.stderr b/src/test/ui/unsized7.stderr index c77503a6f87aa..0f71c5f6f8fe6 100644 --- a/src/test/ui/unsized7.stderr +++ b/src/test/ui/unsized7.stderr @@ -2,9 +2,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized7.rs:12:21 | LL | impl T1 for S3 { - | -- ^^^^^ doesn't have a size known at compile-time + | - ^^^^^ doesn't have a size known at compile-time | | - | help: consider further restricting this bound: `X: std::marker::Sized +` + | this type parameter needs to be `std::marker::Sized` | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit From d2b88b7050b0e21b136022c4cfe8d352c1425588 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 2 Feb 2020 21:17:49 +0100 Subject: [PATCH 0824/1253] move_ref_pattern: test captures inside closure --- ...ve-ref-patterns-closure-captures-inside.rs | 122 ++++++ ...ef-patterns-closure-captures-inside.stderr | 404 ++++++++++++++++++ 2 files changed, 526 insertions(+) create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs new file mode 100644 index 0000000000000..4c3ca62e16586 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs @@ -0,0 +1,122 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct S; // Not `Copy`. + + let mut tup0 = (S, S); + let mut tup1 = (S, S, S); + let tup2 = (S, S); + let tup3 = (S, S, S); + let tup4 = (S, S); + let mut arr0 = [S, S, S]; + let mut arr1 = [S, S, S, S, S]; + let arr2 = [S, S, S]; + let arr3 = [S, S, S, S, S]; + + // The `mov` bindings require that we capture the scrutinees by-move. + let mut closure = || { + // Tuples... + let (ref mut borrow, mov) = tup0; + let (mov, _, ref mut borrow) = tup1; + let (ref borrow, mov) = tup2; + let (mov, _, ref borrow) = tup3; + let (ref borrow, mov) = tup4; + // Arrays... + let [mov @ .., ref borrow] = arr0; + let [_, ref mut borrow @ .., _, mov] = arr1; + let [mov @ .., ref borrow] = arr2; + let [_, ref borrow @ .., _, mov] = arr3; + }; + + // Now we try to borrow and move the captures, which should result in errors... + // ...for tuples: + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + // Ostensibly this should compile. + // However, because closures don't capture individual fields, which is changed in RFC 2229, + // this won't compile because the entire product is moved into the closure. + // The same applies to the array patterns below. + drop(&tup4.0); //~ ERROR borrow of moved value: `tup4` + // ...for arrays: + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + let [_, mov1, mov2, mov3, _] = &arr1; //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + let [_, mov1, mov2, mov3, _] = &arr3; //~ ERROR borrow of moved value: `arr3` + + // Let's redo ^--- with a `match` + sum type: + macro_rules! m { + ($p:pat = $s:expr) => { + match $s { + Some($p) => {} + _ => {} + } + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4` + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3` + + // Let's redo ^--- with `if let` (which may diverge from `match` in the future): + macro_rules! m { + ($p:pat = $s:expr) => { + if let Some($p) = $s {} + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4` + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3` +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr new file mode 100644 index 0000000000000..9159e3e221349 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr @@ -0,0 +1,404 @@ +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:33:10 + | +LL | let mut tup0 = (S, S); + | -------- move occurs because `tup0` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | // Tuples... +LL | let (ref mut borrow, mov) = tup0; + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:34:10 + | +LL | let mut tup1 = (S, S, S); + | -------- move occurs because `tup1` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (mov, _, ref mut borrow) = tup1; + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:35:10 + | +LL | let tup2 = (S, S); + | ---- move occurs because `tup2` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (ref borrow, mov) = tup2; + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:36:10 + | +LL | let tup3 = (S, S, S); + | ---- move occurs because `tup3` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (mov, _, ref borrow) = tup3; + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:41:10 + | +LL | let tup4 = (S, S); + | ---- move occurs because `tup4` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (ref borrow, mov) = tup4; + | ---- variable moved due to use in closure +... +LL | drop(&tup4.0); + | ^^^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:43:10 + | +LL | let mut arr0 = [S, S, S]; + | -------- move occurs because `arr0` has type `[main::S; 3]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [mov @ .., ref borrow] = arr0; + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:44:36 + | +LL | let mut arr1 = [S, S, S, S, S]; + | -------- move occurs because `arr1` has type `[main::S; 5]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [_, ref mut borrow @ .., _, mov] = arr1; + | ---- variable moved due to use in closure +... +LL | let [_, mov1, mov2, mov3, _] = &arr1; + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:45:10 + | +LL | let arr2 = [S, S, S]; + | ---- move occurs because `arr2` has type `[main::S; 3]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [mov @ .., ref borrow] = arr2; + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:46:36 + | +LL | let arr3 = [S, S, S, S, S]; + | ---- move occurs because `arr3` has type `[main::S; 5]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [_, ref borrow @ .., _, mov] = arr3; + | ---- variable moved due to use in closure +... +LL | let [_, mov1, mov2, mov3, _] = &arr3; + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10 + | +LL | let mut tup0: Option<(S, S)> = None; + | -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10 + | +LL | let mut tup1: Option<(S, S, S)> = None; + | -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); +LL | m!((mov, _, ref mut borrow) = tup1); + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:79:10 + | +LL | let tup2: Option<(S, S)> = None; + | ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup2); + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10 + | +LL | let tup3: Option<(S, S, S)> = None; + | ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((mov, _, ref borrow) = tup3); + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:81:21 + | +LL | let tup4: Option<(S, S)> = None; + | ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup4); + | ---- variable moved due to use in closure +... +LL | m!((ref x, _) = &tup4); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10 + | +LL | let mut arr0: Option<[S; 3]> = None; + | -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr0); + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35 + | +LL | let mut arr1: Option<[S; 5]> = None; + | -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref mut borrow @ .., _, mov] = arr1); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:84:10 + | +LL | let arr2: Option<[S; 3]> = None; + | ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +LL | let arr3: Option<[S; 5]> = None; +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr2); + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:85:35 + | +LL | let arr3: Option<[S; 5]> = None; + | ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref borrow @ .., _, mov] = arr3); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:113:10 + | +LL | let mut tup0: Option<(S, S)> = None; + | -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:114:10 + | +LL | let mut tup1: Option<(S, S, S)> = None; + | -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); +LL | m!((mov, _, ref mut borrow) = tup1); + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:115:10 + | +LL | let tup2: Option<(S, S)> = None; + | ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup2); + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:116:10 + | +LL | let tup3: Option<(S, S, S)> = None; + | ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((mov, _, ref borrow) = tup3); + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:117:21 + | +LL | let tup4: Option<(S, S)> = None; + | ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup4); + | ---- variable moved due to use in closure +... +LL | m!((ref x, _) = &tup4); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:118:10 + | +LL | let mut arr0: Option<[S; 3]> = None; + | -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr0); + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:119:35 + | +LL | let mut arr1: Option<[S; 5]> = None; + | -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref mut borrow @ .., _, mov] = arr1); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:120:10 + | +LL | let arr2: Option<[S; 3]> = None; + | ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +LL | let arr3: Option<[S; 5]> = None; +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr2); + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:121:35 + | +LL | let arr3: Option<[S; 5]> = None; + | ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref borrow @ .., _, mov] = arr3); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr3); + | ^^^^^ value borrowed here after move + +error: aborting due to 27 previous errors + +For more information about this error, try `rustc --explain E0382`. From 16d935e72582ad833aed735022cdf3808b229e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 12:50:07 -0800 Subject: [PATCH 0825/1253] fix rebase --- .../bad-bounds-on-assoc-in-trait.stderr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 5713e259362fd..efd5a92a4fced 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -7,7 +7,7 @@ LL | impl Case1 for S1 { = help: the trait `for<'a> std::fmt::Debug` is not implemented for `>::App` error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | fn assume_case1() { | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` @@ -17,7 +17,7 @@ LL | fn assume_case1() { = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` @@ -30,7 +30,7 @@ LL | fn assume_case1() { = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` @@ -43,7 +43,7 @@ LL | fn assume_case1() { = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` - --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1 + --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | trait Case1 { | ----------- required by `Case1` From 865216b3ad4158e31d583f5f3cae12afe91c52d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 12:51:30 -0800 Subject: [PATCH 0826/1253] Point at reason in object unsafe trait with `Self` in supertraits or `where`-clause --- src/librustc/traits/object_safety.rs | 54 +++++++++++++------ src/test/ui/issues/issue-26056.stderr | 7 ++- src/test/ui/issues/issue-28576.stderr | 9 +++- src/test/ui/issues/issue-38404.stderr | 6 ++- src/test/ui/issues/issue-38604.stderr | 13 +++-- .../object-safety-issue-22040.stderr | 7 ++- ...ect-safety-supertrait-mentions-Self.stderr | 7 ++- .../trait-alias-object-fail.stderr | 5 +- 8 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index efb46a1b8d3ee..2745d3205dec0 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -32,7 +32,7 @@ pub enum ObjectSafetyViolation { /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). - SupertraitSelf, + SupertraitSelf(SmallVec<[Span; 1]>), /// Method has something illegal. Method(ast::Name, MethodViolationCode, Span), @@ -45,9 +45,13 @@ impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), - ObjectSafetyViolation::SupertraitSelf => { - "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" - .into() + ObjectSafetyViolation::SupertraitSelf(ref spans) => { + if spans.iter().any(|sp| *sp != DUMMY_SP) { + "it uses `Self` as a type parameter in this".into() + } else { + "it cannot use `Self` as a type parameter in a supertrait or `where`-clause" + .into() + } } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => { format!("associated function `{}` has no `self` parameter", name).into() @@ -87,7 +91,7 @@ impl ObjectSafetyViolation { pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> { Some(match *self { - ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => { + ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => { return None; } ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => ( @@ -118,7 +122,8 @@ impl ObjectSafetyViolation { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. match self { - ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), + ObjectSafetyViolation::SupertraitSelf(spans) + | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(), ObjectSafetyViolation::AssocConst(_, span) | ObjectSafetyViolation::Method(_, _, span) if *span != DUMMY_SP => @@ -162,8 +167,9 @@ pub fn astconv_object_safety_violations( ) -> Vec { debug_assert!(tcx.generics_of(trait_def_id).has_self); let violations = traits::supertrait_def_ids(tcx, trait_def_id) - .filter(|&def_id| predicates_reference_self(tcx, def_id, true)) - .map(|_| ObjectSafetyViolation::SupertraitSelf) + .map(|def_id| predicates_reference_self(tcx, def_id, true)) + .filter(|spans| !spans.is_empty()) + .map(|spans| ObjectSafetyViolation::SupertraitSelf(spans)) .collect(); debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations); @@ -266,8 +272,9 @@ fn object_safety_violations_for_trait( let spans = get_sized_bounds(tcx, trait_def_id); violations.push(ObjectSafetyViolation::SizedSelf(spans)); } - if predicates_reference_self(tcx, trait_def_id, false) { - violations.push(ObjectSafetyViolation::SupertraitSelf); + let spans = predicates_reference_self(tcx, trait_def_id, false); + if !spans.is_empty() { + violations.push(ObjectSafetyViolation::SupertraitSelf(spans)); } violations.extend( @@ -337,7 +344,11 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> .unwrap_or_else(SmallVec::new) } -fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool { +fn predicates_reference_self( + tcx: TyCtxt<'_>, + trait_def_id: DefId, + supertraits_only: bool, +) -> SmallVec<[Span; 1]> { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { tcx.super_predicates_of(trait_def_id) @@ -349,12 +360,16 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o predicates .predicates .iter() - .map(|(predicate, _)| predicate.subst_supertrait(tcx, &trait_ref)) - .any(|predicate| { + .map(|(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) + .filter_map(|(predicate, &sp)| { match predicate { ty::Predicate::Trait(ref data, _) => { // In the case of a trait predicate, we can skip the "self" type. - data.skip_binder().input_types().skip(1).any(has_self_ty) + if data.skip_binder().input_types().skip(1).any(has_self_ty) { + Some(sp) + } else { + None + } } ty::Predicate::Projection(ref data) => { // And similarly for projections. This should be redundant with @@ -369,12 +384,18 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o // // This is ALT2 in issue #56288, see that for discussion of the // possible alternatives. - data.skip_binder() + if data + .skip_binder() .projection_ty .trait_ref(tcx) .input_types() .skip(1) .any(has_self_ty) + { + Some(sp) + } else { + None + } } ty::Predicate::WellFormed(..) | ty::Predicate::ObjectSafe(..) @@ -382,9 +403,10 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o | ty::Predicate::RegionOutlives(..) | ty::Predicate::ClosureKind(..) | ty::Predicate::Subtype(..) - | ty::Predicate::ConstEvaluatable(..) => false, + | ty::Predicate::ConstEvaluatable(..) => None, } }) + .collect() } fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr index 2744fb91d6fe1..be438ef9ac7ba 100644 --- a/src/test/ui/issues/issue-26056.stderr +++ b/src/test/ui/issues/issue-26056.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Map` cannot be made into an object --> $DIR/issue-26056.rs:20:13 | +LL | trait Map: MapLookup<::Key> { + | --- ----------------------------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | as &dyn Map; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr index 5bed9a77d1891..658199003c18d 100644 --- a/src/test/ui/issues/issue-28576.stderr +++ b/src/test/ui/issues/issue-28576.stderr @@ -1,11 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-28576.rs:7:12 | +LL | pub trait Bar: Foo { + | --- ------------- + | | | | + | | | ...because it uses `Self` as a type parameter in this + | | ...because it uses `Self` as a type parameter in this + | this trait cannot be made into an object... +LL | fn new(&self, b: & LL | / dyn Bar LL | | | |________________________^ the trait `Bar` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr index 613888758cab4..50c5195dc93b0 100644 --- a/src/test/ui/issues/issue-38404.stderr +++ b/src/test/ui/issues/issue-38404.stderr @@ -1,10 +1,12 @@ error[E0038]: the trait `B` cannot be made into an object --> $DIR/issue-38404.rs:3:15 | +LL | trait A: std::ops::Add + Sized {} + | ------------------- ...because it uses `Self` as a type parameter in this +LL | trait B: A {} + | - this trait cannot be made into an object... LL | trait C: A> {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index b3ad71e174a97..2bba50e1f41c8 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -1,18 +1,25 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:14:13 | +LL | trait Foo where u32: Q { + | --- ------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | let _f: Box = | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 | +LL | trait Foo where u32: Q { + | --- ------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | Box::new(()); | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<()>` = note: required by cast to type `std::boxed::Box` diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr index 55baf69401b0a..fe9ca5b6fa4b7 100644 --- a/src/test/ui/object-safety/object-safety-issue-22040.stderr +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Expr` cannot be made into an object --> $DIR/object-safety-issue-22040.rs:12:23 | +LL | trait Expr: Debug + PartialEq { + | ---- --------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | elements: Vec>, | ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 04f630d5dacb7..ef7f6bacd1233 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -1,10 +1,13 @@ error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31 | +LL | trait Baz : Bar { + | --- --------- ...because it uses `Self` as a type parameter in this + | | + | this trait cannot be made into an object... +... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^ the trait `Baz` cannot be made into an object - | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses error: aborting due to previous error diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 1f9ffb6a4cfbf..56ecb7256f8cd 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -3,8 +3,11 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object | LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object + | + ::: $SRC_DIR/libcore/cmp.rs:LL:COL | - = note: the trait cannot be made into an object because it cannot use `Self` as a type parameter in the supertraits or `where`-clauses +LL | pub trait Eq: PartialEq { + | --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified --> $DIR/trait-alias-object-fail.rs:9:17 From 91cf0e741186a9fa3bf31b07a65dc89324c10296 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 30 Jan 2020 20:24:44 +0000 Subject: [PATCH 0827/1253] Don't requery the param_env of a union Union fields have the ParamEnv of the union. --- src/librustc_typeck/check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0a917a1853eb5..8d2cfd9a335d1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1545,11 +1545,11 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool { if let ty::Adt(def, substs) = item_type.kind { assert!(def.is_union()); let fields = &def.non_enum_variant().fields; + let param_env = tcx.param_env(item_def_id); for field in fields { let field_ty = field.ty(tcx, substs); // We are currently checking the type this field came from, so it must be local. let field_span = tcx.hir().span_if_local(field.did).unwrap(); - let param_env = tcx.param_env(field.did); if field_ty.needs_drop(tcx, param_env) { struct_span_err!( tcx.sess, From 570c1613c1225d5777af5603dcf526da9cf57e19 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 30 Jan 2020 20:25:39 +0000 Subject: [PATCH 0828/1253] Remove unnecessary features in rustc_ty --- src/librustc_ty/lib.rs | 2 -- src/librustc_ty/ty.rs | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs index e5ec98743e0ae..e970faef02f28 100644 --- a/src/librustc_ty/lib.rs +++ b/src/librustc_ty/lib.rs @@ -6,9 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] -#![feature(in_band_lifetimes)] #![feature(nll)] -#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 8f882be1a090e..a131b11b07ba3 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -9,7 +9,11 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_span::symbol::Symbol; use rustc_span::Span; -fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>) -> Vec> { +fn sized_constraint_for_ty<'tcx>( + tcx: TyCtxt<'tcx>, + adtdef: &ty::AdtDef, + ty: Ty<'tcx>, +) -> Vec> { use ty::TyKind::*; let result = match ty.kind { From 39733223fc817efba52a4204dd697192bf5da185 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 30 Jan 2020 20:26:36 +0000 Subject: [PATCH 0829/1253] Add IS_MANUALLY_DROP to AdtFlags --- src/librustc/ty/mod.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..2b272d7fe08af 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1792,19 +1792,22 @@ bitflags! { const IS_STRUCT = 1 << 2; /// Indicates whether the ADT is a struct and has a constructor. const HAS_CTOR = 1 << 3; - /// Indicates whether the type is a `PhantomData`. + /// Indicates whether the type is `PhantomData`. const IS_PHANTOM_DATA = 1 << 4; /// Indicates whether the type has a `#[fundamental]` attribute. const IS_FUNDAMENTAL = 1 << 5; - /// Indicates whether the type is a `Box`. + /// Indicates whether the type is `Box`. const IS_BOX = 1 << 6; + /// Indicates whether the type is `ManuallyDrop`. + const IS_MANUALLY_DROP = 1 << 7; + // FIXME(matthewjasper) replace these with diagnostic items /// Indicates whether the type is an `Arc`. - const IS_ARC = 1 << 7; + const IS_ARC = 1 << 8; /// Indicates whether the type is an `Rc`. - const IS_RC = 1 << 8; + const IS_RC = 1 << 9; /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`. /// (i.e., this flag is never set unless this ADT is an enum). - const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9; + const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 10; } } @@ -2180,6 +2183,9 @@ impl<'tcx> AdtDef { if Some(did) == tcx.lang_items().owned_box() { flags |= AdtFlags::IS_BOX; } + if Some(did) == tcx.lang_items().manually_drop() { + flags |= AdtFlags::IS_MANUALLY_DROP; + } if Some(did) == tcx.lang_items().arc() { flags |= AdtFlags::IS_ARC; } @@ -2280,6 +2286,12 @@ impl<'tcx> AdtDef { self.flags.contains(AdtFlags::IS_BOX) } + /// Returns `true` if this is ManuallyDrop. + #[inline] + pub fn is_manually_drop(&self) -> bool { + self.flags.contains(AdtFlags::IS_MANUALLY_DROP) + } + /// Returns `true` if this type has a destructor. pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() From d1965216a34dc2831cf44d2e15ad9d78403d10cc Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 30 Jan 2020 20:28:16 +0000 Subject: [PATCH 0830/1253] Improve needs_drop query * Handle cycles in `needs_drop` correctly * Normalize types when computing `needs_drop` * Move queries from rustc to rustc_ty --- src/librustc/query/mod.rs | 17 +- src/librustc/traits/misc.rs | 132 -------------- src/librustc/traits/mod.rs | 1 - src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/query/values.rs | 7 - src/librustc/ty/util.rs | 81 ++++++++- src/librustc_ty/common_traits.rs | 40 ++++ src/librustc_ty/lib.rs | 4 + src/librustc_ty/needs_drop.rs | 171 ++++++++++++++++++ .../ui/type-alias-impl-trait/issue-65918.rs | 2 + 10 files changed, 304 insertions(+), 153 deletions(-) create mode 100644 src/librustc_ty/common_traits.rs create mode 100644 src/librustc_ty/needs_drop.rs diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 37d5e23535b81..c705956f4540a 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -651,26 +651,27 @@ rustc_queries! { no_force desc { "computing whether `{}` is `Copy`", env.value } } + /// Query backing `TyS::is_sized`. query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { no_force desc { "computing whether `{}` is `Sized`", env.value } } + /// Query backing `TyS::is_freeze`. query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { no_force desc { "computing whether `{}` is freeze", env.value } } - - // The cycle error here should be reported as an error by `check_representable`. - // We consider the type as not needing drop in the meanwhile to avoid - // further errors (done in impl Value for NeedsDrop). - // Use `cycle_delay_bug` to delay the cycle error here to be emitted later - // in case we accidentally otherwise don't emit an error. - query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop { - cycle_delay_bug + /// Query backing `TyS::needs_drop`. + query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { no_force desc { "computing whether `{}` needs drop", env.value } } + /// A list of types where the ADT requires drop if and only if any of + /// those types require drop. If the ADT is known to always need drop + /// then `Err(AlwaysRequiresDrop)` is returned. + query adt_drop_tys(_: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> {} + query layout_raw( env: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Result<&'tcx ty::layout::LayoutDetails, ty::layout::LayoutError<'tcx>> { diff --git a/src/librustc/traits/misc.rs b/src/librustc/traits/misc.rs index 08c3a77bf3aca..3fd0d12c626aa 100644 --- a/src/librustc/traits/misc.rs +++ b/src/librustc/traits/misc.rs @@ -1,12 +1,9 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. -use crate::middle::lang_items; use crate::traits::{self, ObligationCause}; -use crate::ty::util::NeedsDrop; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_hir as hir; -use rustc_span::DUMMY_SP; #[derive(Clone)] pub enum CopyImplementationError<'tcx> { @@ -71,132 +68,3 @@ pub fn can_type_implement_copy( Ok(()) }) } - -fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - is_item_raw(tcx, query, lang_items::CopyTraitLangItem) -} - -fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - is_item_raw(tcx, query, lang_items::SizedTraitLangItem) -} - -fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - is_item_raw(tcx, query, lang_items::FreezeTraitLangItem) -} - -fn is_item_raw<'tcx>( - tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, - item: lang_items::LangItem, -) -> bool { - let (param_env, ty) = query.into_parts(); - let trait_def_id = tcx.require_lang_item(item, None); - tcx.infer_ctxt().enter(|infcx| { - traits::type_known_to_meet_bound_modulo_regions( - &infcx, - param_env, - ty, - trait_def_id, - DUMMY_SP, - ) - }) -} - -fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop { - let (param_env, ty) = query.into_parts(); - - let needs_drop = |ty: Ty<'tcx>| -> bool { tcx.needs_drop_raw(param_env.and(ty)).0 }; - - assert!(!ty.needs_infer()); - - NeedsDrop(match ty.kind { - // Fast-path for primitive types - ty::Infer(ty::FreshIntTy(_)) - | ty::Infer(ty::FreshFloatTy(_)) - | ty::Bool - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Never - | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Char - | ty::GeneratorWitness(..) - | ty::RawPtr(_) - | ty::Ref(..) - | ty::Str => false, - - // Foreign types can never have destructors - ty::Foreign(..) => false, - - // `ManuallyDrop` doesn't have a destructor regardless of field types. - ty::Adt(def, _) if Some(def.did) == tcx.lang_items().manually_drop() => false, - - // Issue #22536: We first query `is_copy_modulo_regions`. It sees a - // normalized version of the type, and therefore will definitely - // know whether the type implements Copy (and thus needs no - // cleanup/drop/zeroing) ... - _ if ty.is_copy_modulo_regions(tcx, param_env, DUMMY_SP) => false, - - // ... (issue #22536 continued) but as an optimization, still use - // prior logic of asking for the structural "may drop". - - // FIXME(#22815): Note that this is a conservative heuristic; - // it may report that the type "may drop" when actual type does - // not actually have a destructor associated with it. But since - // the type absolutely did not have the `Copy` bound attached - // (see above), it is sound to treat it as having a destructor. - - // User destructors are the only way to have concrete drop types. - ty::Adt(def, _) if def.has_dtor(tcx) => true, - - // Can refer to a type which may drop. - // FIXME(eddyb) check this against a ParamEnv. - ty::Dynamic(..) - | ty::Projection(..) - | ty::Param(_) - | ty::Bound(..) - | ty::Placeholder(..) - | ty::Opaque(..) - | ty::Infer(_) - | ty::Error => true, - - ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - - // Zero-length arrays never contain anything to drop. - ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false, - - // Structural recursion. - ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty), - - ty::Closure(def_id, ref substs) => { - substs.as_closure().upvar_tys(def_id, tcx).any(needs_drop) - } - - // Pessimistically assume that all generators will require destructors - // as we don't know if a destructor is a noop or not until after the MIR - // state transformation pass - ty::Generator(..) => true, - - ty::Tuple(..) => ty.tuple_fields().any(needs_drop), - - // unions don't have destructors because of the child types, - // only if they manually implement `Drop` (handled above). - ty::Adt(def, _) if def.is_union() => false, - - ty::Adt(def, substs) => def - .variants - .iter() - .any(|variant| variant.fields.iter().any(|field| needs_drop(field.ty(tcx, substs)))), - }) -} - -pub fn provide(providers: &mut ty::query::Providers<'_>) { - *providers = ty::query::Providers { - is_copy_raw, - is_sized_raw, - is_freeze_raw, - needs_drop_raw, - ..*providers - }; -} diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index daaba95cf6b13..f6c939c1ce5a2 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1255,7 +1255,6 @@ impl<'tcx> TraitObligation<'tcx> { } pub fn provide(providers: &mut ty::query::Providers<'_>) { - misc::provide(providers); *providers = ty::query::Providers { is_object_safe: object_safety::is_object_safe_provider, specialization_graph_of: specialize::specialization_graph_provider, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 973cd81014616..4126b161a821b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -33,7 +33,7 @@ use crate::traits::Clauses; use crate::traits::{self, Vtable}; use crate::ty::steal::Steal; use crate::ty::subst::SubstsRef; -use crate::ty::util::NeedsDrop; +use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use crate::util::common::ErrorReported; use rustc_data_structures::fingerprint::Fingerprint; diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index 900a91fe5cf59..b01d15c29b2db 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -1,4 +1,3 @@ -use crate::ty::util::NeedsDrop; use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt}; use rustc_span::symbol::Symbol; @@ -26,12 +25,6 @@ impl<'tcx> Value<'tcx> for ty::SymbolName { } } -impl<'tcx> Value<'tcx> for NeedsDrop { - fn from_cycle_error(_: TyCtxt<'tcx>) -> Self { - NeedsDrop(false) - } -} - impl<'tcx> Value<'tcx> for AdtSizedConstraint<'tcx> { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err])) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 4dfff85d53147..eaa7a43b09174 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -18,6 +18,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_span::Span; +use smallvec::SmallVec; use std::{cmp, fmt}; use syntax::ast; @@ -724,7 +725,23 @@ impl<'tcx> ty::TyS<'tcx> { /// Note that this method is used to check eligible types in unions. #[inline] pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { - tcx.needs_drop_raw(param_env.and(self)).0 + // Avoid querying in simple cases. + match needs_drop_components(self) { + Err(AlwaysRequiresDrop) => true, + Ok(components) => { + let query_ty = match *components { + [] => return false, + // If we've got a single component, call the query with that + // to increase the chance that we hit the query cache. + [component_ty] => component_ty, + _ => self, + }; + // This doesn't depend on regions, so try to minimize distinct. + // query keys used. + let erased = tcx.normalize_erasing_regions(param_env, query_ty); + tcx.needs_drop_raw(param_env.and(erased)) + } + } } pub fn same_type(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { @@ -923,9 +940,6 @@ impl<'tcx> ty::TyS<'tcx> { } } -#[derive(Clone, HashStable)] -pub struct NeedsDrop(pub bool); - pub enum ExplicitSelf<'tcx> { ByValue, ByReference(ty::Region<'tcx>, hir::Mutability), @@ -974,3 +988,62 @@ impl<'tcx> ExplicitSelf<'tcx> { } } } + +/// Returns a list of types such that the given type needs drop if and only if +/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if +/// this type always needs drop. +pub fn needs_drop_components(ty: Ty<'tcx>) -> Result; 4]>, AlwaysRequiresDrop> { + match ty.kind { + ty::Infer(ty::FreshIntTy(_)) + | ty::Infer(ty::FreshFloatTy(_)) + | ty::Bool + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Never + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Char + | ty::GeneratorWitness(..) + | ty::RawPtr(_) + | ty::Ref(..) + | ty::Str => Ok(SmallVec::new()), + + // Foreign types can never have destructors + ty::Foreign(..) => Ok(SmallVec::new()), + + // Pessimistically assume that all generators will require destructors + // as we don't know if a destructor is a noop or not until after the MIR + // state transformation pass + ty::Generator(..) | ty::Dynamic(..) | ty::Error => Err(AlwaysRequiresDrop), + + ty::Slice(ty) => needs_drop_components(ty), + ty::Array(elem_ty, ..) => { + match needs_drop_components(elem_ty) { + Ok(v) if v.is_empty() => Ok(v), + // Arrays of size zero don't need drop, even if their element + // type does. + _ => Ok(smallvec![ty]), + } + } + // If any field needs drop, then the whole tuple does. + ty::Tuple(..) => ty.tuple_fields().try_fold(SmallVec::new(), |mut acc, elem| { + acc.extend(needs_drop_components(elem)?); + Ok(acc) + }), + + // These require checking for `Copy` bounds or `Adt` destructors. + ty::Adt(..) + | ty::Projection(..) + | ty::UnnormalizedProjection(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Opaque(..) + | ty::Infer(_) + | ty::Closure(..) => Ok(smallvec![ty]), + } +} + +#[derive(Copy, Clone, Debug, HashStable)] +pub struct AlwaysRequiresDrop; diff --git a/src/librustc_ty/common_traits.rs b/src/librustc_ty/common_traits.rs new file mode 100644 index 0000000000000..9fe8a19311fb6 --- /dev/null +++ b/src/librustc_ty/common_traits.rs @@ -0,0 +1,40 @@ +//! Queries for checking whether a type implements one of a few common traits. + +use rustc::middle::lang_items; +use rustc::traits; +use rustc::ty::{self, Ty, TyCtxt}; +use rustc_span::DUMMY_SP; + +fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + is_item_raw(tcx, query, lang_items::CopyTraitLangItem) +} + +fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + is_item_raw(tcx, query, lang_items::SizedTraitLangItem) +} + +fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + is_item_raw(tcx, query, lang_items::FreezeTraitLangItem) +} + +fn is_item_raw<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + item: lang_items::LangItem, +) -> bool { + let (param_env, ty) = query.into_parts(); + let trait_def_id = tcx.require_lang_item(item, None); + tcx.infer_ctxt().enter(|infcx| { + traits::type_known_to_meet_bound_modulo_regions( + &infcx, + param_env, + ty, + trait_def_id, + DUMMY_SP, + ) + }) +} + +pub(crate) fn provide(providers: &mut ty::query::Providers<'_>) { + *providers = ty::query::Providers { is_copy_raw, is_sized_raw, is_freeze_raw, ..*providers }; +} diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs index e970faef02f28..7eef19b94e401 100644 --- a/src/librustc_ty/lib.rs +++ b/src/librustc_ty/lib.rs @@ -16,8 +16,12 @@ extern crate log; use rustc::ty::query::Providers; +mod common_traits; +mod needs_drop; mod ty; pub fn provide(providers: &mut Providers<'_>) { + common_traits::provide(providers); + needs_drop::provide(providers); ty::provide(providers); } diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs new file mode 100644 index 0000000000000..1a65acb1f984b --- /dev/null +++ b/src/librustc_ty/needs_drop.rs @@ -0,0 +1,171 @@ +//! Check whether a type has (potentially) non-trivial drop glue. + +use rustc::ty::subst::Subst; +use rustc::ty::util::{needs_drop_components, AlwaysRequiresDrop}; +use rustc::ty::{self, Ty, TyCtxt}; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def_id::DefId; +use rustc_span::DUMMY_SP; + +type NeedsDropResult = Result; + +fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + let adt_fields = + move |adt_def: &ty::AdtDef| tcx.adt_drop_tys(adt_def.did).map(|tys| tys.iter().copied()); + // If we don't know a type doesn't need drop, say it's a type parameter + // without a `Copy` bound, then we conservatively return that it needs + // drop. + let res = NeedsDropTypes::new(tcx, query.param_env, query.value, adt_fields).next().is_some(); + debug!("needs_drop_raw({:?}) = {:?}", query, res); + res +} + +struct NeedsDropTypes<'tcx, F> { + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + query_ty: Ty<'tcx>, + seen_tys: FxHashSet>, + /// A stack of types left to process. Each round, we pop something from the + /// stack and check if it needs drop. If the result depends on whether some + /// other types need drop we push them onto the stack. + unchecked_tys: Vec<(Ty<'tcx>, usize)>, + recursion_limit: usize, + adt_components: F, +} + +impl<'tcx, F> NeedsDropTypes<'tcx, F> { + fn new( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + adt_components: F, + ) -> Self { + let mut seen_tys = FxHashSet::default(); + seen_tys.insert(ty); + let recursion_limit = *tcx.sess.recursion_limit.get(); + Self { + tcx, + param_env, + seen_tys, + query_ty: ty, + unchecked_tys: vec![(ty, 0)], + recursion_limit, + adt_components, + } + } +} + +impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F> +where + F: Fn(&ty::AdtDef) -> NeedsDropResult, + I: Iterator>, +{ + type Item = NeedsDropResult>; + + fn next(&mut self) -> Option>> { + let tcx = self.tcx; + + while let Some((ty, level)) = self.unchecked_tys.pop() { + if level > self.recursion_limit { + // Not having a `Span` isn't great. But there's hopefully some other + // recursion limit error as well. + tcx.sess.span_err( + DUMMY_SP, + &format!("overflow while checking whether `{}` requires drop", self.query_ty), + ); + return Some(Err(AlwaysRequiresDrop)); + } + + let components = match needs_drop_components(ty) { + Err(e) => return Some(Err(e)), + Ok(components) => components, + }; + debug!("needs_drop_components({:?}) = {:?}", ty, components); + + for component in components { + match component.kind { + _ if component.is_copy_modulo_regions(tcx, self.param_env, DUMMY_SP) => (), + + ty::Array(elem_ty, len) => { + // Zero-length arrays never contain anything to drop. + if len.try_eval_usize(tcx, self.param_env) != Some(0) { + if self.seen_tys.insert(elem_ty) { + self.unchecked_tys.push((elem_ty, level + 1)); + } + } + } + + ty::Closure(def_id, substs) => { + for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) { + if self.seen_tys.insert(upvar_ty) { + self.unchecked_tys.push((upvar_ty, level + 1)); + } + } + } + + // Check for a `Drop` impl and whether this is a union or + // `ManuallyDrop`. If it's a struct or enum without a `Drop` + // impl then check whether the field types need `Drop`. + ty::Adt(adt_def, substs) => { + let tys = match (self.adt_components)(adt_def) { + Err(e) => return Some(Err(e)), + Ok(tys) => tys, + }; + for required_ty in tys { + let subst_ty = tcx.normalize_erasing_regions( + self.param_env, + required_ty.subst(tcx, substs), + ); + if self.seen_tys.insert(subst_ty) { + self.unchecked_tys.push((subst_ty, level + 1)); + } + } + } + ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => { + if ty == component { + // Return the type to the caller so they can decide + // what to do with it. + return Some(Ok(component)); + } else if self.seen_tys.insert(component) { + // Store the type for later. We can't return here + // because we would then lose any other components + // of the type. + self.unchecked_tys.push((component, level + 1)); + } + } + _ => return Some(Err(AlwaysRequiresDrop)), + } + } + } + + return None; + } +} + +fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List>, AlwaysRequiresDrop> { + let adt_components = move |adt_def: &ty::AdtDef| { + if adt_def.is_manually_drop() { + debug!("adt_drop_tys: `{:?}` is manually drop", adt_def); + return Ok(Vec::new().into_iter()); + } else if adt_def.destructor(tcx).is_some() { + debug!("adt_drop_tys: `{:?}` implements `Drop`", adt_def); + return Err(AlwaysRequiresDrop); + } else if adt_def.is_union() { + debug!("adt_drop_tys: `{:?}` is a union", adt_def); + return Ok(Vec::new().into_iter()); + } + Ok(adt_def.all_fields().map(|field| tcx.type_of(field.did)).collect::>().into_iter()) + }; + + let adt_ty = tcx.type_of(def_id); + let param_env = tcx.param_env(def_id); + let res: Result, _> = + NeedsDropTypes::new(tcx, param_env, adt_ty, adt_components).collect(); + + debug!("adt_drop_tys(`{}`) = `{:?}`", tcx.def_path_str(def_id), res); + res.map(|components| tcx.intern_type_list(&components)) +} + +pub(crate) fn provide(providers: &mut ty::query::Providers<'_>) { + *providers = ty::query::Providers { needs_drop_raw, adt_drop_tys, ..*providers }; +} diff --git a/src/test/ui/type-alias-impl-trait/issue-65918.rs b/src/test/ui/type-alias-impl-trait/issue-65918.rs index 97efb85ef64c7..4ba778d53ac08 100644 --- a/src/test/ui/type-alias-impl-trait/issue-65918.rs +++ b/src/test/ui/type-alias-impl-trait/issue-65918.rs @@ -1,3 +1,5 @@ +// ignore-test: This now ICEs again. + // build-pass #![feature(type_alias_impl_trait)] From d20646b2d8033f31423b5bda3e56776df115e144 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 31 Jan 2020 22:22:30 +0000 Subject: [PATCH 0831/1253] Address review comments * Handle arrays with const-generic lengths * Use closure for repeated code. --- src/librustc/ty/util.rs | 33 ++++++++++++++++++++++----------- src/librustc_ty/needs_drop.rs | 35 ++++++++++++++--------------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index eaa7a43b09174..6191d304719cb 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -18,6 +18,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_span::Span; +use rustc_target::abi::TargetDataLayout; use smallvec::SmallVec; use std::{cmp, fmt}; use syntax::ast; @@ -726,7 +727,7 @@ impl<'tcx> ty::TyS<'tcx> { #[inline] pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { // Avoid querying in simple cases. - match needs_drop_components(self) { + match needs_drop_components(self, &tcx.data_layout) { Err(AlwaysRequiresDrop) => true, Ok(components) => { let query_ty = match *components { @@ -736,7 +737,7 @@ impl<'tcx> ty::TyS<'tcx> { [component_ty] => component_ty, _ => self, }; - // This doesn't depend on regions, so try to minimize distinct. + // This doesn't depend on regions, so try to minimize distinct // query keys used. let erased = tcx.normalize_erasing_regions(param_env, query_ty); tcx.needs_drop_raw(param_env.and(erased)) @@ -992,7 +993,10 @@ impl<'tcx> ExplicitSelf<'tcx> { /// Returns a list of types such that the given type needs drop if and only if /// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if /// this type always needs drop. -pub fn needs_drop_components(ty: Ty<'tcx>) -> Result; 4]>, AlwaysRequiresDrop> { +pub fn needs_drop_components( + ty: Ty<'tcx>, + target_layout: &TargetDataLayout, +) -> Result; 2]>, AlwaysRequiresDrop> { match ty.kind { ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) @@ -1017,18 +1021,25 @@ pub fn needs_drop_components(ty: Ty<'tcx>) -> Result; 4]>, Al // state transformation pass ty::Generator(..) | ty::Dynamic(..) | ty::Error => Err(AlwaysRequiresDrop), - ty::Slice(ty) => needs_drop_components(ty), - ty::Array(elem_ty, ..) => { - match needs_drop_components(elem_ty) { + ty::Slice(ty) => needs_drop_components(ty, target_layout), + ty::Array(elem_ty, size) => { + match needs_drop_components(elem_ty, target_layout) { Ok(v) if v.is_empty() => Ok(v), - // Arrays of size zero don't need drop, even if their element - // type does. - _ => Ok(smallvec![ty]), + res => match size.val.try_to_bits(target_layout.pointer_size) { + // Arrays of size zero don't need drop, even if their element + // type does. + Some(0) => Ok(SmallVec::new()), + Some(_) => res, + // We don't know which of the cases above we are in, so + // return the whole type and let the caller decide what to + // do. + None => Ok(smallvec![ty]), + }, } } // If any field needs drop, then the whole tuple does. - ty::Tuple(..) => ty.tuple_fields().try_fold(SmallVec::new(), |mut acc, elem| { - acc.extend(needs_drop_components(elem)?); + ty::Tuple(..) => ty.tuple_fields().try_fold(SmallVec::new(), move |mut acc, elem| { + acc.extend(needs_drop_components(elem, target_layout)?); Ok(acc) }), diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs index 1a65acb1f984b..c01b3e384aec5 100644 --- a/src/librustc_ty/needs_drop.rs +++ b/src/librustc_ty/needs_drop.rs @@ -76,30 +76,25 @@ where return Some(Err(AlwaysRequiresDrop)); } - let components = match needs_drop_components(ty) { + let components = match needs_drop_components(ty, &tcx.data_layout) { Err(e) => return Some(Err(e)), Ok(components) => components, }; debug!("needs_drop_components({:?}) = {:?}", ty, components); + let queue_type = move |this: &mut Self, component: Ty<'tcx>| { + if this.seen_tys.insert(component) { + this.unchecked_tys.push((component, level + 1)); + } + }; + for component in components { match component.kind { _ if component.is_copy_modulo_regions(tcx, self.param_env, DUMMY_SP) => (), - ty::Array(elem_ty, len) => { - // Zero-length arrays never contain anything to drop. - if len.try_eval_usize(tcx, self.param_env) != Some(0) { - if self.seen_tys.insert(elem_ty) { - self.unchecked_tys.push((elem_ty, level + 1)); - } - } - } - ty::Closure(def_id, substs) => { for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) { - if self.seen_tys.insert(upvar_ty) { - self.unchecked_tys.push((upvar_ty, level + 1)); - } + queue_type(self, upvar_ty); } } @@ -116,21 +111,19 @@ where self.param_env, required_ty.subst(tcx, substs), ); - if self.seen_tys.insert(subst_ty) { - self.unchecked_tys.push((subst_ty, level + 1)); - } + queue_type(self, subst_ty); } } - ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => { + ty::Array(..) | ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => { if ty == component { - // Return the type to the caller so they can decide - // what to do with it. + // Return the type to the caller: they may be able + // to normalize further than we can. return Some(Ok(component)); - } else if self.seen_tys.insert(component) { + } else { // Store the type for later. We can't return here // because we would then lose any other components // of the type. - self.unchecked_tys.push((component, level + 1)); + queue_type(self, component); } } _ => return Some(Err(AlwaysRequiresDrop)), From 465b86253ce828e215d564fde53adf8742f0e3f6 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 1 Feb 2020 11:41:58 +0000 Subject: [PATCH 0832/1253] Use correct `ParamEnv` in `Instance::resolve` --- src/librustc/ty/instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 51a18f8eae274..f73e069df36c7 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -285,7 +285,7 @@ impl<'tcx> Instance<'tcx> { _ => { if Some(def_id) == tcx.lang_items().drop_in_place_fn() { let ty = substs.type_at(0); - if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) { + if ty.needs_drop(tcx, param_env.with_reveal_all()) { debug!(" => nontrivial drop glue"); ty::InstanceDef::DropGlue(def_id, Some(ty)) } else { From b9c125af751d05c656aa40a38e51af6a03d5ca0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2020 13:51:23 -0800 Subject: [PATCH 0833/1253] Deal with spans showing `std` lib Address #53081 --- src/test/ui/suggestions/imm-ref-trait-object.rs | 5 +++++ src/test/ui/suggestions/imm-ref-trait-object.stderr | 2 +- src/test/ui/traits/trait-alias/trait-alias-object-fail.rs | 5 +++++ .../ui/traits/trait-alias/trait-alias-object-fail.stderr | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/ui/suggestions/imm-ref-trait-object.rs b/src/test/ui/suggestions/imm-ref-trait-object.rs index 288d6c699f59a..241dde9fec1d6 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.rs +++ b/src/test/ui/suggestions/imm-ref-trait-object.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn test(t: &dyn Iterator) -> u64 { t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object } diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 37c2053522961..c5fe6ddb8a9bf 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -1,5 +1,5 @@ error: the `min` method cannot be invoked on a trait object - --> $DIR/imm-ref-trait-object.rs:2:8 + --> $DIR/imm-ref-trait-object.rs:7:8 | LL | t.min().unwrap() | ^^^ diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs index d62fd7e59c920..3be8db8663ab7 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![feature(trait_alias)] trait EqAlias = Eq; diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 56ecb7256f8cd..21818097bd6a0 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `std::cmp::Eq` cannot be made into an object - --> $DIR/trait-alias-object-fail.rs:7:13 + --> $DIR/trait-alias-object-fail.rs:12:13 | LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object @@ -10,7 +10,7 @@ LL | pub trait Eq: PartialEq { | --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified - --> $DIR/trait-alias-object-fail.rs:9:17 + --> $DIR/trait-alias-object-fail.rs:14:17 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^ help: specify the associated type: `IteratorAlias` From e835d0d761945bb242d271f5ccedf0aee54a4ca8 Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Thu, 30 Jan 2020 20:04:24 +0100 Subject: [PATCH 0834/1253] Optimize core::ptr::align_offset - Stopping condition inside mod_inv can be >= instead of > - Remove intrinsics::unchecked_rem, we are working modulu powers-of-2 so we can simply mask --- src/libcore/ptr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 9727e4face56a..8d83937802708 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -1083,7 +1083,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // anyway. inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse))) & (going_mod - 1); - if going_mod > m { + if going_mod >= m { return inverse & (m - 1); } going_mod = going_mod.wrapping_mul(going_mod); @@ -1134,7 +1134,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // to take the result $o mod lcm(s, a)$. We can replace $lcm(s, a)$ with just a $a / g$. let j = a.wrapping_sub(pmoda) >> gcdpow; let k = smoda >> gcdpow; - return intrinsics::unchecked_rem(j.wrapping_mul(mod_inv(k, a)), a >> gcdpow); + return (j.wrapping_mul(mod_inv(k, a))) & ((a >> gcdpow).wrapping_sub(1)); } // Cannot be aligned at all. From 3173cd1473eeebcc9567b686e63d281a761fd936 Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Tue, 28 Jan 2020 22:14:04 +0100 Subject: [PATCH 0835/1253] Optimize core::ptr::align_offset - When calculating the inverse, it's enough to work `mod a/g` instead of `mod a`. --- src/libcore/ptr/mod.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 8d83937802708..805404b101b74 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -1115,26 +1115,33 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { let gcdpow = intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a)); let gcd = 1usize << gcdpow; - if p as usize & (gcd - 1) == 0 { + if p as usize & (gcd.wrapping_sub(1)) == 0 { // This branch solves for the following linear congruence equation: // - // $$ p + so ≡ 0 mod a $$ + // ` p + so = 0 mod a ` // - // $p$ here is the pointer value, $s$ – stride of `T`, $o$ offset in `T`s, and $a$ – the + // `p` here is the pointer value, `s` - stride of `T`, `o` offset in `T`s, and `a` - the // requested alignment. // - // g = gcd(a, s) - // o = (a - (p mod a))/g * ((s/g)⁻¹ mod a) + // With `g = gcd(a, s)`, and the above asserting that `p` is also divisible by `g`, we can + // denote `a' = a/g`, `s' = s/g`, `p' = p/g`, then this becomes equivalent to: // - // The first term is “the relative alignment of p to a”, the second term is “how does - // incrementing p by s bytes change the relative alignment of p”. Division by `g` is - // necessary to make this equation well formed if $a$ and $s$ are not co-prime. + // ` p' + s'o = 0 mod a' ` + // ` o = (a' - (p' mod a')) * (s'^-1 mod a') ` // - // Furthermore, the result produced by this solution is not “minimal”, so it is necessary - // to take the result $o mod lcm(s, a)$. We can replace $lcm(s, a)$ with just a $a / g$. - let j = a.wrapping_sub(pmoda) >> gcdpow; - let k = smoda >> gcdpow; - return (j.wrapping_mul(mod_inv(k, a))) & ((a >> gcdpow).wrapping_sub(1)); + // The first term is "the relative alignment of `p` to `a`" (divided by the `g`), the second + // term is "how does incrementing `p` by `s` bytes change the relative alignment of `p`" (again + // divided by `g`). + // Division by `g` is necessary to make the inverse well formed if `a` and `s` are not + // co-prime. + // + // Furthermore, the result produced by this solution is not "minimal", so it is necessary + // to take the result `o mod lcm(s, a)`. We can replace `lcm(s, a)` with just a `a'`. + let a2 = a >> gcdpow; + let a2minus1 = a2.wrapping_sub(1); + let s2 = smoda >> gcdpow; + let minusp2 = a2.wrapping_sub(pmoda >> gcdpow); + return (minusp2.wrapping_mul(mod_inv(s2, a2))) & a2minus1; } // Cannot be aligned at all. From 22b263ae1837ab6a64fe4bcdbfa07aa8883f57db Mon Sep 17 00:00:00 2001 From: Amos Onn Date: Sun, 2 Feb 2020 02:18:33 +0100 Subject: [PATCH 0836/1253] Optimize core::ptr::align_offset - As explained in the comment inside mod_inv, it is valid to work mod `usize::max_value()` right until the end. --- src/libcore/ptr/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 805404b101b74..0ee50966f968c 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -1081,8 +1081,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod // usize::max_value()` instead, because we take the result `mod n` at the end // anyway. - inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse))) - & (going_mod - 1); + inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse))); if going_mod >= m { return inverse & (m - 1); } From 0eb297d3e04e618b96e668e8e9ed9ddf66d671fb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2020 12:11:11 +1100 Subject: [PATCH 0837/1253] Fix up `merge_from_succ`. This function has a variable `changed` that is erroneously used for two related-but-different purpose: - to detect if the current element has changed; - to detect if any elements have changed. As a result, its use for the first purpose is broken, because if any prior element changed then the code always thinks the current element has changed. This is only a performance bug, not a correctness bug, because we frequently end up calling `assign_unpacked` unnecessarily to overwrite the element with itself. This commit adds `any_changed` to correctly distinguish between the two purposes. This is a small perf win for some benchmarks. --- src/librustc_passes/liveness.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 7718139f6e924..606947bfbdd7e 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -822,8 +822,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { return false; } - let mut changed = false; + let mut any_changed = false; self.indices2(ln, succ_ln, |this, idx, succ_idx| { + let mut changed = false; let mut rwu = this.rwu_table.get(idx); let succ_rwu = this.rwu_table.get(succ_idx); if succ_rwu.reader.is_valid() && !rwu.reader.is_valid() { @@ -843,6 +844,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { if changed { this.rwu_table.assign_unpacked(idx, rwu); + any_changed = true; } }); @@ -851,9 +853,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ln, self.ln_str(succ_ln), first_merge, - changed + any_changed ); - return changed; + return any_changed; } // Indicates that a local variable was *defined*; we know that no From d62b6f204733d255a3e943388ba99f14b053bf4a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2020 13:32:59 +1100 Subject: [PATCH 0838/1253] Pull out a special case in `merge_from_succ`. This is a small perf win. --- src/librustc_passes/liveness.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 606947bfbdd7e..b355a47c39470 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -824,6 +824,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let mut any_changed = false; self.indices2(ln, succ_ln, |this, idx, succ_idx| { + // This is a special case, pulled out from the code below, where we + // don't have to do anything. It occurs about 60-70% of the time. + if this.rwu_table.packed_rwus[succ_idx] == INV_INV_FALSE { + return; + } + let mut changed = false; let mut rwu = this.rwu_table.get(idx); let succ_rwu = this.rwu_table.get(succ_idx); From 152811d8bf389fce7328ba7bc50c26c34afb0d81 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 2 Feb 2020 11:28:32 -0800 Subject: [PATCH 0839/1253] Change expansion error to be non-fatal Changes the error handler for inner attributes that replace the root with a non-module. Previously it would emit a fatal error. It now emits an empty expasion and a non-fatal error like the existing handler for a failed expansion. --- src/librustc_expand/expand.rs | 4 +++- .../proc-macro/issue-59191-replace-root-with-fn.rs | 1 + .../issue-59191-replace-root-with-fn.stderr | 13 +++++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 1aa4f11a13026..4e0fec9ce1d1c 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -364,7 +364,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true }; } Some(ast::Item { span, kind, .. }) => { - self.cx.span_fatal( + krate.attrs = vec![]; + krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true }; + self.cx.span_err( span, &format!( "expected crate top-level item to be a module after macro expansion, found a {}", diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs index 039878af56eb6..a59cacb8bde1f 100644 --- a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs +++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -3,5 +3,6 @@ // Test that using a macro to replace the entire crate tree with a non-'mod' item errors out nicely. // `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`. #![feature(custom_inner_attributes)] +//~^ ERROR `main` function not found in crate `issue_59191_replace_root_with_fn` [E0601] #![issue_59191::no_main] //~^ ERROR expected crate top-level item to be a module after macro expansion, found a function diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr index 1bda86551d418..e0a3caef9db88 100644 --- a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr +++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr @@ -1,8 +1,17 @@ error: expected crate top-level item to be a module after macro expansion, found a function - --> $DIR/issue-59191-replace-root-with-fn.rs:6:1 + --> $DIR/issue-59191-replace-root-with-fn.rs:7:1 | LL | #![issue_59191::no_main] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0601]: `main` function not found in crate `issue_59191_replace_root_with_fn` + --> $DIR/issue-59191-replace-root-with-fn.rs:5:1 + | +LL | / #![feature(custom_inner_attributes)] +LL | | +LL | | #![issue_59191::no_main] + | |________________________^ consider adding a `main` function to `$DIR/issue-59191-replace-root-with-fn.rs` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0601`. From 0b633c82f094d52a642b53cae64614ff097eebd8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 26 Jan 2020 18:50:13 +0200 Subject: [PATCH 0840/1253] rustc_codegen_ssa: split declare_local into create_dbg_var and dbg_var_addr. --- src/librustc_codegen_llvm/builder.rs | 1 + src/librustc_codegen_llvm/common.rs | 1 + src/librustc_codegen_llvm/debuginfo/mod.rs | 84 ++++++++++++-------- src/librustc_codegen_ssa/mir/debuginfo.rs | 8 +- src/librustc_codegen_ssa/traits/backend.rs | 3 + src/librustc_codegen_ssa/traits/builder.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 22 +++-- src/librustc_codegen_ssa/traits/mod.rs | 1 + 8 files changed, 79 insertions(+), 43 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c59b81eb4cc32..342ac437d3c24 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> { type Funclet = as BackendTypes>::Funclet; type DIScope = as BackendTypes>::DIScope; + type DIVariable = as BackendTypes>::DIVariable; } impl ty::layout::HasDataLayout for Builder<'_, '_, '_> { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 76f6eeb3f7907..1d6bfb321598c 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> { type Funclet = Funclet<'ll>; type DIScope = &'ll llvm::debuginfo::DIScope; + type DIVariable = &'ll llvm::debuginfo::DIVariable; } impl CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 0462dcff42919..87af9b9c88da7 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB}; use crate::llvm; use crate::llvm::debuginfo::{ - DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, + DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable, }; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::ty::subst::{GenericArgKind, SubstsRef}; @@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) { }; } -impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn declare_local( +impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn dbg_var_addr( &mut self, dbg_context: &FunctionDebugContext<&'ll DIScope>, - variable_name: ast::Name, - variable_type: Ty<'tcx>, + dbg_var: &'ll DIVariable, scope_metadata: &'ll DIScope, variable_alloca: Self::Value, direct_offset: Size, indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ) { assert!(!dbg_context.source_locations_enabled); let cx = self.cx(); - let file = span_start(cx, span).file; - let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate); - let loc = span_start(cx, span); - let type_metadata = type_metadata(cx, variable_type, span); - - let (argument_index, dwarf_tag) = match variable_kind { - ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable => (0, DW_TAG_auto_variable), - }; - let align = cx.align_of(variable_type); // Convert the direct and indirect offsets to address ops. let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() }; @@ -188,32 +178,19 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } - let name = SmallCStr::new(&variable_name.as_str()); - let metadata = unsafe { - llvm::LLVMRustDIBuilderCreateVariable( - DIB(cx), - dwarf_tag, - scope_metadata, - name.as_ptr(), - file_metadata, - loc.line as c_uint, - type_metadata, - cx.sess().opts.optimize != config::OptLevel::No, - DIFlags::FlagZero, - argument_index, - align.bytes() as u32, - ) - }; + // FIXME(eddyb) maybe this information could be extracted from `var`, + // to avoid having to pass it down in both places? source_loc::set_debug_location( self, InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), ); unsafe { let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); + // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( DIB(cx), variable_alloca, - metadata, + dbg_var, addr_ops.as_ptr(), addr_ops.len() as c_uint, debug_loc, @@ -558,4 +535,45 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn debuginfo_finalize(&self) { finalize(self) } + + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn create_dbg_var( + &self, + dbg_context: &FunctionDebugContext<&'ll DIScope>, + variable_name: ast::Name, + variable_type: Ty<'tcx>, + scope_metadata: &'ll DIScope, + variable_kind: VariableKind, + span: Span, + ) -> &'ll DIVariable { + let file = span_start(self, span).file; + let file_metadata = file_metadata(self, &file.name, dbg_context.defining_crate); + + let loc = span_start(self, span); + let type_metadata = type_metadata(self, variable_type, span); + + let (argument_index, dwarf_tag) = match variable_kind { + ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), + LocalVariable => (0, DW_TAG_auto_variable), + }; + let align = self.align_of(variable_type); + + let name = SmallCStr::new(&variable_name.as_str()); + unsafe { + llvm::LLVMRustDIBuilderCreateVariable( + DIB(self), + dwarf_tag, + scope_metadata, + name.as_ptr(), + file_metadata, + loc.line as c_uint, + type_metadata, + self.sess().opts.optimize != config::OptLevel::No, + DIFlags::FlagZero, + argument_index, + align.bytes() as u32, + ) + } + } } diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index e0aec5d6dd512..1ee5fdba2a202 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -226,15 +226,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (scope, span) = self.debug_loc(var.source_info); if let Some(scope) = scope { - bx.declare_local( + let dbg_var = + bx.create_dbg_var(debug_context, var.name, layout.ty, scope, kind, span); + bx.dbg_var_addr( debug_context, - var.name, - layout.ty, + dbg_var, scope, base.llval, direct_offset, &indirect_offsets, - kind, span, ); } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index bc3a75250bf70..7b22961cd46e2 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -21,7 +21,10 @@ pub trait BackendTypes { type Type: CodegenObject; type Funclet; + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.). type DIScope: Copy; + type DIVariable: Copy; } pub trait Backend<'tcx>: diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 6f331e14a0d37..b3c830eef8698 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -28,7 +28,7 @@ pub enum OverflowOp { pub trait BuilderMethods<'a, 'tcx>: HasCodegen<'tcx> - + DebugInfoBuilderMethods<'tcx> + + DebugInfoBuilderMethods + ArgAbiMethods<'tcx> + AbiBuilderMethods<'tcx> + IntrinsicCallMethods<'tcx> diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index d2784f5b860f7..22a4e96b9e4bf 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -30,20 +30,32 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { defining_crate: CrateNum, ) -> Self::DIScope; fn debuginfo_finalize(&self); -} -pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { - fn declare_local( - &mut self, + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn create_dbg_var( + &self, dbg_context: &FunctionDebugContext, variable_name: Name, variable_type: Ty<'tcx>, scope_metadata: Self::DIScope, + variable_kind: VariableKind, + span: Span, + ) -> Self::DIVariable; +} + +pub trait DebugInfoBuilderMethods: BackendTypes { + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn dbg_var_addr( + &mut self, + dbg_context: &FunctionDebugContext, + dbg_var: Self::DIVariable, + scope_metadata: Self::DIScope, variable_alloca: Self::Value, direct_offset: Size, // NB: each offset implies a deref (i.e. they're steps in a pointer chain). indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ); fn set_source_location( diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index fff1b35507ce6..b8afadaadef38 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -93,5 +93,6 @@ pub trait HasCodegen<'tcx>: Type = Self::Type, Funclet = Self::Funclet, DIScope = Self::DIScope, + DIVariable = Self::DIVariable, >; } From f4b74773c730e7afb6e81aa90df3ddade7442b60 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 22 Jan 2020 19:45:22 +0200 Subject: [PATCH 0841/1253] rustc_codegen_ssa: convert mir::VarDebugInfo into a custom PerLocalVarDebugInfo. --- src/librustc_codegen_ssa/mir/debuginfo.rs | 174 ++++++++++++++++------ src/librustc_codegen_ssa/mir/mod.rs | 13 +- 2 files changed, 133 insertions(+), 54 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index 1ee5fdba2a202..f66496d10fb16 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -1,12 +1,12 @@ use crate::traits::*; use rustc::mir; use rustc::session::config::DebugInfo; +use rustc::ty; use rustc::ty::layout::{LayoutOf, Size}; -use rustc::ty::TyCtxt; use rustc_hir::def_id::CrateNum; use rustc_index::vec::IndexVec; -use rustc_span::symbol::kw; +use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; use super::OperandValue; @@ -24,6 +24,19 @@ pub enum VariableKind { LocalVariable, } +/// Like `mir::VarDebugInfo`, but within a `mir::Local`. +#[derive(Copy, Clone)] +pub struct PerLocalVarDebugInfo<'tcx, D> { + pub name: Symbol, + pub source_info: mir::SourceInfo, + + /// `DIVariable` returned by `create_dbg_var`. + pub dbg_var: Option, + + /// `.place.projection` from `mir::VarDebugInfo`. + pub projection: &'tcx ty::List>, +} + #[derive(Clone, Copy, Debug)] pub struct DebugScope { pub scope_metadata: Option, @@ -103,6 +116,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // FIXME(eddyb) use `llvm.dbg.value` (which would work for operands), // not just `llvm.dbg.declare` (which requires `alloca`). pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { + let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; + // FIXME(eddyb) maybe name the return place as `_0` or `return`? if local == mir::RETURN_PLACE { return; @@ -112,35 +127,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(per_local) => &per_local[local], None => return, }; - let whole_local_var = vars.iter().copied().find(|var| var.place.projection.is_empty()); - let has_proj = || vars.iter().any(|var| !var.place.projection.is_empty()); + let whole_local_var = vars.iter().find(|var| var.projection.is_empty()).copied(); + let has_proj = || vars.iter().any(|var| !var.projection.is_empty()); - let (fallback_var, kind) = if self.mir.local_kind(local) == mir::LocalKind::Arg { + let fallback_var = if self.mir.local_kind(local) == mir::LocalKind::Arg { let arg_index = local.index() - 1; // Add debuginfo even to unnamed arguments. // FIXME(eddyb) is this really needed? - let var = if arg_index == 0 && has_proj() { + if arg_index == 0 && has_proj() { // Hide closure environments from debuginfo. // FIXME(eddyb) shouldn't `ArgumentVariable` indices // be offset to account for the hidden environment? None + } else if whole_local_var.is_some() { + // No need to make up anything, there is a `mir::VarDebugInfo` + // covering the whole local. + // FIXME(eddyb) take `whole_local_var.source_info.scope` into + // account, just in case it doesn't use `ArgumentVariable` + // (after #67586 gets fixed). + None } else { - Some(mir::VarDebugInfo { - name: kw::Invalid, - source_info: self.mir.local_decls[local].source_info, - place: local.into(), + let name = kw::Invalid; + let decl = &self.mir.local_decls[local]; + let (scope, span) = if full_debug_info { + self.debug_loc(decl.source_info) + } else { + (None, decl.source_info.span) + }; + let dbg_var = scope.map(|scope| { + // FIXME(eddyb) is this `+ 1` needed at all? + let kind = VariableKind::ArgumentVariable(arg_index + 1); + + self.cx.create_dbg_var( + self.debug_context.as_ref().unwrap(), + name, + self.monomorphize(&decl.ty), + scope, + kind, + span, + ) + }); + + Some(PerLocalVarDebugInfo { + name, + source_info: decl.source_info, + dbg_var, + projection: ty::List::empty(), }) - }; - (var, VariableKind::ArgumentVariable(arg_index + 1)) + } } else { - (None, VariableKind::LocalVariable) + None }; let local_ref = &self.locals[local]; if !bx.sess().fewer_names() { - let name = match whole_local_var.or(fallback_var.as_ref()) { + let name = match whole_local_var.or(fallback_var) { Some(var) if var.name != kw::Invalid => var.name.to_string(), _ => format!("{:?}", local), }; @@ -163,7 +206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - if bx.sess().opts.debuginfo != DebugInfo::Full { + if !full_debug_info { return; } @@ -178,11 +221,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => return, }; - let vars = vars.iter().copied().chain(if whole_local_var.is_none() { - fallback_var.as_ref() - } else { - None - }); + let vars = vars.iter().copied().chain(fallback_var); for var in vars { let mut layout = base.layout; @@ -190,10 +229,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // FIXME(eddyb) use smallvec here. let mut indirect_offsets = vec![]; - let kind = - if var.place.projection.is_empty() { kind } else { VariableKind::LocalVariable }; - - for elem in &var.place.projection[..] { + for elem in &var.projection[..] { match *elem { mir::ProjectionElem::Deref => { indirect_offsets.push(Size::ZERO); @@ -202,7 +238,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .ty .builtin_deref(true) .unwrap_or_else(|| { - span_bug!(var.source_info.span, "cannot deref `{}`", layout.ty,) + span_bug!(var.source_info.span, "cannot deref `{}`", layout.ty) }) .ty, ); @@ -219,24 +255,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => span_bug!( var.source_info.span, "unsupported var debuginfo place `{:?}`", - var.place, + mir::Place { local, projection: var.projection }, ), } } let (scope, span) = self.debug_loc(var.source_info); if let Some(scope) = scope { - let dbg_var = - bx.create_dbg_var(debug_context, var.name, layout.ty, scope, kind, span); - bx.dbg_var_addr( - debug_context, - dbg_var, - scope, - base.llval, - direct_offset, - &indirect_offsets, - span, - ); + if let Some(dbg_var) = var.dbg_var { + bx.dbg_var_addr( + debug_context, + dbg_var, + scope, + base.llval, + direct_offset, + &indirect_offsets, + span, + ); + } } } } @@ -248,20 +284,60 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } -} -/// Partition all `VarDebuginfo` in `body`, by their base `Local`. -pub fn per_local_var_debug_info( - tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, -) -> Option>>> { - if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() { - let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); - for var in &body.var_debug_info { - per_local[var.place.local].push(var); + /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`. + pub fn compute_per_local_var_debug_info( + &self, + ) -> Option>>> { + let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full; + + if !(full_debug_info || !self.cx.sess().fewer_names()) { + return None; + } + + let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls); + for var in &self.mir.var_debug_info { + let (scope, span) = if full_debug_info { + self.debug_loc(var.source_info) + } else { + (None, var.source_info.span) + }; + let dbg_var = scope.map(|scope| { + let place = var.place; + let var_ty = self.monomorphized_place_ty(place.as_ref()); + let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg + && place.projection.is_empty() + { + // FIXME(eddyb, #67586) take `var.source_info.scope` into + // account to avoid using `ArgumentVariable` more than once + // per argument local. + + let arg_index = place.local.index() - 1; + + // FIXME(eddyb) shouldn't `ArgumentVariable` indices be + // offset in closures to account for the hidden environment? + // Also, is this `+ 1` needed at all? + VariableKind::ArgumentVariable(arg_index + 1) + } else { + VariableKind::LocalVariable + }; + self.cx.create_dbg_var( + self.debug_context.as_ref().unwrap(), + var.name, + var_ty, + scope, + var_kind, + span, + ) + }); + + per_local[var.place.local].push(PerLocalVarDebugInfo { + name: var.name, + source_info: var.source_info, + dbg_var, + projection: var.place.projection, + }); } Some(per_local) - } else { - None } } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 02b07ebfb7df5..8a6284479c722 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -11,7 +11,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use self::analyze::CleanupKind; -use self::debuginfo::FunctionDebugContext; +use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo}; use self::place::PlaceRef; use rustc::mir::traversal; @@ -74,9 +74,10 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// notably `expect`. locals: IndexVec>, - /// All `VarDebuginfo` from the MIR body, partitioned by `Local`. - /// This is `None` if no variable debuginfo/names are needed. - per_local_var_debug_info: Option>>>, + /// All `VarDebugInfo` from the MIR body, partitioned by `Local`. + /// This is `None` if no var`#[non_exhaustive]`iable debuginfo/names are needed. + per_local_var_debug_info: + Option>>>, /// Caller location propagated if this function has `#[track_caller]`. caller_location: Option>, @@ -178,10 +179,12 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( funclets, locals: IndexVec::new(), debug_context, - per_local_var_debug_info: debuginfo::per_local_var_debug_info(cx.tcx(), mir_body), + per_local_var_debug_info: None, caller_location: None, }; + fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(); + let memory_locals = analyze::non_ssa_locals(&fx); // Allocate variable and temp allocas From e35dfad5b8cfe12555c6b7459c75d4b78280bfb2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 3 Feb 2020 12:14:05 +0200 Subject: [PATCH 0842/1253] rustc_codegen_llvm: avoid redundant calls to span_start. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 87af9b9c88da7..c4a52a73e25d9 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -290,7 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Get the linkage_name, which is just the symbol name let linkage_name = mangled_name_of_instance(self, instance); - let scope_line = span_start(self, span).line; + // FIXME(eddyb) does this need to be separate from `loc.line` for some reason? + let scope_line = loc.line; let function_name = CString::new(name).unwrap(); let linkage_name = SmallCStr::new(&linkage_name.name.as_str()); @@ -547,10 +548,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { variable_kind: VariableKind, span: Span, ) -> &'ll DIVariable { - let file = span_start(self, span).file; - let file_metadata = file_metadata(self, &file.name, dbg_context.defining_crate); - let loc = span_start(self, span); + let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate); + let type_metadata = type_metadata(self, variable_type, span); let (argument_index, dwarf_tag) = match variable_kind { From 392e59500a96be718383e127d38bf74300f521c0 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 2 Feb 2020 22:46:06 +0100 Subject: [PATCH 0843/1253] Fix miscompilation --- src/librustc_mir/transform/generator.rs | 63 ++++++++++++++++--- src/test/mir-opt/generator-drop-cleanup.rs | 5 +- .../ui/generator/resume-live-across-yield.rs | 45 +++++++++++++ 3 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/generator/resume-live-across-yield.rs diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index b5edcbe457b63..414d91a18be12 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -380,28 +380,35 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body PinArgVisitor { ref_gen_ty, tcx }.visit_body(body); } -fn replace_result_variable<'tcx>( - ret_ty: Ty<'tcx>, +/// Allocates a new local and replaces all references of `local` with it. Returns the new local. +/// +/// `local` will be changed to a new local decl with type `ty`. +/// +/// Note that the new local will be uninitialized. It is the caller's responsibility to assign some +/// valid value to it before its first use. +fn replace_local<'tcx>( + local: Local, + ty: Ty<'tcx>, body: &mut BodyAndCache<'tcx>, tcx: TyCtxt<'tcx>, ) -> Local { let source_info = source_info(body); - let new_ret = LocalDecl { + let new_decl = LocalDecl { mutability: Mutability::Mut, - ty: ret_ty, + ty, user_ty: UserTypeProjections::none(), source_info, internal: false, is_block_tail: None, local_info: LocalInfo::Other, }; - let new_ret_local = Local::new(body.local_decls.len()); - body.local_decls.push(new_ret); - body.local_decls.swap(RETURN_PLACE, new_ret_local); + let new_local = Local::new(body.local_decls.len()); + body.local_decls.push(new_decl); + body.local_decls.swap(local, new_local); - RenameLocalVisitor { from: RETURN_PLACE, to: new_ret_local, tcx }.visit_body(body); + RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body); - new_ret_local + new_local } struct StorageIgnored(liveness::LiveVarSet); @@ -794,6 +801,10 @@ fn compute_layout<'tcx>( (remap, layout, storage_liveness) } +/// Replaces the entry point of `body` with a block that switches on the generator discriminant and +/// dispatches to blocks according to `cases`. +/// +/// After this function, the former entry point of the function will be bb1. fn insert_switch<'tcx>( body: &mut BodyAndCache<'tcx>, cases: Vec<(usize, BasicBlock)>, @@ -1093,6 +1104,13 @@ fn create_cases<'tcx>( // Create StorageLive instructions for locals with live storage for i in 0..(body.local_decls.len()) { + if i == 2 { + // The resume argument is live on function entry. Don't insert a + // `StorageLive`, or the following `Assign` will read from uninitialized + // memory. + continue; + } + let l = Local::new(i); if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) { statements @@ -1110,6 +1128,10 @@ fn create_cases<'tcx>( Rvalue::Use(Operand::Move(resume_arg.into())), )), }); + statements.push(Statement { + source_info, + kind: StatementKind::StorageDead(resume_arg), + }); } // Then jump to the real target @@ -1166,7 +1188,28 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local // RETURN_PLACE then is a fresh unused local with type ret_ty. - let new_ret_local = replace_result_variable(ret_ty, body, tcx); + let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx); + + // We also replace the resume argument and insert an `Assign`. + // This is needed because the resume argument might be live across a `yield`, and the + // transform assumes that any local live across a `yield` is assigned to before that. + let resume_local = Local::new(2); + let new_resume_local = + replace_local(resume_local, body.local_decls[resume_local].ty, body, tcx); + + // When first entering the generator, move the resume argument into its new local. + let source_info = source_info(body); + let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements; + stmts.insert( + 0, + Statement { + source_info, + kind: StatementKind::Assign(box ( + new_resume_local.into(), + Rvalue::Use(Operand::Move(resume_local.into())), + )), + }, + ); // Extract locals which are live across suspension point into `layout` // `remap` gives a mapping from local indices onto generator struct indices diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs index e5f3f9221c098..278dc49c92605 100644 --- a/src/test/mir-opt/generator-drop-cleanup.rs +++ b/src/test/mir-opt/generator-drop-cleanup.rs @@ -13,8 +13,8 @@ fn main() { // START rustc.main-{{closure}}.generator_drop.0.mir // bb0: { -// _6 = discriminant((*_1)); -// switchInt(move _6) -> [0u32: bb4, 3u32: bb7, otherwise: bb8]; +// _7 = discriminant((*_1)); +// switchInt(move _7) -> [0u32: bb4, 3u32: bb7, otherwise: bb8]; // } // bb1: { // StorageDead(_4); @@ -37,7 +37,6 @@ fn main() { // goto -> bb3; // } // bb7: { -// StorageLive(_2); // StorageLive(_3); // StorageLive(_4); // goto -> bb1; diff --git a/src/test/ui/generator/resume-live-across-yield.rs b/src/test/ui/generator/resume-live-across-yield.rs new file mode 100644 index 0000000000000..4c4cf117a5563 --- /dev/null +++ b/src/test/ui/generator/resume-live-across-yield.rs @@ -0,0 +1,45 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP: AtomicUsize = AtomicUsize::new(0); + +#[derive(PartialEq, Eq, Debug)] +struct Dropper(String); + +impl Drop for Dropper { + fn drop(&mut self) { + DROP.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + let mut g = |mut _d| { + _d = yield; + _d + }; + + let mut g = Pin::new(&mut g); + + assert_eq!( + g.as_mut().resume(Dropper(String::from("Hello world!"))), + GeneratorState::Yielded(()) + ); + assert_eq!(DROP.load(Ordering::Acquire), 0); + match g.as_mut().resume(Dropper(String::from("Number Two"))) { + GeneratorState::Complete(dropper) => { + assert_eq!(DROP.load(Ordering::Acquire), 1); + assert_eq!(dropper.0, "Number Two"); + drop(dropper); + assert_eq!(DROP.load(Ordering::Acquire), 2); + } + _ => unreachable!(), + } + + drop(g); + assert_eq!(DROP.load(Ordering::Acquire), 2); +} From 46f6dad1010be9fc609e706f7452b1df4b0afa45 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 3 Feb 2020 16:12:35 +0100 Subject: [PATCH 0844/1253] Fix links to types instead of modules --- src/libstd/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index dc93ac90482fb..0884d602b5b4d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -163,11 +163,11 @@ //! [`Iterator`]: iter/trait.Iterator.html //! [`Mutex`]: sync/struct.Mutex.html //! [`Option`]: option/enum.Option.html -//! [`Rc`]: rc/index.html +//! [`Rc`]: rc/struct.Rc.html //! [`RefCell`]: cell/struct.RefCell.html //! [`Result`]: result/enum.Result.html //! [`String`]: string/struct.String.html -//! [`Vec`]: vec/index.html +//! [`Vec`]: vec/struct.Vec.html //! [array]: primitive.array.html //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html From f0eec8858173868d2d266c5d7fe4ef83a2d9412c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 3 Feb 2020 16:15:30 +0100 Subject: [PATCH 0845/1253] track_caller test caller_location ctfe/rt equivalence wrt. fnptrs --- .../caller-location-fnptr-rt-ctfe-equiv.rs | 32 +++++++++++++++++++ ...caller-location-fnptr-rt-ctfe-equiv.stderr | 6 ++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs create mode 100644 src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.stderr diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs b/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs new file mode 100644 index 0000000000000..fe2b92eafdb76 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs @@ -0,0 +1,32 @@ +// Ensure that a `#[track_caller]` function, returning `caller_location()`, +// which coerced (to a function pointer) and called, inside a `const fn`, +// in turn called, results in the same output irrespective of whether +// we're in a const or runtime context. + +// run-pass +// compile-flags: -Z unleash-the-miri-inside-of-you + +#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)] + +type L = &'static std::panic::Location<'static>; + +#[track_caller] +const fn attributed() -> L { + std::intrinsics::caller_location() +} + +const fn calling_attributed() -> L { + // We need `-Z unleash-the-miri-inside-of-you` for this as we don't have `const fn` pointers. + let ptr: fn() -> L = attributed; + ptr() //~ WARN skipping const checks +} + +fn main() { + const CONSTANT: L = calling_attributed(); + let runtime = calling_attributed(); + + assert_eq!( + (runtime.file(), runtime.line(), runtime.column()), + (CONSTANT.file(), CONSTANT.line(), CONSTANT.column()), + ); +} diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.stderr b/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.stderr new file mode 100644 index 0000000000000..fcf0945ed4cc6 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.stderr @@ -0,0 +1,6 @@ +warning: skipping const checks + --> $DIR/caller-location-fnptr-rt-ctfe-equiv.rs:21:5 + | +LL | ptr() + | ^^^^^ + From 7e2d7e0bbcc8c20320a32778dafd07a3aa111384 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 4 Feb 2020 00:47:04 +0900 Subject: [PATCH 0846/1253] Stabilize `core::iter::once_with()` --- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/sources.rs | 18 +++++++----------- src/libcore/lib.rs | 1 - src/libcore/tests/lib.rs | 1 - 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index d8a56cb3ae515..5fa9962f811c5 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -327,7 +327,7 @@ pub use self::sources::{empty, Empty}; pub use self::sources::{from_fn, FromFn}; #[stable(feature = "iter_once", since = "1.2.0")] pub use self::sources::{once, Once}; -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] pub use self::sources::{once_with, OnceWith}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::sources::{repeat, Repeat}; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 25dfc573e416a..5a31acab273f1 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -399,12 +399,12 @@ pub fn once(value: T) -> Once { /// /// [`once_with`]: fn.once_with.html #[derive(Copy, Clone, Debug)] -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] pub struct OnceWith { gen: Option, } -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] impl A> Iterator for OnceWith { type Item = A; @@ -420,24 +420,24 @@ impl A> Iterator for OnceWith { } } -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] impl A> DoubleEndedIterator for OnceWith { fn next_back(&mut self) -> Option { self.next() } } -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] impl A> ExactSizeIterator for OnceWith { fn len(&self) -> usize { self.gen.iter().len() } } -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] impl A> FusedIterator for OnceWith {} -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] unsafe impl A> TrustedLen for OnceWith {} /// Creates an iterator that lazily generates a value exactly once by invoking @@ -458,8 +458,6 @@ unsafe impl A> TrustedLen for OnceWith {} /// Basic usage: /// /// ``` -/// #![feature(iter_once_with)] -/// /// use std::iter; /// /// // one is the loneliest number @@ -476,8 +474,6 @@ unsafe impl A> TrustedLen for OnceWith {} /// `.foorc`: /// /// ```no_run -/// #![feature(iter_once_with)] -/// /// use std::iter; /// use std::fs; /// use std::path::PathBuf; @@ -500,7 +496,7 @@ unsafe impl A> TrustedLen for OnceWith {} /// } /// ``` #[inline] -#[unstable(feature = "iter_once_with", issue = "57581")] +#[stable(feature = "iter_once_with", since = "1.43.0")] pub fn once_with A>(gen: F) -> OnceWith { OnceWith { gen: Some(gen) } } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index ce7ddffd82584..7738ea2ac57a4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -87,7 +87,6 @@ #![feature(intrinsics)] #![feature(try_find)] #![feature(is_sorted)] -#![feature(iter_once_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] #![feature(never_type)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8fd19ef67fccf..bfc3ee09dce4e 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -13,7 +13,6 @@ #![feature(hashmap_internals)] #![feature(try_find)] #![feature(is_sorted)] -#![feature(iter_once_with)] #![feature(pattern)] #![feature(range_is_empty)] #![feature(raw)] From 0c0c31b11c5460ac25a6e8a478d414a56437e92d Mon Sep 17 00:00:00 2001 From: mark Date: Sun, 2 Feb 2020 23:41:33 -0600 Subject: [PATCH 0847/1253] implement proper linkchecker hardening --- Cargo.lock | 1 + src/tools/rustbook/Cargo.toml | 3 +- src/tools/rustbook/src/main.rs | 69 +++++++++++++++++++++++++++++----- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec976b6901646..bbfda0fa2c846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3067,6 +3067,7 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap", + "codespan", "codespan-reporting", "failure", "mdbook", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 327de29037cc3..e6e758dccdf0a 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -6,13 +6,14 @@ license = "MIT OR Apache-2.0" edition = "2018" [features] -linkcheck = ["mdbook-linkcheck", "codespan-reporting"] +linkcheck = ["mdbook-linkcheck", "codespan-reporting", "codespan"] [dependencies] clap = "2.25.0" failure = "0.1" mdbook-linkcheck = { version = "0.5.0", optional = true } # Keep in sync with mdbook-linkcheck. +codespan = { version = "0.5", optional = true } codespan-reporting = { version = "0.5", optional = true } diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index fc28315669376..a0b7b29f46257 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -8,8 +8,6 @@ use clap::{App, AppSettings, ArgMatches, SubCommand}; use mdbook::errors::Result as Result3; use mdbook::MDBook; -#[cfg(feature = "linkcheck")] -use failure::Error; #[cfg(feature = "linkcheck")] use mdbook::renderer::RenderContext; @@ -53,8 +51,18 @@ fn main() { ("linkcheck", Some(sub_matches)) => { #[cfg(feature = "linkcheck")] { - if let Err(err) = linkcheck(sub_matches) { - eprintln!("Error: {}", err); + let (diags, files) = linkcheck(sub_matches).expect("Error while linkchecking."); + if !diags.is_empty() { + let color = codespan_reporting::term::termcolor::ColorChoice::Auto; + let mut writer = + codespan_reporting::term::termcolor::StandardStream::stderr(color); + let cfg = codespan_reporting::term::Config::default(); + + for diag in diags { + codespan_reporting::term::emit(&mut writer, &cfg, &files, &diag) + .expect("Unable to emit linkcheck error."); + } + std::process::exit(101); } } @@ -73,14 +81,57 @@ fn main() { } #[cfg(feature = "linkcheck")] -pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> { +pub fn linkcheck( + args: &ArgMatches<'_>, +) -> Result<(Vec, codespan::Files), failure::Error> { + use mdbook_linkcheck::Reason; + let book_dir = get_book_dir(args); + let src_dir = get_book_dir(args).join("src"); let book = MDBook::load(&book_dir).unwrap(); - let cfg = book.config; - let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir); + let linkck_cfg = mdbook_linkcheck::get_config(&book.config)?; + let mut files = codespan::Files::new(); + let target_files = mdbook_linkcheck::load_files_into_memory(&book.book, &mut files); + let render_ctx = RenderContext::new(&book_dir, book.book, book.config, &book_dir); let cache_file = render_ctx.destination.join("cache.json"); - let color = codespan_reporting::term::termcolor::ColorChoice::Auto; - mdbook_linkcheck::run(&cache_file, color, &render_ctx) + let cache = mdbook_linkcheck::Cache::load(std::fs::File::open(cache_file)?)?; + + let (links, incomplete) = mdbook_linkcheck::extract_links(target_files, &files); + + let outcome = + mdbook_linkcheck::validate(&links, &linkck_cfg, &src_dir, &cache, &files, incomplete)?; + + let mut is_real_error = false; + + for link in outcome.invalid_links.iter() { + match &link.reason { + Reason::FileNotFound | Reason::TraversesParentDirectories => { + is_real_error = true; + } + Reason::UnsuccessfulServerResponse(status) => { + if status.is_client_error() { + is_real_error = true; + } else { + eprintln!("Unsuccessful server response for link `{}`", link.link.uri); + } + } + Reason::Client(err) => { + if err.is_timeout() { + eprintln!("Timeout for link `{}`", link.link.uri); + } else if err.is_server_error() { + eprintln!("Server error for link `{}`", link.link.uri); + } else { + is_real_error = true; + } + } + } + } + + if is_real_error { + Ok((outcome.generate_diagnostics(&files, linkck_cfg.warning_policy), files)) + } else { + Ok((vec![], files)) + } } // Build command implementation From 80515f7528efd2921e474d932755b823eee6f53b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 3 Feb 2020 19:42:39 +0200 Subject: [PATCH 0848/1253] rustc_codegen_ssa: don't treat inlined variables as debuginfo arguments. --- src/librustc_codegen_ssa/mir/debuginfo.rs | 5 +---- .../ui/mir/mir-inlining/var-debuginfo-issue-67586.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index f66496d10fb16..9cba77b72980e 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -307,11 +307,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let var_ty = self.monomorphized_place_ty(place.as_ref()); let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg && place.projection.is_empty() + && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE { - // FIXME(eddyb, #67586) take `var.source_info.scope` into - // account to avoid using `ArgumentVariable` more than once - // per argument local. - let arg_index = place.local.index() - 1; // FIXME(eddyb) shouldn't `ArgumentVariable` indices be diff --git a/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs b/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs new file mode 100644 index 0000000000000..23cc114880c63 --- /dev/null +++ b/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs @@ -0,0 +1,11 @@ +// run-pass +// compile-flags: -Z mir-opt-level=2 -C opt-level=0 -C debuginfo=2 + +#[inline(never)] +pub fn foo(bar: usize) -> usize { + std::convert::identity(bar) +} + +fn main() { + foo(0); +} From 49ef3dac69767d322a30331712b0ce578e611abd Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 10:27:38 -0800 Subject: [PATCH 0849/1253] Take `FnMut` instead of `Fn` in `Qualif` methods --- .../transform/check_consts/qualifs.rs | 18 +++++++++--------- .../transform/check_consts/validation.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 2c0c0cbbaddb9..e509e8267cc1a 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -34,7 +34,7 @@ pub trait Qualif { fn in_projection_structurally( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, place: PlaceRef<'_, 'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { @@ -66,7 +66,7 @@ pub trait Qualif { fn in_projection( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, place: PlaceRef<'_, 'tcx>, ) -> bool { Self::in_projection_structurally(cx, per_local, place) @@ -74,7 +74,7 @@ pub trait Qualif { fn in_place( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, place: PlaceRef<'_, 'tcx>, ) -> bool { match place { @@ -85,7 +85,7 @@ pub trait Qualif { fn in_operand( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, operand: &Operand<'tcx>, ) -> bool { match *operand { @@ -126,7 +126,7 @@ pub trait Qualif { fn in_rvalue_structurally( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, rvalue: &Rvalue<'tcx>, ) -> bool { match *rvalue { @@ -170,7 +170,7 @@ pub trait Qualif { fn in_rvalue( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, rvalue: &Rvalue<'tcx>, ) -> bool { Self::in_rvalue_structurally(cx, per_local, rvalue) @@ -178,7 +178,7 @@ pub trait Qualif { fn in_call( cx: &ConstCx<'_, 'tcx>, - _per_local: &impl Fn(Local) -> bool, + _per_local: &mut impl FnMut(Local) -> bool, _callee: &Operand<'tcx>, _args: &[Operand<'tcx>], return_ty: Ty<'tcx>, @@ -208,7 +208,7 @@ impl Qualif for HasMutInterior { fn in_rvalue( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, rvalue: &Rvalue<'tcx>, ) -> bool { match *rvalue { @@ -249,7 +249,7 @@ impl Qualif for NeedsDrop { fn in_rvalue( cx: &ConstCx<'_, 'tcx>, - per_local: &impl Fn(Local) -> bool, + per_local: &mut impl FnMut(Local) -> bool, rvalue: &Rvalue<'tcx>, ) -> bool { if let Rvalue::Aggregate(ref kind, _) = *rvalue { diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 6f109a060dfc1..4dac0d09413ea 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -253,7 +253,7 @@ impl Validator<'a, 'mir, 'tcx> { let borrowed_place_has_mut_interior = HasMutInterior::in_place( &self.item, - &|local| self.qualifs.has_mut_interior_eager_seek(local), + &mut |local| self.qualifs.has_mut_interior_eager_seek(local), place.as_ref(), ); From 4c5ca44b92691424b9a624e08b9588eaa2bfde25 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 10:32:54 -0800 Subject: [PATCH 0850/1253] Pass correct closure type to `Qualif` methods --- .../transform/check_consts/resolver.rs | 14 ++++++++++---- src/librustc_mir/transform/promote_consts.rs | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index eac60029784d2..b804dc4b5b678 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -71,8 +71,13 @@ where return_place: &mir::Place<'tcx>, ) { let return_ty = return_place.ty(*self.item.body, self.item.tcx).ty; - let qualif = - Q::in_call(self.item, &|l| self.qualifs_per_local.contains(l), func, args, return_ty); + let qualif = Q::in_call( + self.item, + &mut |l| self.qualifs_per_local.contains(l), + func, + args, + return_ty, + ); if !return_place.is_indirect() { self.assign_qualif_direct(return_place, qualif); } @@ -105,7 +110,7 @@ where rvalue: &mir::Rvalue<'tcx>, location: Location, ) { - let qualif = Q::in_rvalue(self.item, &|l| self.qualifs_per_local.contains(l), rvalue); + let qualif = Q::in_rvalue(self.item, &mut |l| self.qualifs_per_local.contains(l), rvalue); if !place.is_indirect() { self.assign_qualif_direct(place, qualif); } @@ -120,7 +125,8 @@ where // here; that occurs in `apply_call_return_effect`. if let mir::TerminatorKind::DropAndReplace { value, location: dest, .. } = kind { - let qualif = Q::in_operand(self.item, &|l| self.qualifs_per_local.contains(l), value); + let qualif = + Q::in_operand(self.item, &mut |l| self.qualifs_per_local.contains(l), value); if !dest.is_indirect() { self.assign_qualif_direct(dest, qualif); } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index f82225c6ae147..9a7f3f86a6fcd 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -407,7 +407,7 @@ impl<'tcx> Validator<'_, 'tcx> { // FIXME(eddyb) maybe cache this? fn qualif_local(&self, local: Local) -> bool { - let per_local = &|l| self.qualif_local::(l); + let per_local = &mut |l| self.qualif_local::(l); if let TempState::Defined { location: loc, .. } = self.temps[local] { let num_stmts = self.body[loc.block].statements.len(); From 110a7e25b62b94612bbc7c453e191e20c4b38290 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 10:33:29 -0800 Subject: [PATCH 0851/1253] Eliminate "eager" qualif getter All qualif getters are now lazy --- .../transform/check_consts/validation.rs | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 4dac0d09413ea..1728037ad43b8 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -64,7 +64,7 @@ impl Qualifs<'a, 'mir, 'tcx> { /// Returns `true` if `local` is `NeedsDrop` at the given `Location`. /// /// Only updates the cursor if absolutely necessary - fn needs_drop_lazy_seek(&mut self, local: Local, location: Location) -> bool { + fn needs_drop(&mut self, local: Local, location: Location) -> bool { if !self.needs_drop.in_any_value_of_ty.contains(local) { return false; } @@ -76,7 +76,7 @@ impl Qualifs<'a, 'mir, 'tcx> { /// Returns `true` if `local` is `HasMutInterior` at the given `Location`. /// /// Only updates the cursor if absolutely necessary. - fn has_mut_interior_lazy_seek(&mut self, local: Local, location: Location) -> bool { + fn has_mut_interior(&mut self, local: Local, location: Location) -> bool { if !self.has_mut_interior.in_any_value_of_ty.contains(local) { return false; } @@ -86,17 +86,6 @@ impl Qualifs<'a, 'mir, 'tcx> { || self.indirectly_mutable(local, location) } - /// Returns `true` if `local` is `HasMutInterior`, but requires the `has_mut_interior` and - /// `indirectly_mutable` cursors to be updated beforehand. - fn has_mut_interior_eager_seek(&self, local: Local) -> bool { - if !self.has_mut_interior.in_any_value_of_ty.contains(local) { - return false; - } - - self.has_mut_interior.cursor.get().contains(local) - || self.indirectly_mutable.get().contains(local) - } - fn in_return_place(&mut self, item: &Item<'_, 'tcx>) -> ConstQualifs { // Find the `Return` terminator if one exists. // @@ -120,8 +109,8 @@ impl Qualifs<'a, 'mir, 'tcx> { let return_loc = item.body.terminator_loc(return_block); ConstQualifs { - needs_drop: self.needs_drop_lazy_seek(RETURN_PLACE, return_loc), - has_mut_interior: self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc), + needs_drop: self.needs_drop(RETURN_PLACE, return_loc), + has_mut_interior: self.has_mut_interior(RETURN_PLACE, return_loc), } } } @@ -246,14 +235,9 @@ impl Validator<'a, 'mir, 'tcx> { } fn check_immutable_borrow_like(&mut self, location: Location, place: &Place<'tcx>) { - // FIXME: Change the `in_*` methods to take a `FnMut` so we don't have to manually - // seek the cursors beforehand. - self.qualifs.has_mut_interior.cursor.seek_before(location); - self.qualifs.indirectly_mutable.seek(location); - let borrowed_place_has_mut_interior = HasMutInterior::in_place( &self.item, - &mut |local| self.qualifs.has_mut_interior_eager_seek(local), + &mut |local| self.qualifs.has_mut_interior(local, location), place.as_ref(), ); @@ -571,7 +555,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { let needs_drop = if let Some(local) = dropped_place.as_local() { // Use the span where the local was declared as the span of the drop error. err_span = self.body.local_decls[local].source_info.span; - self.qualifs.needs_drop_lazy_seek(local, location) + self.qualifs.needs_drop(local, location) } else { true }; From 21a040e7acd769038f392360aa785141b821ffa5 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 10:37:36 -0800 Subject: [PATCH 0852/1253] Treat `Rvalue::AddressOf` the same as `Rvalue::Ref` --- .../transform/check_consts/validation.rs | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 1728037ad43b8..5abc5eb154fbf 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -233,18 +233,6 @@ impl Validator<'a, 'mir, 'tcx> { self.check_op_spanned(ops::StaticAccess, span) } } - - fn check_immutable_borrow_like(&mut self, location: Location, place: &Place<'tcx>) { - let borrowed_place_has_mut_interior = HasMutInterior::in_place( - &self.item, - &mut |local| self.qualifs.has_mut_interior(local, location), - place.as_ref(), - ); - - if borrowed_place_has_mut_interior { - self.check_op(ops::CellBorrow); - } - } } impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { @@ -350,12 +338,17 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf), Rvalue::Ref(_, BorrowKind::Shared, ref place) - | Rvalue::Ref(_, BorrowKind::Shallow, ref place) => { - self.check_immutable_borrow_like(location, place) - } - - Rvalue::AddressOf(Mutability::Not, ref place) => { - self.check_immutable_borrow_like(location, place) + | Rvalue::Ref(_, BorrowKind::Shallow, ref place) + | Rvalue::AddressOf(Mutability::Not, ref place) => { + let borrowed_place_has_mut_interior = HasMutInterior::in_place( + &self.item, + &mut |local| self.qualifs.has_mut_interior(local, location), + place.as_ref(), + ); + + if borrowed_place_has_mut_interior { + self.check_op(ops::CellBorrow); + } } Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => { From 0e584114c6153a3d7ff94349729c46a4735cb838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Feb 2020 10:43:45 -0800 Subject: [PATCH 0853/1253] Change wording for object unsafe because of assoc const --- src/librustc/traits/object_safety.rs | 8 +++----- .../ui/associated-const/associated-const-in-trait.stderr | 2 +- src/test/ui/associated-item/issue-48027.stderr | 2 +- .../object-safety-associated-consts.curr.stderr | 2 +- ...fety-associated-consts.object_safe_for_dispatch.stderr | 2 +- src/test/ui/traits/trait-item-privacy.stderr | 6 +++--- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 2745d3205dec0..d0dbfe73c91d5 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -80,12 +80,10 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { format!("method `{}`'s `self` parameter cannot be dispatched on", name).into() } - ObjectSafetyViolation::AssocConst(_, DUMMY_SP) => { - "it cannot contain associated consts".into() - } - ObjectSafetyViolation::AssocConst(name, _) => { - format!("it cannot contain associated consts like `{}`", name).into() + ObjectSafetyViolation::AssocConst(name, DUMMY_SP) => { + format!("it contains associated `const` `{}`", name).into() } + ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(), } } diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr index b9101c86d218a..a8a8d01ed78fb 100644 --- a/src/test/ui/associated-const/associated-const-in-trait.stderr +++ b/src/test/ui/associated-const/associated-const-in-trait.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | trait Trait { | ----- this trait cannot be made into an object... LL | const N: usize; - | - ...because it cannot contain associated consts like `N` + | - ...because it contains this associated `const` ... LL | impl dyn Trait { | ^^^^^^^^^ the trait `Trait` cannot be made into an object diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index e8442c6c9ac14..62a380732a8bb 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | impl dyn Bar {} | ^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index e0e0344af7591..890acde35c4f8 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index ff0bd17dccce5..e2a95d95a13ed 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; - | - ...because it cannot contain associated consts like `X` + | - ...because it contains this associated `const` ... LL | t | ^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index e050d6940abc3..072328ab50c70 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -111,15 +111,15 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | LL | const A: u8 = 0; - | - ...because it cannot contain associated consts like `A` + | - ...because it contains this associated `const` ... LL | const B: u8 = 0; - | - ...because it cannot contain associated consts like `B` + | - ...because it contains this associated `const` ... LL | pub trait C: A + B { | - this trait cannot be made into an object... LL | const C: u8 = 0; - | - ...because it cannot contain associated consts like `C` + | - ...because it contains this associated `const` ... LL | C::A; | ^^^^ the trait `assoc_const::C` cannot be made into an object From adc8cd9680228c7d3d389387ce585e13f616ba93 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 3 Feb 2020 12:57:39 -0600 Subject: [PATCH 0854/1253] update rustc-guide --- src/doc/rustc-guide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide index 92baf7293dd2d..5bd60bc51efae 160000 --- a/src/doc/rustc-guide +++ b/src/doc/rustc-guide @@ -1 +1 @@ -Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7 +Subproject commit 5bd60bc51efaec04e69e2e18b59678e2af066433 From 5f979e9afab42dd7536ca93994de66169880361e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 3 Feb 2020 20:13:30 +0100 Subject: [PATCH 0855/1253] bootstrap: fix clippy warnings --- src/bootstrap/bin/rustc.rs | 6 +++--- src/bootstrap/bin/rustdoc.rs | 2 +- src/bootstrap/builder.rs | 24 ++++++++---------------- src/bootstrap/builder/tests.rs | 1 - src/bootstrap/compile.rs | 20 ++++++++++---------- src/bootstrap/config.rs | 7 +++---- src/bootstrap/dist.rs | 4 ++-- src/bootstrap/doc.rs | 2 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/install.rs | 5 ++--- src/bootstrap/lib.rs | 6 +++--- src/bootstrap/metadata.rs | 1 - src/bootstrap/native.rs | 4 +--- src/bootstrap/test.rs | 9 +++------ src/bootstrap/tool.rs | 2 +- src/bootstrap/toolstate.rs | 2 +- src/bootstrap/util.rs | 2 +- 17 files changed, 41 insertions(+), 58 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index a34ec44566bc1..a8c00c8c3ca88 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -47,7 +47,7 @@ fn main() { }; let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); - let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); + let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new); let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); @@ -64,7 +64,7 @@ fn main() { if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { if target == "all" - || target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name) + || target.into_string().unwrap().split(',').any(|c| c.trim() == crate_name) { cmd.arg("-Ztime"); } @@ -189,7 +189,7 @@ fn main() { crate_name, is_test, dur.as_secs(), - dur.subsec_nanos() / 1_000_000 + dur.subsec_millis() ); match status.code() { diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 8c8b33a4e4e0a..04345867bf5c1 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -61,7 +61,7 @@ fn main() { } // Needed to be able to run all rustdoc tests. - if let Some(_) = env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES") { + if env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES").is_some() { // This "unstable-options" can be removed when `--generate-redirect-pages` is stabilized if !has_unstable { cmd.arg("-Z").arg("unstable-options"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d9c894aa9c6b1..18f6fda760846 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -510,7 +510,7 @@ impl<'a> Builder<'a> { Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), }; - let builder = Builder { + Builder { build, top_stage: build.config.stage.unwrap_or(2), kind, @@ -518,9 +518,7 @@ impl<'a> Builder<'a> { stack: RefCell::new(Vec::new()), time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), paths: paths.to_owned(), - }; - - builder + } } pub fn execute_cli(&self) { @@ -753,13 +751,12 @@ impl<'a> Builder<'a> { cargo.env("RUST_CHECK", "1"); } - let stage; - if compiler.stage == 0 && self.local_rebuild { + let stage = if compiler.stage == 0 && self.local_rebuild { // Assume the local-rebuild rustc already has stage1 features. - stage = 1; + 1 } else { - stage = compiler.stage; - } + compiler.stage + }; let mut rustflags = Rustflags::new(&target); if stage != 0 { @@ -1252,12 +1249,7 @@ impl<'a> Builder<'a> { }; if self.config.print_step_timings && dur > Duration::from_millis(100) { - println!( - "[TIMING] {:?} -- {}.{:03}", - step, - dur.as_secs(), - dur.subsec_nanos() / 1_000_000 - ); + println!("[TIMING] {:?} -- {}.{:03}", step, dur.as_secs(), dur.subsec_millis()); } { @@ -1302,7 +1294,7 @@ impl Rustflags { fn arg(&mut self, arg: &str) -> &mut Self { assert_eq!(arg.split_whitespace().count(), 1); - if self.0.len() > 0 { + if !self.0.is_empty() { self.0.push_str(" "); } self.0.push_str(arg); diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 5fefb972866a9..cca8ab80c93b1 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -19,7 +19,6 @@ fn configure(host: &[&str], target: &[&str]) -> Config { config.out = dir; config.build = INTERNER.intern_str("A"); config.hosts = vec![config.build] - .clone() .into_iter() .chain(host.iter().map(|s| INTERNER.intern_str(s))) .collect::>(); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index eced03506ab9f..7dded96e18efd 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -18,7 +18,6 @@ use std::str; use build_helper::{output, t, up_to_date}; use filetime::FileTime; use serde::Deserialize; -use serde_json; use crate::builder::Cargo; use crate::dist; @@ -149,7 +148,8 @@ fn copy_third_party_objects( // which is provided by std for this target. if target == "x86_64-fortanix-unknown-sgx" { let src_path_env = "X86_FORTANIX_SGX_LIBS"; - let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env)); + let src = + env::var(src_path_env).unwrap_or_else(|_| panic!("{} not found in env", src_path_env)); copy_and_stamp(Path::new(&src), "libunwind.a"); } @@ -361,7 +361,7 @@ impl Step for StartupObjects { ); } - let target = sysroot_dir.join(file.to_string() + ".o"); + let target = sysroot_dir.join((*file).to_string() + ".o"); builder.copy(dst_file, &target); target_deps.push(target); } @@ -515,7 +515,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne .env("CFG_VERSION", builder.rust_version()) .env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default()); - let libdir_relative = builder.config.libdir_relative().unwrap_or(Path::new("lib")); + let libdir_relative = builder.config.libdir_relative().unwrap_or_else(|| Path::new("lib")); cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative); if let Some(ref ver_date) = builder.rust_info.commit_date() { @@ -843,11 +843,11 @@ pub fn run_cargo( }; for filename in filenames { // Skip files like executables - if !filename.ends_with(".rlib") - && !filename.ends_with(".lib") - && !filename.ends_with(".a") - && !is_dylib(&filename) - && !(is_check && filename.ends_with(".rmeta")) + if !(filename.ends_with(".rlib") + || filename.ends_with(".lib") + || filename.ends_with(".a") + || is_dylib(&filename) + || (is_check && filename.ends_with(".rmeta"))) { continue; } @@ -905,7 +905,7 @@ pub fn run_cargo( for (prefix, extension, expected_len) in toplevel { let candidates = contents.iter().filter(|&&(_, ref filename, ref meta)| { filename.starts_with(&prefix[..]) - && filename[prefix.len()..].starts_with("-") + && filename[prefix.len()..].starts_with('-') && filename.ends_with(&extension[..]) && meta.len() == expected_len }); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 110c8b844d54c..709cf2908eadf 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -16,7 +16,6 @@ use crate::flags::Flags; pub use crate::flags::Subcommand; use build_helper::t; use serde::Deserialize; -use toml; /// Global configuration for the entire build and/or bootstrap. /// @@ -440,7 +439,7 @@ impl Config { } } }) - .unwrap_or_else(|| TomlConfig::default()); + .unwrap_or_else(TomlConfig::default); let build = toml.build.clone().unwrap_or_default(); // set by bootstrap.py @@ -539,7 +538,7 @@ impl Config { config.llvm_ldflags = llvm.ldflags.clone(); set(&mut config.llvm_use_libcxx, llvm.use_libcxx); config.llvm_use_linker = llvm.use_linker.clone(); - config.llvm_allow_old_toolchain = llvm.allow_old_toolchain.clone(); + config.llvm_allow_old_toolchain = llvm.allow_old_toolchain; } if let Some(ref rust) = toml.rust { @@ -606,7 +605,7 @@ impl Config { target.ar = cfg.ar.clone().map(PathBuf::from); target.ranlib = cfg.ranlib.clone().map(PathBuf::from); target.linker = cfg.linker.clone().map(PathBuf::from); - target.crt_static = cfg.crt_static.clone(); + target.crt_static = cfg.crt_static; target.musl_root = cfg.musl_root.clone().map(PathBuf::from); target.wasi_root = cfg.wasi_root.clone().map(PathBuf::from); target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 8d13df3ee21a4..651506dbaa8ab 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -827,7 +827,7 @@ impl Step for Analysis { assert!(builder.config.extended); let name = pkgname(builder, "rust-analysis"); - if &compiler.host != builder.config.build { + if compiler.host != builder.config.build { return distdir(builder).join(format!("{}-{}.tar.gz", name, target)); } @@ -876,7 +876,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str] Some(path) => path, None => return false, }; - if spath.ends_with("~") || spath.ends_with(".pyc") { + if spath.ends_with('~') || spath.ends_with(".pyc") { return false; } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 204056598d900..b0d9a5b94641c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -560,7 +560,7 @@ impl Step for Rustdoc { builder.ensure(Rustc { stage, target }); // Build rustdoc. - builder.ensure(tool::Rustdoc { compiler: compiler }); + builder.ensure(tool::Rustdoc { compiler }); // Symlink compiler docs to the output directory of rustdoc documentation. let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc"); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 2101ef27f9d42..516be6a30c235 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -571,7 +571,7 @@ fn split(s: &[String]) -> Vec { } fn parse_deny_warnings(matches: &getopts::Matches) -> Option { - match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) { + match matches.opt_str("warnings").as_deref() { Some("deny") => Some(true), Some("warn") => Some(false), Some(value) => { diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index f8734ebdf4254..6549262811b9f 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -126,9 +126,8 @@ fn add_destdir(path: &Path, destdir: &Option) -> PathBuf { None => return path.to_path_buf(), }; for part in path.components() { - match part { - Component::Normal(s) => ret.push(s), - _ => {} + if let Component::Normal(s) = part { + ret.push(s) } } ret diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 1fee3fd9ac1d2..0db4fb3890100 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -444,7 +444,7 @@ impl Build { builder.execute_cli(); } else { let builder = builder::Builder::new(&self); - let _ = builder.execute_cli(); + builder.execute_cli(); } // Check for postponed failures from `test --no-fail-fast`. @@ -839,7 +839,7 @@ impl Build { .target_config .get(&target) .and_then(|t| t.musl_root.as_ref()) - .or(self.config.musl_root.as_ref()) + .or_else(|| self.config.musl_root.as_ref()) .map(|p| &**p) } @@ -1026,7 +1026,7 @@ impl Build { } fn llvm_link_tools_dynamically(&self, target: Interned) -> bool { - (target.contains("linux-gnu") || target.contains("apple-darwin")) + target.contains("linux-gnu") || target.contains("apple-darwin") } /// Returns the `version` string associated with this compiler for Rust diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 8a26adc7ed501..292aa3b1e24a7 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -5,7 +5,6 @@ use std::process::Command; use build_helper::output; use serde::Deserialize; -use serde_json; use crate::cache::INTERNER; use crate::{Build, Crate}; diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 5bbd9f47fc907..1cfb4b2f63b57 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -15,8 +15,6 @@ use std::path::{Path, PathBuf}; use std::process::Command; use build_helper::{output, t}; -use cc; -use cmake; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::cache::Interned; @@ -205,7 +203,7 @@ impl Step for Llvm { cfg.define("LLVM_ENABLE_LIBXML2", "OFF"); } - if enabled_llvm_projects.len() > 0 { + if !enabled_llvm_projects.is_empty() { enabled_llvm_projects.sort(); enabled_llvm_projects.dedup(); cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";")); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 6adf9ddaf3438..8d9e62010015b 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1424,13 +1424,10 @@ impl Step for ErrorIndex { } fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> bool { - match fs::read_to_string(markdown) { - Ok(contents) => { - if !contents.contains("```") { - return true; - } + if let Ok(contents) = fs::read_to_string(markdown) { + if !contents.contains("```") { + return true; } - Err(_) => {} } builder.info(&format!("doc tests for: {}", markdown.display())); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 7f24768a4f10e..67e0ed5c58029 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -234,7 +234,7 @@ pub fn prepare_tool_cargo( cargo.env("RUSTC_EXTERNAL_TOOL", "1"); } - let mut features = extra_features.iter().cloned().collect::>(); + let mut features = extra_features.to_vec(); if builder.build.config.cargo_native_static { if path.ends_with("cargo") || path.ends_with("rls") diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index b068c8200acec..bb012a3885511 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -124,7 +124,7 @@ fn check_changed_files(toolstates: &HashMap, ToolState>) { let output = t!(String::from_utf8(output.stdout)); for (tool, submodule) in STABLE_TOOLS.iter().chain(NIGHTLY_TOOLS.iter()) { - let changed = output.lines().any(|l| l.starts_with("M") && l.ends_with(submodule)); + let changed = output.lines().any(|l| l.starts_with('M') && l.ends_with(submodule)); eprintln!("Verifying status of {}...", tool); if !changed { continue; diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 7d1efe4610f9c..eac790fe504b8 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -98,7 +98,7 @@ impl Drop for TimeIt { fn drop(&mut self) { let time = self.1.elapsed(); if !self.0 { - println!("\tfinished in {}.{:03}", time.as_secs(), time.subsec_nanos() / 1_000_000); + println!("\tfinished in {}.{:03}", time.as_secs(), time.subsec_millis()); } } } From c7e6f88926e746d310ca15ce9761b3fd434dbfd2 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 27 Dec 2019 18:11:20 +0000 Subject: [PATCH 0856/1253] Add more tests for or-patterns --- src/test/mir-opt/exponential-or.rs | 76 ++++++++++ src/test/ui/borrowck/or-patterns.rs | 64 ++++++++ src/test/ui/borrowck/or-patterns.stderr | 141 ++++++++++++++++++ src/test/ui/or-patterns/bindings-runpass-1.rs | 25 ++++ src/test/ui/or-patterns/bindings-runpass-2.rs | 32 ++++ src/test/ui/or-patterns/for-loop.rs | 18 +++ src/test/ui/or-patterns/if-let-while-let.rs | 22 +++ .../issue-67514-irrefutable-param.rs | 11 ++ src/test/ui/or-patterns/let-pattern.rs | 19 +++ .../ui/or-patterns/search-via-bindings.rs | 66 ++++++++ 10 files changed, 474 insertions(+) create mode 100644 src/test/mir-opt/exponential-or.rs create mode 100644 src/test/ui/borrowck/or-patterns.rs create mode 100644 src/test/ui/borrowck/or-patterns.stderr create mode 100644 src/test/ui/or-patterns/bindings-runpass-1.rs create mode 100644 src/test/ui/or-patterns/bindings-runpass-2.rs create mode 100644 src/test/ui/or-patterns/for-loop.rs create mode 100644 src/test/ui/or-patterns/if-let-while-let.rs create mode 100644 src/test/ui/or-patterns/issue-67514-irrefutable-param.rs create mode 100644 src/test/ui/or-patterns/let-pattern.rs create mode 100644 src/test/ui/or-patterns/search-via-bindings.rs diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential-or.rs new file mode 100644 index 0000000000000..4c23582e1f894 --- /dev/null +++ b/src/test/mir-opt/exponential-or.rs @@ -0,0 +1,76 @@ +// Test that simple or-patterns don't get expanded to exponentially large CFGs + +// ignore-tidy-linelength + +#![feature(or_patterns)] + +fn match_tuple(x: (u32, bool, Option, u32)) -> u32 { + match x { + (y @ (1 | 4), true | false, Some(1 | 8) | None, z @ (6..=9 | 13..=16)) => y ^ z, + _ => 0, + } +} + +fn main() {} + +// END RUST SOURCE + +// START rustc.match_tuple.SimplifyCfg-initial.after.mir +// scope 1 { +// debug y => _7; +// debug z => _8; +// } +// bb0: { +// FakeRead(ForMatchedPlace, _1); +// switchInt((_1.0: u32)) -> [1u32: bb2, 4u32: bb2, otherwise: bb1]; +// } +// bb1: { +// _0 = const 0u32; +// goto -> bb10; +// } +// bb2: { +// _2 = discriminant((_1.2: std::option::Option)); +// switchInt(move _2) -> [0isize: bb4, 1isize: bb3, otherwise: bb1]; +// } +// bb3: { +// switchInt((((_1.2: std::option::Option) as Some).0: i32)) -> [1i32: bb4, 8i32: bb4, otherwise: bb1]; +// } +// bb4: { +// _5 = Le(const 6u32, (_1.3: u32)); +// switchInt(move _5) -> [false: bb6, otherwise: bb5]; +// } +// bb5: { +// _6 = Le((_1.3: u32), const 9u32); +// switchInt(move _6) -> [false: bb6, otherwise: bb8]; +// } +// bb6: { +// _3 = Le(const 13u32, (_1.3: u32)); +// switchInt(move _3) -> [false: bb1, otherwise: bb7]; +// } +// bb7: { +// _4 = Le((_1.3: u32), const 16u32); +// switchInt(move _4) -> [false: bb1, otherwise: bb8]; +// } +// bb8: { +// falseEdges -> [real: bb9, imaginary: bb1]; +// } +// bb9: { +// StorageLive(_7); +// _7 = (_1.0: u32); +// StorageLive(_8); +// _8 = (_1.3: u32); +// StorageLive(_9); +// _9 = _7; +// StorageLive(_10); +// _10 = _8; +// _0 = BitXor(move _9, move _10); +// StorageDead(_10); +// StorageDead(_9); +// StorageDead(_8); +// StorageDead(_7); +// goto -> bb10; +// } +// bb10: { +// return; +// } +// END rustc.match_tuple.SimplifyCfg-initial.after.mir diff --git a/src/test/ui/borrowck/or-patterns.rs b/src/test/ui/borrowck/or-patterns.rs new file mode 100644 index 0000000000000..5b31e2d76a05b --- /dev/null +++ b/src/test/ui/borrowck/or-patterns.rs @@ -0,0 +1,64 @@ +// Test that borrow check considers all choices in an or pattern, even the +// unreachable ones. + +#![feature(or_patterns)] + +fn or_pattern_moves_all(x: ((String, String),)) { + match x { + ((y, _) | (_, y),) => (), + } + &x.0 .0; + //~^ ERROR borrow of moved value + &x.0 .1; + //~^ ERROR borrow of moved value +} + +fn or_pattern_borrows_all(mut x: ((String, String),)) { + let r = match x { + ((ref y, _) | (_, ref y),) => y, + }; + &mut x.0 .0; + //~^ ERROR cannot borrow + &mut x.0 .1; + //~^ ERROR cannot borrow + drop(r); +} + +fn or_pattern_borrows_all_mut(mut x: ((String, String),)) { + let r = match x { + ((ref mut y, _) | (_, ref mut y),) => y, + }; + &x.0 .0; + //~^ ERROR cannot borrow + &x.0 .1; + //~^ ERROR cannot borrow + drop(r); +} + +fn let_or_pattern_moves_all(x: ((String, String),)) { + let ((y, _) | (_, y),) = x; + &x.0 .0; + //~^ ERROR borrow of moved value + &x.0 .1; + //~^ ERROR borrow of moved value +} + +fn let_or_pattern_borrows_all(mut x: ((String, String),)) { + let ((ref r, _) | (_, ref r),) = x; + &mut x.0 .0; + //~^ ERROR cannot borrow + &mut x.0 .1; + //~^ ERROR cannot borrow + drop(r); +} + +fn let_or_pattern_borrows_all_mut(mut x: ((String, String),)) { + let ((ref mut r, _) | (_, ref mut r),) = x; + &x.0 .0; + //~^ ERROR cannot borrow + &x.0 .1; + //~^ ERROR cannot borrow + drop(r); +} + +fn main() {} diff --git a/src/test/ui/borrowck/or-patterns.stderr b/src/test/ui/borrowck/or-patterns.stderr new file mode 100644 index 0000000000000..d3f3544426aad --- /dev/null +++ b/src/test/ui/borrowck/or-patterns.stderr @@ -0,0 +1,141 @@ +error[E0382]: borrow of moved value: `x.0.0` + --> $DIR/or-patterns.rs:10:5 + | +LL | ((y, _) | (_, y),) => (), + | - value moved here +LL | } +LL | &x.0 .0; + | ^^^^^^^ value borrowed here after move + | + = note: move occurs because `x.0.0` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x.0.1` + --> $DIR/or-patterns.rs:12:5 + | +LL | ((y, _) | (_, y),) => (), + | - value moved here +... +LL | &x.0 .1; + | ^^^^^^^ value borrowed here after move + | + = note: move occurs because `x.0.1` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0502]: cannot borrow `x.0.0` as mutable because it is also borrowed as immutable + --> $DIR/or-patterns.rs:20:5 + | +LL | ((ref y, _) | (_, ref y),) => y, + | ----- immutable borrow occurs here +LL | }; +LL | &mut x.0 .0; + | ^^^^^^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x.0.1` as mutable because it is also borrowed as immutable + --> $DIR/or-patterns.rs:22:5 + | +LL | ((ref y, _) | (_, ref y),) => y, + | ----- immutable borrow occurs here +... +LL | &mut x.0 .1; + | ^^^^^^^^^^^ mutable borrow occurs here +LL | +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x.0.0` as immutable because it is also borrowed as mutable + --> $DIR/or-patterns.rs:31:5 + | +LL | ((ref mut y, _) | (_, ref mut y),) => y, + | --------- mutable borrow occurs here +LL | }; +LL | &x.0 .0; + | ^^^^^^^ immutable borrow occurs here +... +LL | drop(r); + | - mutable borrow later used here + +error[E0502]: cannot borrow `x.0.1` as immutable because it is also borrowed as mutable + --> $DIR/or-patterns.rs:33:5 + | +LL | ((ref mut y, _) | (_, ref mut y),) => y, + | --------- mutable borrow occurs here +... +LL | &x.0 .1; + | ^^^^^^^ immutable borrow occurs here +LL | +LL | drop(r); + | - mutable borrow later used here + +error[E0382]: borrow of moved value: `x.0.0` + --> $DIR/or-patterns.rs:40:5 + | +LL | let ((y, _) | (_, y),) = x; + | - value moved here +LL | &x.0 .0; + | ^^^^^^^ value borrowed here after move + | + = note: move occurs because `x.0.0` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x.0.1` + --> $DIR/or-patterns.rs:42:5 + | +LL | let ((y, _) | (_, y),) = x; + | - value moved here +... +LL | &x.0 .1; + | ^^^^^^^ value borrowed here after move + | + = note: move occurs because `x.0.1` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0502]: cannot borrow `x.0.0` as mutable because it is also borrowed as immutable + --> $DIR/or-patterns.rs:48:5 + | +LL | let ((ref r, _) | (_, ref r),) = x; + | ----- immutable borrow occurs here +LL | &mut x.0 .0; + | ^^^^^^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x.0.1` as mutable because it is also borrowed as immutable + --> $DIR/or-patterns.rs:50:5 + | +LL | let ((ref r, _) | (_, ref r),) = x; + | ----- immutable borrow occurs here +... +LL | &mut x.0 .1; + | ^^^^^^^^^^^ mutable borrow occurs here +LL | +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x.0.0` as immutable because it is also borrowed as mutable + --> $DIR/or-patterns.rs:57:5 + | +LL | let ((ref mut r, _) | (_, ref mut r),) = x; + | --------- mutable borrow occurs here +LL | &x.0 .0; + | ^^^^^^^ immutable borrow occurs here +... +LL | drop(r); + | - mutable borrow later used here + +error[E0502]: cannot borrow `x.0.1` as immutable because it is also borrowed as mutable + --> $DIR/or-patterns.rs:59:5 + | +LL | let ((ref mut r, _) | (_, ref mut r),) = x; + | --------- mutable borrow occurs here +... +LL | &x.0 .1; + | ^^^^^^^ immutable borrow occurs here +LL | +LL | drop(r); + | - mutable borrow later used here + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/or-patterns/bindings-runpass-1.rs b/src/test/ui/or-patterns/bindings-runpass-1.rs new file mode 100644 index 0000000000000..0087167af7ecc --- /dev/null +++ b/src/test/ui/or-patterns/bindings-runpass-1.rs @@ -0,0 +1,25 @@ +// run-pass + +#![feature(or_patterns)] + +fn two_bindings(x: &((bool, bool), u8)) -> u8 { + match x { + &((true, y) | (y, true), z @ (0 | 4)) => (y as u8) + z, + _ => 20, + } +} + +fn main() { + assert_eq!(two_bindings(&((false, false), 0)), 20); + assert_eq!(two_bindings(&((false, true), 0)), 0); + assert_eq!(two_bindings(&((true, false), 0)), 0); + assert_eq!(two_bindings(&((true, true), 0)), 1); + assert_eq!(two_bindings(&((false, false), 4)), 20); + assert_eq!(two_bindings(&((false, true), 4)), 4); + assert_eq!(two_bindings(&((true, false), 4)), 4); + assert_eq!(two_bindings(&((true, true), 4)), 5); + assert_eq!(two_bindings(&((false, false), 3)), 20); + assert_eq!(two_bindings(&((false, true), 3)), 20); + assert_eq!(two_bindings(&((true, false), 3)), 20); + assert_eq!(two_bindings(&((true, true), 3)), 20); +} diff --git a/src/test/ui/or-patterns/bindings-runpass-2.rs b/src/test/ui/or-patterns/bindings-runpass-2.rs new file mode 100644 index 0000000000000..0e1eb7b2e030b --- /dev/null +++ b/src/test/ui/or-patterns/bindings-runpass-2.rs @@ -0,0 +1,32 @@ +// run-pass + +#![feature(or_patterns)] + +fn or_at(x: Result) -> u32 { + match x { + Ok(x @ 4) | Err(x @ (6 | 8)) => x, + Ok(x @ 1 | x @ 2) => x, + Err(x @ (0..=10 | 30..=40)) if x % 2 == 0 => x + 100, + Err(x @ 0..=40) => x + 200, + _ => 500, + } +} + +fn main() { + assert_eq!(or_at(Ok(1)), 1); + assert_eq!(or_at(Ok(2)), 2); + assert_eq!(or_at(Ok(3)), 500); + assert_eq!(or_at(Ok(4)), 4); + assert_eq!(or_at(Ok(5)), 500); + assert_eq!(or_at(Ok(6)), 500); + assert_eq!(or_at(Err(1)), 201); + assert_eq!(or_at(Err(2)), 102); + assert_eq!(or_at(Err(3)), 203); + assert_eq!(or_at(Err(4)), 104); + assert_eq!(or_at(Err(5)), 205); + assert_eq!(or_at(Err(6)), 6); + assert_eq!(or_at(Err(7)), 207); + assert_eq!(or_at(Err(8)), 8); + assert_eq!(or_at(Err(20)), 220); + assert_eq!(or_at(Err(50)), 500); +} diff --git a/src/test/ui/or-patterns/for-loop.rs b/src/test/ui/or-patterns/for-loop.rs new file mode 100644 index 0000000000000..b79af6c402ec5 --- /dev/null +++ b/src/test/ui/or-patterns/for-loop.rs @@ -0,0 +1,18 @@ +// Check that or patterns are lowered correctly in `for` loops. +// run-pass + +#![feature(or_patterns)] + +fn main() { + let v = vec![Ok(2), Err(3), Ok(5)]; + let mut w = Vec::new(); + for &(Ok(i) | Err(i)) in &v { + w.push(i); + } + let mut u = Vec::new(); + for Ok(i) | Err(i) in v { + u.push(i); + } + assert_eq!(w, [2, 3, 5]); + assert_eq!(u, [2, 3, 5]); +} diff --git a/src/test/ui/or-patterns/if-let-while-let.rs b/src/test/ui/or-patterns/if-let-while-let.rs new file mode 100644 index 0000000000000..9256360b29db9 --- /dev/null +++ b/src/test/ui/or-patterns/if-let-while-let.rs @@ -0,0 +1,22 @@ +// Check that or patterns are lowered correctly in `if let` and `while let` expressions. +// run-pass + +#![feature(or_patterns)] + +fn main() { + let mut opt = Some(3); + let mut w = Vec::new(); + while let Some(ref mut val @ (3 | 4 | 6)) = opt { + w.push(*val); + *val += 1; + } + assert_eq!(w, [3, 4]); + if let &(None | Some(6 | 7)) = &opt { + unreachable!(); + } + if let Some(x @ (4 | 5 | 6)) = opt { + assert_eq!(x, 5); + } else { + unreachable!(); + } +} diff --git a/src/test/ui/or-patterns/issue-67514-irrefutable-param.rs b/src/test/ui/or-patterns/issue-67514-irrefutable-param.rs new file mode 100644 index 0000000000000..0c2ae44e546d9 --- /dev/null +++ b/src/test/ui/or-patterns/issue-67514-irrefutable-param.rs @@ -0,0 +1,11 @@ +// Check that we don't ICE for irrefutable or-patterns in function parameters + +// check-pass + +#![feature(or_patterns)] + +fn foo((Some(_) | None): Option) {} + +fn main() { + foo(None); +} diff --git a/src/test/ui/or-patterns/let-pattern.rs b/src/test/ui/or-patterns/let-pattern.rs new file mode 100644 index 0000000000000..07e37412ce842 --- /dev/null +++ b/src/test/ui/or-patterns/let-pattern.rs @@ -0,0 +1,19 @@ +#![feature(or_patterns)] + +// run-pass + +fn or_pat_let(x: Result) -> u32 { + let Ok(y) | Err(y) = x; + y +} + +fn or_pat_arg((Ok(y) | Err(y)): Result) -> u32 { + y +} + +fn main() { + assert_eq!(or_pat_let(Ok(3)), 3); + assert_eq!(or_pat_let(Err(5)), 5); + assert_eq!(or_pat_arg(Ok(7)), 7); + assert_eq!(or_pat_arg(Err(9)), 9); +} diff --git a/src/test/ui/or-patterns/search-via-bindings.rs b/src/test/ui/or-patterns/search-via-bindings.rs new file mode 100644 index 0000000000000..eb127b881cd37 --- /dev/null +++ b/src/test/ui/or-patterns/search-via-bindings.rs @@ -0,0 +1,66 @@ +// Check that we expand multiple or-patterns from left to right. + +// run-pass + +#![feature(or_patterns)] +#![allow(unreachable_patterns)] // FIXME(or-patterns) this shouldn't trigger + +fn search(target: (bool, bool, bool)) -> u32 { + let x = ((false, true), (false, true), (false, true)); + let mut guard_count = 0; + match x { + ((a, _) | (_, a), (b @ _, _) | (_, b @ _), (c @ false, _) | (_, c @ true)) + if { + guard_count += 1; + (a, b, c) == target + } => + { + guard_count + } + _ => unreachable!(), + } +} + +// Equivalent to the above code, but hopefully easier to understand. +fn search_old_style(target: (bool, bool, bool)) -> u32 { + let x = ((false, true), (false, true), (false, true)); + let mut guard_count = 0; + match x { + ((a, _), (b @ _, _), (c @ false, _)) + | ((a, _), (b @ _, _), (_, c @ true)) + | ((a, _), (_, b @ _), (c @ false, _)) + | ((a, _), (_, b @ _), (_, c @ true)) + | ((_, a), (b @ _, _), (c @ false, _)) + | ((_, a), (b @ _, _), (_, c @ true)) + | ((_, a), (_, b @ _), (c @ false, _)) + | ((_, a), (_, b @ _), (_, c @ true)) + if { + guard_count += 1; + (a, b, c) == target + } => + { + guard_count + } + _ => unreachable!(), + } +} + +fn main() { + assert_eq!(search((false, false, false)), 1); + assert_eq!(search((false, false, true)), 2); + assert_eq!(search((false, true, false)), 3); + assert_eq!(search((false, true, true)), 4); + assert_eq!(search((true, false, false)), 5); + assert_eq!(search((true, false, true)), 6); + assert_eq!(search((true, true, false)), 7); + assert_eq!(search((true, true, true)), 8); + + assert_eq!(search_old_style((false, false, false)), 1); + assert_eq!(search_old_style((false, false, true)), 2); + assert_eq!(search_old_style((false, true, false)), 3); + assert_eq!(search_old_style((false, true, true)), 4); + assert_eq!(search_old_style((true, false, false)), 5); + assert_eq!(search_old_style((true, false, true)), 6); + assert_eq!(search_old_style((true, true, false)), 7); + assert_eq!(search_old_style((true, true, true)), 8); +} From 5f90dbd5e86a5ba68ec03cef5dd2c2418f587dbb Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 29 Dec 2019 17:00:23 +0000 Subject: [PATCH 0857/1253] Make `Candidate` private --- src/librustc_mir_build/build/matches/mod.rs | 2 +- src/librustc_mir_build/build/matches/simplify.rs | 5 ++++- src/librustc_mir_build/build/matches/test.rs | 10 +++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 928363246c2c0..7e7035e89abee 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -659,7 +659,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } #[derive(Debug)] -crate struct Candidate<'pat, 'tcx> { +struct Candidate<'pat, 'tcx> { /// `Span` of the original pattern that gave rise to this candidate span: Span, diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 3a806ab6bff0a..d3ed7c4daf7eb 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -38,7 +38,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// only generates a single switch. If this happens this method returns /// `true`. - crate fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) -> bool { + pub(super) fn simplify_candidate<'pat>( + &mut self, + candidate: &mut Candidate<'pat, 'tcx>, + ) -> bool { // repeatedly simplify match pairs until fixed point is reached loop { let match_pairs = mem::take(&mut candidate.match_pairs); diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index ff95f16225751..dd0102e1c410f 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. /// /// It is a bug to call this with a simplifiable pattern. - crate fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { + pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { match *match_pair.pattern.kind { PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => Test { span: match_pair.pattern.span, @@ -81,7 +81,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - crate fn add_cases_to_switch<'pat>( + pub(super) fn add_cases_to_switch<'pat>( &mut self, test_place: &Place<'tcx>, candidate: &Candidate<'pat, 'tcx>, @@ -125,7 +125,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - crate fn add_variants_to_switch<'pat>( + pub(super) fn add_variants_to_switch<'pat>( &mut self, test_place: &Place<'tcx>, candidate: &Candidate<'pat, 'tcx>, @@ -152,7 +152,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - crate fn perform_test( + pub(super) fn perform_test( &mut self, block: BasicBlock, place: &Place<'tcx>, @@ -498,7 +498,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// that it *doesn't* apply. For now, we return false, indicate that the /// test does not apply to this candidate, but it might be we can get /// tighter match code if we do something a bit different. - crate fn sort_candidate<'pat>( + pub(super) fn sort_candidate<'pat>( &mut self, test_place: &Place<'tcx>, test: &Test<'tcx>, From 89e52e2ca9e5bf63c197c2dfa7d062f409fbeec7 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 29 Dec 2019 17:28:41 +0000 Subject: [PATCH 0858/1253] Address review comments --- src/librustc_mir_build/build/matches/mod.rs | 221 +++++++++++------- .../build/matches/simplify.rs | 18 +- 2 files changed, 143 insertions(+), 96 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 7e7035e89abee..d5ac2a14129ce 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -153,18 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arms.iter() .map(|arm| { let arm_has_guard = arm.guard.is_some(); - let arm_candidate = Candidate { - span: arm.pattern.span, - match_pairs: smallvec![MatchPair::new(*scrutinee, &arm.pattern),], - bindings: vec![], - ascriptions: vec![], - has_guard: arm_has_guard, - needs_otherwise_block: arm_has_guard, - otherwise_block: None, - pre_binding_block: None, - next_candidate_pre_binding_block: None, - subcandidates: vec![], - }; + let arm_candidate = Candidate::new(*scrutinee, &arm.pattern, arm_has_guard); (arm, arm_candidate) }) .collect() @@ -195,10 +184,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.match_candidates(scrutinee_span, block, &mut otherwise, candidates, &mut fake_borrows); if let Some(otherwise_block) = otherwise { + // See the doc comment on `match_candidates` for why we may have an + // otherwise block. Match checking will ensure this is actually + // unreachable. let source_info = self.source_info(scrutinee_span); self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); } + // Link each leaf candidate to the `pre_binding_block` of the next one. let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; for candidate in candidates { @@ -449,29 +442,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer: &Place<'tcx>, set_match_place: bool, ) -> BlockAnd<()> { - // create a dummy candidate - let mut candidate = Candidate { - span: irrefutable_pat.span, - has_guard: false, - needs_otherwise_block: false, - match_pairs: smallvec![MatchPair::new(*initializer, &irrefutable_pat)], - bindings: vec![], - ascriptions: vec![], - - // since we don't call `match_candidates`, next fields are unused - otherwise_block: None, - pre_binding_block: None, - next_candidate_pre_binding_block: None, - subcandidates: vec![], - }; + let mut candidate = Candidate::new(*initializer, &irrefutable_pat, false); let fake_borrow_temps = self.lower_match_tree(block, irrefutable_pat.span, false, &mut [&mut candidate]); - // for matches and function arguments, the place that is being matched + // For matches and function arguments, the place that is being matched // can be set when creating the variables. But the place for // let PATTERN = ... might not even exist until we do the assignment. - // so we set it here instead + // so we set it here instead. if set_match_place { let mut candidate_ref = &candidate; while let Some(next) = { @@ -487,6 +466,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("Let binding to non-user variable.") } } + // All of the subcandidates should bind the same locals, so we + // only visit the first one. candidate_ref.subcandidates.get(0) } { candidate_ref = next; @@ -666,10 +647,6 @@ struct Candidate<'pat, 'tcx> { /// This `Candidate` has a guard. has_guard: bool, - /// This `Candidate` needs and otherwise block, either because it has a - /// guard or it has subcandidates. - needs_otherwise_block: bool, - /// All of these must be satisfied... match_pairs: SmallVec<[MatchPair<'pat, 'tcx>; 1]>, @@ -690,7 +667,21 @@ struct Candidate<'pat, 'tcx> { next_candidate_pre_binding_block: Option, } -impl Candidate<'_, '_> { +impl<'tcx, 'pat> Candidate<'pat, 'tcx> { + fn new(place: Place<'tcx>, pattern: &'pat Pat<'tcx>, has_guard: bool) -> Self { + Candidate { + span: pattern.span, + has_guard, + match_pairs: smallvec![MatchPair { place, pattern }], + bindings: Vec::new(), + ascriptions: Vec::new(), + subcandidates: Vec::new(), + otherwise_block: None, + pre_binding_block: None, + next_candidate_pre_binding_block: None, + } + } + /// Visit the leaf candidates (those with no subcandidates) contained in /// this candidate. fn visit_leaves<'a>(&'a mut self, mut visit_leaf: impl FnMut(&'a mut Self)) { @@ -839,6 +830,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// If `fake_borrows` is Some, then places which need fake borrows /// will be added to it. + /// + /// For an example of a case where we set `otherwise_block`, even for an + /// exhaustive match consider: + /// + /// match x { + /// (true, true) => (), + /// (_, false) => (), + /// (false, true) => (), + /// } + /// + /// For this match we check if `x.0` matches `true` (for the first + /// arm) if that's false we check `x.1`, if it's `true` we check if + /// `x.0` matches `false` (for the third arm). In the (impossible at + /// runtime) case when `x.0` is now `true` we branch to + /// `otherwise_block`. fn match_candidates<'pat>( &mut self, span: Span, @@ -1009,7 +1015,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fully_matched_with_guard = matched_candidates .iter() - .position(|c| !c.needs_otherwise_block) + .position(|c| !c.has_guard) .unwrap_or(matched_candidates.len() - 1); let (reachable_candidates, unreachable_candidates) = @@ -1021,7 +1027,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert!(candidate.otherwise_block.is_none()); assert!(candidate.pre_binding_block.is_none()); candidate.pre_binding_block = Some(next_prebinding); - if candidate.needs_otherwise_block { + if candidate.has_guard { + // Create the otherwise block for this candidate, which is the + // pre-binding block for the next candidate. next_prebinding = self.cfg.start_new_block(); candidate.otherwise_block = Some(next_prebinding); } @@ -1039,6 +1047,53 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { reachable_candidates.last_mut().unwrap().otherwise_block } + /// Tests a candidate where there are only or-patterns left to test, or + /// forwards to [Builder::test_candidates]. + /// + /// Given a pattern `(P | Q, R | S)` we (in principle) generate a CFG like + /// so + /// + /// ```text + /// [ start ] + /// | + /// [ match P, Q ] + /// | + /// +----------------------------------------+------------------------------------+ + /// | | | + /// [ P matches ] [ Q matches ] [ otherwise ] + /// | | | + /// [ match R, S ] [ match R, S ] | + /// | | | + /// +--------------+------------+ +--------------+------------+ | + /// | | | | | | | + /// [ R matches ] [ S matches ] [otherwise ] [ R matches ] [ S matches ] [otherwise ] | + /// | | | | | | | + /// +--------------+------------|------------+--------------+ | | + /// | | | | + /// | +----------------------------------------+--------+ + /// | | + /// [ Success ] [ Failure ] + /// ``` + /// + /// In practice there are some complications: + /// + /// * If there's a guard, then the otherwise branch of the first match on + /// `R | S` goes to a test for whether `Q` matches. + /// * If neither `P` or `Q` has any bindings or type ascriptions and there + /// isn't a match guard, then we create a smaller CFG like: + /// + /// ```text + /// ... + /// +---------------+------------+ + /// | | | + /// [ P matches ] [ Q matches ] [ otherwise ] + /// | | | + /// +---------------+ | + /// | ... + /// [ match R, S ] + /// | + /// ... + /// ``` fn test_candidates_with_or( &mut self, span: Span, @@ -1049,42 +1104,53 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap(); - if let PatKind::Or { .. } = *first_candidate.match_pairs[0].pattern.kind { - let match_pairs = mem::take(&mut first_candidate.match_pairs); - first_candidate.needs_otherwise_block = true; - first_candidate.pre_binding_block = Some(block); + match *first_candidate.match_pairs[0].pattern.kind { + PatKind::Or { .. } => (), + _ => { + self.test_candidates(span, candidates, block, otherwise_block, fake_borrows); + return; + } + } - // We sort or-patterns to the end in `simplify_candidate`, so all - // the remaining match pairs are or-patterns. - for match_pair in match_pairs { - if let PatKind::Or { ref pats } = *match_pair.pattern.kind { - let or_span = match_pair.pattern.span; - let place = &match_pair.place; + let match_pairs = mem::take(&mut first_candidate.match_pairs); + first_candidate.pre_binding_block = Some(block); - first_candidate.visit_leaves(|leaf_candidate| { - self.test_or_pattern(leaf_candidate, pats, or_span, place, fake_borrows); - }); - } else { - bug!("Or patterns should have been sorted to the end"); - } + let mut otherwise = None; + for match_pair in match_pairs { + if let PatKind::Or { ref pats } = *match_pair.pattern.kind { + let or_span = match_pair.pattern.span; + let place = &match_pair.place; + + first_candidate.visit_leaves(|leaf_candidate| { + self.test_or_pattern( + leaf_candidate, + &mut otherwise, + pats, + or_span, + place, + fake_borrows, + ); + }); + } else { + bug!("Or-patterns should have been sorted to the end"); } - let remainder_start = - first_candidate.otherwise_block.unwrap_or_else(|| self.cfg.start_new_block()); - self.match_candidates( - span, - remainder_start, - otherwise_block, - remaining_candidates, - fake_borrows, - ) - } else { - self.test_candidates(span, candidates, block, otherwise_block, fake_borrows) } + + let remainder_start = otherwise.unwrap_or_else(|| self.cfg.start_new_block()); + + self.match_candidates( + span, + remainder_start, + otherwise_block, + remaining_candidates, + fake_borrows, + ) } fn test_or_pattern<'pat>( &mut self, candidate: &mut Candidate<'pat, 'tcx>, + otherwise: &mut Option, pats: &'pat [Pat<'tcx>], or_span: Span, place: &Place<'tcx>, @@ -1093,27 +1159,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("test_or_pattern:\ncandidate={:#?}\npats={:#?}", candidate, pats); let mut or_candidates: Vec<_> = pats .iter() - .map(|pat| { - let new_match_pair = smallvec![MatchPair { pattern: pat, place: place.clone() }]; - Candidate { - span: pat.span, - has_guard: candidate.has_guard, - needs_otherwise_block: candidate.needs_otherwise_block, - match_pairs: new_match_pair, - bindings: Vec::new(), - ascriptions: Vec::new(), - otherwise_block: None, - pre_binding_block: None, - next_candidate_pre_binding_block: None, - subcandidates: Vec::new(), - } - }) + .map(|pat| Candidate::new(place.clone(), pat, candidate.has_guard)) .collect(); let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect(); + let otherwise = if candidate.otherwise_block.is_some() { + &mut candidate.otherwise_block + } else { + otherwise + }; self.match_candidates( or_span, candidate.pre_binding_block.unwrap(), - &mut candidate.otherwise_block, + otherwise, &mut or_candidate_refs, fake_borrows, ); @@ -1128,10 +1185,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'_, 'tcx>, source_info: SourceInfo, ) { - if candidate.subcandidates.is_empty() { + if candidate.subcandidates.is_empty() || candidate.has_guard { + // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard. return; } - let mut can_merge = !candidate.has_guard; + + let mut can_merge = true; // Not `Iterator::all` because we don't want to short-circuit. for subcandidate in &mut candidate.subcandidates { diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index d3ed7c4daf7eb..422a75a4f37a1 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -22,7 +22,6 @@ use rustc::ty::layout::{Integer, IntegerExt, Size}; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; -use smallvec::smallvec; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -49,7 +48,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, ref place }] = *match_pairs { - candidate.subcandidates = self.create_or_subcanidates(candidate, place, pats); + candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats); return true; } @@ -76,7 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - fn create_or_subcanidates<'pat>( + fn create_or_subcandidates<'pat>( &mut self, candidate: &Candidate<'pat, 'tcx>, place: &Place<'tcx>, @@ -84,18 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> Vec> { pats.iter() .map(|pat| { - let mut candidate = Candidate { - span: pat.span, - has_guard: candidate.has_guard, - needs_otherwise_block: candidate.needs_otherwise_block, - match_pairs: smallvec![MatchPair { place: place.clone(), pattern: pat }], - bindings: vec![], - ascriptions: vec![], - subcandidates: vec![], - otherwise_block: None, - pre_binding_block: None, - next_candidate_pre_binding_block: None, - }; + let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard); self.simplify_candidate(&mut candidate); candidate }) From 1d90ed6370df81cb6e30816cb655c5a90af824a6 Mon Sep 17 00:00:00 2001 From: matthewjasper <20113453+matthewjasper@users.noreply.github.com> Date: Mon, 30 Dec 2019 17:47:10 +0000 Subject: [PATCH 0859/1253] Apply suggestions from code review Co-Authored-By: Mazdak Farrokhzad --- src/librustc_mir_build/build/matches/mod.rs | 8 +++++--- src/test/ui/or-patterns/basic-switchint.rs | 3 --- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index d5ac2a14129ce..ed5d74f2e6859 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -840,10 +840,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// (false, true) => (), /// } /// - /// For this match we check if `x.0` matches `true` (for the first - /// arm) if that's false we check `x.1`, if it's `true` we check if + /// For this match, we check if `x.0` matches `true` (for the first + /// arm). If that's false, we check `x.1`. If it's `true` we check if /// `x.0` matches `false` (for the third arm). In the (impossible at - /// runtime) case when `x.0` is now `true` we branch to + /// runtime) case when `x.0` is now `true`, we branch to /// `otherwise_block`. fn match_candidates<'pat>( &mut self, @@ -1104,6 +1104,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap(); + // All of the or-patterns have been sorted to the end, so if the first + // pattern is an or-pattern we only have or-patterns. match *first_candidate.match_pairs[0].pattern.kind { PatKind::Or { .. } => (), _ => { diff --git a/src/test/ui/or-patterns/basic-switchint.rs b/src/test/ui/or-patterns/basic-switchint.rs index 2ae5f2681655a..c5a6d894eacec 100644 --- a/src/test/ui/or-patterns/basic-switchint.rs +++ b/src/test/ui/or-patterns/basic-switchint.rs @@ -26,9 +26,6 @@ fn test_foo(x: Foo) -> MatchArm { // multiple or-patterns for one structure. Foo::Two(42 | 255, 1024 | 2048) => MatchArm::Arm(2), // mix of pattern types in one or-pattern (range). - // - // FIXME(dlrobertson | Nadrieril): Fix or-pattern completeness and - // unreachabilitychecks for ranges. Foo::One(100 | 110..=120 | 210..=220) => MatchArm::Arm(3), // multiple or-patterns with wild. Foo::Two(0..=10 | 100..=110, 0 | _) => MatchArm::Arm(4), From 9b9dafb2c8795a542e1c93036afa02889ef696f0 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 11 Jan 2020 20:30:42 +0000 Subject: [PATCH 0860/1253] Make use of `Place: Copy` --- src/librustc_mir_build/build/matches/mod.rs | 42 +++++++++---------- .../build/matches/simplify.rs | 6 +-- src/librustc_mir_build/build/matches/test.rs | 26 +++++------- src/librustc_mir_build/build/mod.rs | 2 +- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index ed5d74f2e6859..7ab9129398975 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scrutinee_place = unpack!(block = self.lower_scrutinee(block, scrutinee, scrutinee_span,)); - let mut arm_candidates = self.create_match_candidates(&scrutinee_place, &arms); + let mut arm_candidates = self.create_match_candidates(scrutinee_place, &arms); let match_has_guard = arms.iter().any(|arm| arm.guard.is_some()); let mut candidates = @@ -103,7 +103,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.lower_match_tree(block, scrutinee_span, match_has_guard, &mut candidates); self.lower_match_arms( - &destination, + destination, scrutinee_place, scrutinee_span, arm_candidates, @@ -137,7 +137,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // check safety. let cause_matched_place = FakeReadCause::ForMatchedPlace; let source_info = self.source_info(scrutinee_span); - self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place.clone()); + self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place); block.and(scrutinee_place) } @@ -145,7 +145,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Create the initial `Candidate`s for a `match` expression. fn create_match_candidates<'pat>( &mut self, - scrutinee: &Place<'tcx>, + scrutinee: Place<'tcx>, arms: &'pat [Arm<'tcx>], ) -> Vec<(&'pat Arm<'tcx>, Candidate<'pat, 'tcx>)> { // Assemble a list of candidates: there is one candidate per pattern, @@ -153,7 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arms.iter() .map(|arm| { let arm_has_guard = arm.guard.is_some(); - let arm_candidate = Candidate::new(*scrutinee, &arm.pattern, arm_has_guard); + let arm_candidate = Candidate::new(scrutinee, &arm.pattern, arm_has_guard); (arm, arm_candidate) }) .collect() @@ -391,7 +391,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Inject a fake read, see comments on `FakeReadCause::ForLet`. let pattern_source_info = self.source_info(irrefutable_pat.span); let cause_let = FakeReadCause::ForLet; - self.cfg.push_fake_read(block, pattern_source_info, cause_let, place.clone()); + self.cfg.push_fake_read(block, pattern_source_info, cause_let, place); let ty_source_info = self.source_info(user_ty_span); let user_ty = pat_ascription_ty.user_ty( @@ -430,7 +430,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => { let place = unpack!(block = self.as_place(block, initializer)); - self.place_into_pattern(block, irrefutable_pat, &place, true) + self.place_into_pattern(block, irrefutable_pat, place, true) } } } @@ -439,10 +439,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, block: BasicBlock, irrefutable_pat: Pat<'tcx>, - initializer: &Place<'tcx>, + initializer: Place<'tcx>, set_match_place: bool, ) -> BlockAnd<()> { - let mut candidate = Candidate::new(*initializer, &irrefutable_pat, false); + let mut candidate = Candidate::new(initializer, &irrefutable_pat, false); let fake_borrow_temps = self.lower_match_tree(block, irrefutable_pat.span, false, &mut [&mut candidate]); @@ -461,7 +461,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. }, ))) = self.local_decls[local].local_info { - *match_place = Some(*initializer); + *match_place = Some(initializer); } else { bug!("Let binding to non-user variable.") } @@ -897,7 +897,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, start_block: BasicBlock, otherwise_block: &mut Option, - candidates: &mut [&mut Candidate<_, 'tcx>], + candidates: &mut [&mut Candidate<'_, 'tcx>], fake_borrows: &mut Option>>, ) { // The candidates are sorted by priority. Check to see whether the @@ -1121,7 +1121,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for match_pair in match_pairs { if let PatKind::Or { ref pats } = *match_pair.pattern.kind { let or_span = match_pair.pattern.span; - let place = &match_pair.place; + let place = match_pair.place; first_candidate.visit_leaves(|leaf_candidate| { self.test_or_pattern( @@ -1155,14 +1155,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { otherwise: &mut Option, pats: &'pat [Pat<'tcx>], or_span: Span, - place: &Place<'tcx>, + place: Place<'tcx>, fake_borrows: &mut Option>>, ) { debug!("test_or_pattern:\ncandidate={:#?}\npats={:#?}", candidate, pats); - let mut or_candidates: Vec<_> = pats - .iter() - .map(|pat| Candidate::new(place.clone(), pat, candidate.has_guard)) - .collect(); + let mut or_candidates: Vec<_> = + pats.iter().map(|pat| Candidate::new(place, pat, candidate.has_guard)).collect(); let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect(); let otherwise = if candidate.otherwise_block.is_some() { &mut candidate.otherwise_block @@ -1368,7 +1366,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Insert a Shallow borrow of any places that is switched on. - fake_borrows.as_mut().map(|fb| fb.insert(match_place.clone())); + fake_borrows.as_mut().map(|fb| fb.insert(match_place)); // perform the test, branching to one of N blocks. For each of // those N possible outcomes, create a (initially empty) @@ -1448,7 +1446,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target_blocks }; - self.perform_test(block, &match_place, &test, make_target_blocks); + self.perform_test(block, match_place, &test, make_target_blocks); } /// Determine the fake borrows that are needed from a set of places that @@ -1669,9 +1667,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let re_erased = tcx.lifetimes.re_erased; let scrutinee_source_info = self.source_info(scrutinee_span); - for (place, temp) in fake_borrows { - let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, *place); - self.cfg.push_assign(block, scrutinee_source_info, &Place::from(*temp), borrow); + for &(place, temp) in fake_borrows { + let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, place); + self.cfg.push_assign(block, scrutinee_source_info, &Place::from(temp), borrow); } // the block to branch to if the guard fails; if there is no diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 422a75a4f37a1..4213a30f2d8c1 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -45,7 +45,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { loop { let match_pairs = mem::take(&mut candidate.match_pairs); - if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, ref place }] = + if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, place }] = *match_pairs { candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats); @@ -78,12 +78,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn create_or_subcandidates<'pat>( &mut self, candidate: &Candidate<'pat, 'tcx>, - place: &Place<'tcx>, + place: Place<'tcx>, pats: &'pat [Pat<'tcx>], ) -> Vec> { pats.iter() .map(|pat| { - let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard); + let mut candidate = Candidate::new(place, pat, candidate.has_guard); self.simplify_candidate(&mut candidate); candidate }) diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index dd0102e1c410f..1acfa7dddbe1f 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -155,7 +155,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub(super) fn perform_test( &mut self, block: BasicBlock, - place: &Place<'tcx>, + place: Place<'tcx>, test: &Test<'tcx>, make_target_blocks: impl FnOnce(&mut Self) -> Vec, ) { @@ -205,7 +205,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let discr_ty = adt_def.repr.discr_type().to_ty(tcx); let discr = self.temp(discr_ty, test.span); - self.cfg.push_assign(block, source_info, &discr, Rvalue::Discriminant(*place)); + self.cfg.push_assign(block, source_info, &discr, Rvalue::Discriminant(place)); assert_eq!(values.len() + 1, targets.len()); self.cfg.terminate( block, @@ -229,12 +229,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 0 => (second_bb, first_bb), v => span_bug!(test.span, "expected boolean value but got {:?}", v), }; - TerminatorKind::if_( - self.hir.tcx(), - Operand::Copy(*place), - true_bb, - false_bb, - ) + TerminatorKind::if_(self.hir.tcx(), Operand::Copy(place), true_bb, false_bb) } else { bug!("`TestKind::SwitchInt` on `bool` should have two targets") } @@ -242,7 +237,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // The switch may be inexhaustive so we have a catch all block debug_assert_eq!(options.len() + 1, target_blocks.len()); TerminatorKind::SwitchInt { - discr: Operand::Copy(*place), + discr: Operand::Copy(place), switch_ty, values: options.clone().into(), targets: target_blocks, @@ -267,7 +262,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let [success, fail] = *make_target_blocks(self) { assert_eq!(value.ty, ty); let expect = self.literal_operand(test.span, value); - let val = Operand::Copy(*place); + let val = Operand::Copy(place); self.compare(block, success, fail, source_info, BinOp::Eq, expect, val); } else { bug!("`TestKind::Eq` should have two target blocks"); @@ -282,7 +277,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons. let lo = self.literal_operand(test.span, lo); let hi = self.literal_operand(test.span, hi); - let val = Operand::Copy(*place); + let val = Operand::Copy(place); if let [success, fail] = *target_blocks { self.compare( @@ -311,7 +306,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let actual = self.temp(usize_ty, test.span); // actual = len(place) - self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(*place)); + self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(place)); // expected = let expected = self.push_usize(block, source_info, len); @@ -367,13 +362,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { make_target_blocks: impl FnOnce(&mut Self) -> Vec, source_info: SourceInfo, value: &'tcx ty::Const<'tcx>, - place: &Place<'tcx>, + place: Place<'tcx>, mut ty: Ty<'tcx>, ) { use rustc::middle::lang_items::EqTraitLangItem; let mut expect = self.literal_operand(source_info.span, value); - let mut val = Operand::Copy(*place); + let mut val = Operand::Copy(place); // If we're using `b"..."` as a pattern, we need to insert an // unsizing coercion, as the byte string has the type `&[u8; N]`. @@ -751,8 +746,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let downcast_place = tcx.mk_place_elem(match_pair.place, elem); // `(x as Variant)` let consequent_match_pairs = subpatterns.iter().map(|subpattern| { // e.g., `(x as Variant).0` - let place = - tcx.mk_place_field(downcast_place.clone(), subpattern.field, subpattern.pattern.ty); + let place = tcx.mk_place_field(downcast_place, subpattern.field, subpattern.pattern.ty); // e.g., `(x as Variant).0 @ P1` MatchPair::new(place, &subpattern.pattern) }); diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 1f536b63a394a..7e51f7aafe4b3 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -899,7 +899,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { matches::ArmHasGuard(false), Some((Some(&place), span)), ); - unpack!(block = self.place_into_pattern(block, pattern, &place, false)); + unpack!(block = self.place_into_pattern(block, pattern, place, false)); } } self.source_scope = original_source_scope; From 8dbbe4d14467d95d89ca3dff9054522f32cc12e8 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 25 Jan 2020 00:10:40 +0000 Subject: [PATCH 0861/1253] Avoid scheduling repeated `StorageDead`s Also add some comments --- src/librustc_mir_build/build/block.rs | 2 +- src/librustc_mir_build/build/matches/mod.rs | 62 ++++++++++++++----- .../build/matches/simplify.rs | 3 + 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs index c517d3113c659..df5526ad76281 100644 --- a/src/librustc_mir_build/build/block.rs +++ b/src/librustc_mir_build/build/block.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &pattern, UserTypeProjections::none(), &mut |this, _, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard); + this.storage_live_binding(block, node, span, OutsideGuard, true); this.schedule_drop_for_binding(node, span, OutsideGuard); }, ) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 7ab9129398975..f900ae45b94d6 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -274,9 +274,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { end_block.unit() } - /// Binds the variables and ascribes types for a given `match` arm. + /// Binds the variables and ascribes types for a given `match` arm or + /// `let` binding. /// /// Also check if the guard matches, if it's provided. + /// `arm_scope` should be `Some` if and only if this is called for a + /// `match` arm. fn bind_pattern( &mut self, outer_source_info: SourceInfo, @@ -298,6 +301,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { true, ) } else { + // It's helpful to avoid scheduling drops multiple times to save + // drop elaboration from having to clean up the extra drops. + // + // If we are in a `let` then we only schedule drops for the first + // candidate. + // + // If we're in a `match` arm then we could have a case like so: + // + // Ok(x) | Err(x) if return => { /* ... */ } + // + // In this case we don't want a drop of `x` scheduled when we + // return: it isn't bound by move until right before enter the arm. + // To handle this we instead unschedule it's drop after each time + // we lower the guard. let target_block = self.cfg.start_new_block(); let mut schedule_drops = true; // We keep a stack of all of the bindings and type asciptions @@ -308,7 +325,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut Vec::new(), &mut |leaf_candidate, parent_bindings| { if let Some(arm_scope) = arm_scope { - // Avoid scheduling drops multiple times by unscheduling drops. self.clear_top_scope(arm_scope); } let binding_end = self.bind_and_guard_matched_candidate( @@ -320,9 +336,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { schedule_drops, ); if arm_scope.is_none() { - // If we aren't in a match, then our bindings may not be - // the only thing in the top scope, so only schedule - // them to drop for the first pattern instead. schedule_drops = false; } self.cfg.goto(binding_end, outer_source_info, target_block); @@ -350,7 +363,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Optimize the case of `let x = ...` to write directly into `x` PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => { let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard); + self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); unpack!(block = self.into(&place, block, initializer)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -385,7 +398,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { hair::pattern::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span }, } => { let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard); + self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); unpack!(block = self.into(&place, block, initializer)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -532,12 +545,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var: HirId, span: Span, for_guard: ForGuard, + schedule_drop: bool, ) -> Place<'tcx> { let local_id = self.var_local_id(var, for_guard); let source_info = self.source_info(span); self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) }); let region_scope = self.hir.region_scope_tree.var_scope(var.local_id); - self.schedule_drop(span, region_scope, local_id, DropKind::Storage); + if schedule_drop { + self.schedule_drop(span, region_scope, local_id, DropKind::Storage); + } Place::from(local_id) } @@ -1060,25 +1076,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// | /// +----------------------------------------+------------------------------------+ /// | | | + /// V V V /// [ P matches ] [ Q matches ] [ otherwise ] /// | | | + /// V V | /// [ match R, S ] [ match R, S ] | /// | | | /// +--------------+------------+ +--------------+------------+ | /// | | | | | | | + /// V V V V V V | /// [ R matches ] [ S matches ] [otherwise ] [ R matches ] [ S matches ] [otherwise ] | /// | | | | | | | /// +--------------+------------|------------+--------------+ | | /// | | | | /// | +----------------------------------------+--------+ /// | | + /// V V /// [ Success ] [ Failure ] /// ``` /// /// In practice there are some complications: /// /// * If there's a guard, then the otherwise branch of the first match on - /// `R | S` goes to a test for whether `Q` matches. + /// `R | S` goes to a test for whether `Q` matches, and the control flow + /// doesn't merge into a single success block until after the guard is + /// tested. /// * If neither `P` or `Q` has any bindings or type ascriptions and there /// isn't a match guard, then we create a smaller CFG like: /// @@ -1658,7 +1680,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .flat_map(|(bindings, _)| bindings) .chain(&candidate.bindings); - self.bind_matched_candidate_for_guard(block, bindings.clone()); + self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone()); let guard_frame = GuardFrame { locals: bindings.map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode)).collect(), }; @@ -1807,6 +1829,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_guard<'b>( &mut self, block: BasicBlock, + schedule_drops: bool, bindings: impl IntoIterator>, ) where 'tcx: 'b, @@ -1825,8 +1848,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // a reference R: &T pointing to the location matched by // the pattern, and every occurrence of P within a guard // denotes *R. - let ref_for_guard = - self.storage_live_binding(block, binding.var_id, binding.span, RefWithinGuard); + let ref_for_guard = self.storage_live_binding( + block, + binding.var_id, + binding.span, + RefWithinGuard, + schedule_drops, + ); match binding.binding_mode { BindingMode::ByValue => { let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source); @@ -1838,6 +1866,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { binding.var_id, binding.span, OutsideGuard, + schedule_drops, ); let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source); @@ -1863,8 +1892,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Assign each of the bindings. This may trigger moves out of the candidate. for binding in bindings { let source_info = self.source_info(binding.span); - let local = - self.storage_live_binding(block, binding.var_id, binding.span, OutsideGuard); + let local = self.storage_live_binding( + block, + binding.var_id, + binding.span, + OutsideGuard, + schedule_drops, + ); if schedule_drops { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); } diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 4213a30f2d8c1..56aa150dd37d2 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -75,6 +75,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + /// Given `candidate` that has a single or-pattern for its match-pairs, + /// creates a fresh candidate for each of its input subpatterns passed via + /// `pats`. fn create_or_subcandidates<'pat>( &mut self, candidate: &Candidate<'pat, 'tcx>, From 5e086c842f7bfac58a3d836495dde5d8c194cccc Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 3 Feb 2020 13:45:46 -0600 Subject: [PATCH 0862/1253] some cleanup/fixes --- src/tools/rustbook/src/main.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index a0b7b29f46257..023f5aa1e284b 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -8,9 +8,6 @@ use clap::{App, AppSettings, ArgMatches, SubCommand}; use mdbook::errors::Result as Result3; use mdbook::MDBook; -#[cfg(feature = "linkcheck")] -use mdbook::renderer::RenderContext; - fn main() { let d_message = "-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book when omitted)'"; @@ -87,14 +84,12 @@ pub fn linkcheck( use mdbook_linkcheck::Reason; let book_dir = get_book_dir(args); - let src_dir = get_book_dir(args).join("src"); + let src_dir = book_dir.join("src"); let book = MDBook::load(&book_dir).unwrap(); let linkck_cfg = mdbook_linkcheck::get_config(&book.config)?; let mut files = codespan::Files::new(); let target_files = mdbook_linkcheck::load_files_into_memory(&book.book, &mut files); - let render_ctx = RenderContext::new(&book_dir, book.book, book.config, &book_dir); - let cache_file = render_ctx.destination.join("cache.json"); - let cache = mdbook_linkcheck::Cache::load(std::fs::File::open(cache_file)?)?; + let cache = mdbook_linkcheck::Cache::default(); let (links, incomplete) = mdbook_linkcheck::extract_links(target_files, &files); From 5f689fe466b6ed0d63e5d5f732804bb74c07b58d Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 3 Feb 2020 22:30:17 +0000 Subject: [PATCH 0863/1253] Remove Copy impl from OnceWith Iterators typically don't implement `Copy` and this shouldn't be an exception. --- src/libcore/iter/sources.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 5a31acab273f1..a1d4e1b31e9b1 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -398,7 +398,7 @@ pub fn once(value: T) -> Once { /// See its documentation for more. /// /// [`once_with`]: fn.once_with.html -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] #[stable(feature = "iter_once_with", since = "1.43.0")] pub struct OnceWith { gen: Option, From 697ef95c9f22376232e5dd60ab429fe4a31b6332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 4 Feb 2020 01:05:45 +0100 Subject: [PATCH 0864/1253] remove redundant imports (clippy::single_component_path_imports) --- src/librustc/traits/mod.rs | 1 - src/librustc/traits/structural_impls.rs | 1 - src/librustc/ty/mod.rs | 1 - src/librustc_builtin_macros/log_syntax.rs | 1 - src/librustc_interface/callbacks.rs | 1 - src/librustc_interface/passes.rs | 4 ---- src/librustc_macros/src/lift.rs | 2 -- src/librustc_macros/src/query.rs | 1 - src/librustc_macros/src/symbols.rs | 1 - src/librustc_macros/src/type_foldable.rs | 2 -- src/librustc_passes/dead.rs | 1 - src/librustc_session/config.rs | 4 ---- src/librustc_session/options.rs | 2 -- src/librustc_session/session.rs | 1 - src/librustc_typeck/variance/mod.rs | 1 - src/librustdoc/clean/utils.rs | 1 - src/librustdoc/config.rs | 2 -- src/librustdoc/core.rs | 1 - src/librustdoc/html/render.rs | 2 -- src/librustdoc/markdown.rs | 1 - src/librustdoc/passes/collect_intra_doc_links.rs | 1 - src/librustdoc/test.rs | 1 - src/libtest/cli.rs | 1 - src/libtest/console.rs | 2 -- 24 files changed, 36 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index daaba95cf6b13..b1b3d44044ebc 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -31,7 +31,6 @@ use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, SubstsRef}; use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness}; use crate::util::common::ErrorReported; -use chalk_engine; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 58204a460d7df..1db83c5bafac9 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -2,7 +2,6 @@ use crate::traits; use crate::traits::project::Normalized; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::{self, Lift, Ty, TyCtxt}; -use chalk_engine; use rustc_span::symbol::Symbol; use smallvec::SmallVec; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..ea29a718b23a3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -46,7 +46,6 @@ use rustc_target::abi::Align; use syntax::ast::{self, Constness, Ident, Name}; use syntax::node_id::{NodeId, NodeMap, NodeSet}; -use smallvec; use std::cell::RefCell; use std::cmp::{self, Ordering}; use std::fmt; diff --git a/src/librustc_builtin_macros/log_syntax.rs b/src/librustc_builtin_macros/log_syntax.rs index 6d9bfbfd05f0a..ac7ba49ba185d 100644 --- a/src/librustc_builtin_macros/log_syntax.rs +++ b/src/librustc_builtin_macros/log_syntax.rs @@ -1,6 +1,5 @@ use rustc_ast_pretty::pprust; use rustc_expand::base; -use rustc_span; use syntax::tokenstream::TokenStream; pub fn expand_log_syntax<'cx>( diff --git a/src/librustc_interface/callbacks.rs b/src/librustc_interface/callbacks.rs index eb9c118bb0100..803e895857202 100644 --- a/src/librustc_interface/callbacks.rs +++ b/src/librustc_interface/callbacks.rs @@ -11,7 +11,6 @@ use rustc::ty::tls; use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS}; -use rustc_span; use std::fmt; /// This is a callback from libsyntax as it cannot access the implicit state diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 0be73e55e9c1d..bf8bcd71efa41 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -17,7 +17,6 @@ use rustc::traits; use rustc::ty::steal::Steal; use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc::util::common::ErrorReported; -use rustc_builtin_macros; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; @@ -26,18 +25,15 @@ use rustc_data_structures::{box_region_allow_access, declare_box_region_type, pa use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_incremental; use rustc_lint::LintStore; use rustc_mir as mir; use rustc_mir_build as mir_build; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; -use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_span::symbol::Symbol; use rustc_span::FileName; -use rustc_traits; use rustc_typeck as typeck; use syntax::mut_visit::MutVisitor; use syntax::{self, ast, visit}; diff --git a/src/librustc_macros/src/lift.rs b/src/librustc_macros/src/lift.rs index 1b91fc5018a23..a246b34b2c295 100644 --- a/src/librustc_macros/src/lift.rs +++ b/src/librustc_macros/src/lift.rs @@ -1,7 +1,5 @@ -use proc_macro2; use quote::quote; use syn::{self, parse_quote}; -use synstructure; pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { s.add_bounds(synstructure::AddBounds::Generics); diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index f680b0d64cded..6dc4f7f251595 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -2,7 +2,6 @@ use itertools::Itertools; use proc_macro::TokenStream; use proc_macro2::{Delimiter, TokenTree}; use quote::quote; -use syn; use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; diff --git a/src/librustc_macros/src/symbols.rs b/src/librustc_macros/src/symbols.rs index c692c7f399541..feddcd5f99429 100644 --- a/src/librustc_macros/src/symbols.rs +++ b/src/librustc_macros/src/symbols.rs @@ -1,7 +1,6 @@ use proc_macro::TokenStream; use quote::quote; use std::collections::HashSet; -use syn; use syn::parse::{Parse, ParseStream, Result}; use syn::{braced, parse_macro_input, Ident, LitStr, Token}; diff --git a/src/librustc_macros/src/type_foldable.rs b/src/librustc_macros/src/type_foldable.rs index 3d58984a9009b..687401e33449b 100644 --- a/src/librustc_macros/src/type_foldable.rs +++ b/src/librustc_macros/src/type_foldable.rs @@ -1,6 +1,4 @@ use quote::quote; -use syn; -use synstructure; pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 2ff9d744f2c4d..9367909d10c30 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -15,7 +15,6 @@ use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{Node, PatKind, TyKind}; use rustc_session::lint; -use rustc_span; use rustc_span::symbol::sym; use syntax::{ast, attr}; diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 813d14d616d42..ad1a6c4906ea3 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -22,8 +22,6 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags}; -use getopts; - use std::collections::btree_map::{ Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter, }; @@ -816,7 +814,6 @@ mod opt { #![allow(dead_code)] use super::RustcOptGroup; - use getopts; pub type R = RustcOptGroup; pub type S = &'static str; @@ -1862,7 +1859,6 @@ pub fn parse_crate_types_from_list(list_list: Vec) -> Result bool { diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index be0e668a467b2..d6b71641da52f 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -11,8 +11,6 @@ use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; -use getopts; - use std::collections::BTreeMap; use std::collections::hash_map::DefaultHasher; diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index a40d6451b958c..f8cba58f9d904 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -33,7 +33,6 @@ use rustc_data_structures::jobserver::{self, Client}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple}; -use std; use std::cell::{self, RefCell}; use std::env; use std::fmt; diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 27dc03bbbe206..32bd7e4c4c1d0 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -3,7 +3,6 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html -use arena; use hir::Node; use rustc::ty::query::Providers; use rustc::ty::{self, CrateVariancesMap, TyCtxt}; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index e110545c6f27b..356660763a755 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -16,7 +16,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_span; use rustc_span::symbol::{kw, sym, Symbol}; use std::mem; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 22f5d0dc2c078..1b776930d7a78 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -3,7 +3,6 @@ use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; -use getopts; use rustc::lint::Level; use rustc::session; use rustc::session::config::{ @@ -13,7 +12,6 @@ use rustc::session::config::{ use rustc::session::config::{parse_crate_types_from_list, parse_externs, CrateType}; use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; use rustc::session::search_paths::SearchPath; -use rustc_driver; use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_target::spec::TargetTriple; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index a8baa89c6f181..429988db9d843 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,7 +11,6 @@ use rustc_hir::def::Namespace::TypeNS; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use rustc_hir::HirId; use rustc_interface::interface; -use rustc_lint; use rustc_resolve as resolve; use rustc_session::lint; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c670641394267..e2a0126a8fabb 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -73,8 +73,6 @@ use crate::html::markdown::{self, ErrorCodes, IdMap, Markdown, MarkdownHtml, Mar use crate::html::sources; use crate::html::{highlight, layout, static_files}; -use minifier; - #[cfg(test)] mod tests; diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 912a40722b8af..a37efc22c9305 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -5,7 +5,6 @@ use std::path::PathBuf; use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; use rustc_span::source_map::DUMMY_SP; -use testing; use crate::config::{Options, RenderOptions}; use crate::externalfiles::{load_string, LoadStringError}; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 50d5f70f4889a..332d19fbfaeca 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId; use rustc_resolve::ParentScope; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; -use syntax; use syntax::ast::{self, Ident}; use std::ops::Range; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 936f63975a58e..2892c4b153790 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -20,7 +20,6 @@ use std::str; use syntax::ast; use syntax::with_globals; use tempfile::Builder as TempFileBuilder; -use testing; use crate::clean::Attributes; use crate::config::Options; diff --git a/src/libtest/cli.rs b/src/libtest/cli.rs index edff8bea0f3d0..778600b2196b7 100644 --- a/src/libtest/cli.rs +++ b/src/libtest/cli.rs @@ -1,6 +1,5 @@ //! Module converting command-line arguments into test configuration. -use getopts; use std::env; use std::path::PathBuf; diff --git a/src/libtest/console.rs b/src/libtest/console.rs index ebdfb16294759..149c9202e6e2d 100644 --- a/src/libtest/console.rs +++ b/src/libtest/console.rs @@ -4,8 +4,6 @@ use std::fs::File; use std::io; use std::io::prelude::Write; -use term; - use super::{ bench::fmt_bench_samples, cli::TestOpts, From ae51d2ba32a3dfa3811ee19164ef789eb734a38b Mon Sep 17 00:00:00 2001 From: Victor Ding Date: Wed, 29 Jan 2020 00:16:14 +1100 Subject: [PATCH 0865/1253] Split `join_codegen_and_link()` into two steps `join_codegen_and_link()` is split to `join_codegen()` and `link()`. --- src/librustc_codegen_llvm/lib.rs | 29 ++++++++++--------- src/librustc_codegen_utils/codegen_backend.rs | 13 ++++++++- src/librustc_interface/queries.rs | 23 ++++++++------- .../hotplug_codegen_backend/the_backend.rs | 18 +++++++++--- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 70e3874035b60..5de31a875c332 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -29,7 +29,7 @@ use rustc::dep_graph::WorkProduct; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::CompiledModule; +use rustc_codegen_ssa::{CodegenResults, CompiledModule}; use rustc_errors::{FatalError, Handler}; use std::any::Any; use std::ffi::CStr; @@ -39,7 +39,7 @@ use syntax::expand::allocator::AllocatorKind; use rustc::dep_graph::DepGraph; use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; -use rustc::session::config::{OptLevel, OutputFilenames, OutputType, PrintRequest}; +use rustc::session::config::{OptLevel, OutputFilenames, PrintRequest}; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; @@ -270,13 +270,12 @@ impl CodegenBackend for LlvmCodegenBackend { ) } - fn join_codegen_and_link( + fn join_codegen( &self, ongoing_codegen: Box, sess: &Session, dep_graph: &DepGraph, - outputs: &OutputFilenames, - ) -> Result<(), ErrorReported> { + ) -> Result, ErrorReported> { let (codegen_results, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") @@ -291,14 +290,18 @@ impl CodegenBackend for LlvmCodegenBackend { sess.compile_status()?; - if !sess - .opts - .output_types - .keys() - .any(|&i| i == OutputType::Exe || i == OutputType::Metadata) - { - return Ok(()); - } + Ok(Box::new(codegen_results)) + } + + fn link( + &self, + sess: &Session, + codegen_results: Box, + outputs: &OutputFilenames, + ) -> Result<(), ErrorReported> { + let codegen_results = codegen_results + .downcast::() + .expect("Expected CodegenResults, found Box"); if sess.opts.debugging_opts.no_link { // FIXME: use a binary format to encode the `.rlink` file diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index fecb3986e7e08..96166e04c2e3c 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -43,11 +43,22 @@ pub trait CodegenBackend { /// # Panics /// /// Panics when the passed `Box` was not returned by `codegen_backend`. - fn join_codegen_and_link( + fn join_codegen( &self, ongoing_codegen: Box, sess: &Session, dep_graph: &DepGraph, + ) -> Result, ErrorReported>; + + /// This is called on the returned `Box` from `join_codegen` + /// + /// # Panics + /// + /// Panics when the passed `Box` was not returned by `join_codegen`. + fn link( + &self, + sess: &Session, + codegen_results: Box, outputs: &OutputFilenames, ) -> Result<(), ErrorReported>; } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 0af9b17a2995b..2ac2845be91b3 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -310,19 +310,22 @@ pub struct Linker { impl Linker { pub fn link(self) -> Result<()> { - let r = self - .codegen_backend - .join_codegen_and_link( - self.ongoing_codegen, - &self.sess, - &self.dep_graph, - &self.prepare_outputs, - ) - .map_err(|_| ErrorReported); + let codegen_results = + self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?; let prof = self.sess.prof.clone(); let dep_graph = self.dep_graph; prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph)); - r + + if !self + .sess + .opts + .output_types + .keys() + .any(|&i| i == OutputType::Exe || i == OutputType::Metadata) + { + return Ok(()); + } + self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs) } } diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 84bcd220ae766..07ef2424cc880 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -71,18 +71,28 @@ impl CodegenBackend for TheBackend { Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) } - fn join_codegen_and_link( + fn join_codegen( &self, ongoing_codegen: Box, - sess: &Session, + _sess: &Session, _dep_graph: &DepGraph, + ) -> Result, ErrorReported> { + let crate_name = ongoing_codegen.downcast::() + .expect("in join_codegen: ongoing_codegen is not a Symbol"); + Ok(crate_name) + } + + fn link( + &self, + sess: &Session, + codegen_results: Box, outputs: &OutputFilenames, ) -> Result<(), ErrorReported> { use std::io::Write; use rustc::session::config::CrateType; use rustc_codegen_utils::link::out_filename; - let crate_name = ongoing_codegen.downcast::() - .expect("in join_codegen_and_link: ongoing_codegen is not a Symbol"); + let crate_name = codegen_results.downcast::() + .expect("in link: codegen_results is not a Symbol"); for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { sess.fatal(&format!("Crate type is {:?}", crate_type)); From fe1314dbc42da3331062c9348f7117b3585ad6bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 4 Feb 2020 02:28:11 +0100 Subject: [PATCH 0866/1253] fix couple of perf related clipyp warnings librustc: don't clone a type that is copy librustc_incremental: use faster vector initialization librustc_typeck: don't clone a type that is copy librustdoc: don't create a vector where a slice will do --- src/librustc/ty/mod.rs | 2 +- src/librustc_incremental/persist/file_format.rs | 3 +-- src/librustc_typeck/astconv.rs | 6 ++---- src/librustdoc/html/render.rs | 9 +-------- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..9cfd64d638234 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1344,7 +1344,7 @@ pub trait ToPredicate<'tcx> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(&self) -> Predicate<'tcx> { ty::Predicate::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value }), self.constness, ) } diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs index 7534b7e9ef429..5c72b049d97e9 100644 --- a/src/librustc_incremental/persist/file_format.rs +++ b/src/librustc_incremental/persist/file_format.rs @@ -90,8 +90,7 @@ pub fn read_file( let mut rustc_version_str_len = [0u8; 1]; file.read_exact(&mut rustc_version_str_len)?; let rustc_version_str_len = rustc_version_str_len[0] as usize; - let mut buffer = Vec::with_capacity(rustc_version_str_len); - buffer.resize(rustc_version_str_len, 0); + let mut buffer = vec![0; rustc_version_str_len]; file.read_exact(&mut buffer)?; if buffer != rustc_version().as_bytes() { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c2123876b679b..231aed48fb6be 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1438,10 +1438,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Expand trait aliases recursively and check that only one regular (non-auto) trait // is used and no 'maybe' bounds are used. - let expanded_traits = traits::expand_trait_aliases( - tcx, - bounds.trait_bounds.iter().map(|&(a, b, _)| (a.clone(), b)), - ); + let expanded_traits = + traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b))); let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); if regular_traits.len() > 1 { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c670641394267..a16f7248baac7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3629,14 +3629,7 @@ fn render_impl( for it in &i.inner_impl().items { if let clean::TypedefItem(ref tydef, _) = it.inner { write!(w, " "); - assoc_type( - w, - it, - &vec![], - Some(&tydef.type_), - AssocItemLink::Anchor(None), - "", - ); + assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), ""); write!(w, ";"); } } From 0f73133be6a6915e2d5836ce9986eaffc1b2954d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Feb 2020 17:58:28 -0800 Subject: [PATCH 0867/1253] Suggest `split_at_mut` on multiple mutable index access --- .../diagnostics/conflict_errors.rs | 27 +++++++++++++++++-- .../ui/suggestions/suggest-split-at-mut.rs | 8 ++++++ .../suggestions/suggest-split-at-mut.stderr | 15 +++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-split-at-mut.rs create mode 100644 src/test/ui/suggestions/suggest-split-at-mut.stderr diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index a8e534a9f650c..67254cd0c4842 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -395,14 +395,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => { first_borrow_desc = "first "; - self.cannot_mutably_borrow_multiply( + let mut err = self.cannot_mutably_borrow_multiply( span, &desc_place, &msg_place, issued_span, &msg_borrow, None, - ) + ); + self.suggest_split_at_mut_if_applicable( + &mut err, + &place, + &issued_borrow.borrowed_place, + ); + err } (BorrowKind::Unique, BorrowKind::Unique) => { @@ -547,6 +553,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err } + fn suggest_split_at_mut_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + place: &Place<'tcx>, + borrowed_place: &Place<'tcx>, + ) { + match (&place.projection[..], &borrowed_place.projection[..]) { + ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) => { + err.help( + "consider using `.split_at_mut(position)` or similar method to obtain \ + two mutable non-overlapping sub-slices", + ); + } + _ => {} + } + } + /// Returns the description of the root place for a conflicting borrow and the full /// descriptions of the places that caused the conflict. /// diff --git a/src/test/ui/suggestions/suggest-split-at-mut.rs b/src/test/ui/suggestions/suggest-split-at-mut.rs new file mode 100644 index 0000000000000..d294c20b8240e --- /dev/null +++ b/src/test/ui/suggestions/suggest-split-at-mut.rs @@ -0,0 +1,8 @@ +fn main() { + let mut foo = [1, 2, 3, 4]; + let a = &mut foo[2]; + let b = &mut foo[3]; //~ ERROR cannot borrow `foo[_]` as mutable more than once at a time + *a = 5; + *b = 6; + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/suggestions/suggest-split-at-mut.stderr b/src/test/ui/suggestions/suggest-split-at-mut.stderr new file mode 100644 index 0000000000000..330f012b2a9be --- /dev/null +++ b/src/test/ui/suggestions/suggest-split-at-mut.stderr @@ -0,0 +1,15 @@ +error[E0499]: cannot borrow `foo[_]` as mutable more than once at a time + --> $DIR/suggest-split-at-mut.rs:4:13 + | +LL | let a = &mut foo[2]; + | ----------- first mutable borrow occurs here +LL | let b = &mut foo[3]; + | ^^^^^^^^^^^ second mutable borrow occurs here +LL | *a = 5; + | ------ first borrow later used here + | + = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. From 109d5c189f4b5c3405a7d6cfb312e04d866c0c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Feb 2020 16:08:45 -0800 Subject: [PATCH 0868/1253] Tweak borrow error on `FnMut` when `Fn` is expected --- .../diagnostics/mutability_errors.rs | 102 +++++++++++++- .../borrow-immutable-upvar-mutation.rs | 21 ++- .../borrow-immutable-upvar-mutation.stderr | 123 ++++++++++------- .../borrow-raw-address-of-mutability.stderr | 32 ++--- src/test/ui/borrowck/mutability-errors.stderr | 128 +++++++++--------- src/test/ui/fn/fn-closure-mutable-capture.rs | 4 +- .../ui/fn/fn-closure-mutable-capture.stderr | 13 +- src/test/ui/issues/issue-21600.stderr | 33 +++-- src/test/ui/nll/closure-captures.stderr | 120 ++++++++-------- .../unboxed-closures-mutate-upvar.stderr | 16 +-- ...sures-mutated-upvar-from-fn-closure.stderr | 16 +-- 11 files changed, 370 insertions(+), 238 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 563ff1112c3a6..4fc31b3a41262 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -10,7 +10,7 @@ use rustc_span::Span; use crate::borrow_check::diagnostics::BorrowedContentSource; use crate::borrow_check::MirBorrowckCtxt; use crate::util::collect_writes::FindAssignments; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, DiagnosticBuilder}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum AccessKind { @@ -412,11 +412,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { projection: [ProjectionElem::Deref], // FIXME document what is this 1 magic number about } if local == Local::new(1) && !self.upvars.is_empty() => { - err.span_label(span, format!("cannot {ACT}", ACT = act)); - err.span_help( - self.body.span, - "consider changing this to accept closures that implement `FnMut`", - ); + self.expected_fn_found_fn_mut_call(&mut err, span, act); } PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => { @@ -448,6 +444,100 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.buffer(&mut self.errors_buffer); } + + /// Targetted error when encountering an `FnMut` closure where an `Fn` closure was expected. + fn expected_fn_found_fn_mut_call(&self, err: &mut DiagnosticBuilder<'_>, sp: Span, act: &str) { + err.span_label(sp, format!("cannot {ACT}", ACT = act)); + + let hir = self.infcx.tcx.hir(); + let closure_id = hir.as_local_hir_id(self.mir_def_id).unwrap(); + let fn_call_id = hir.get_parent_node(closure_id); + let node = hir.get(fn_call_id); + let item_id = hir.get_parent_item(fn_call_id); + let mut look_at_return = true; + // If we can detect the expression to be an `fn` call where the closure was an argument, + // we point at the `fn` definition argument... + match node { + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) => { + let arg_pos = args + .iter() + .enumerate() + .filter(|(_, arg)| arg.span == self.body.span) + .map(|(pos, _)| pos) + .next(); + let def_id = hir.local_def_id(item_id); + let tables = self.infcx.tcx.typeck_tables_of(def_id); + if let Some(ty::FnDef(def_id, _)) = + tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind) + { + let arg = match hir.get_if_local(*def_id) { + Some(hir::Node::Item(hir::Item { + ident, + kind: hir::ItemKind::Fn(sig, ..), + .. + })) + | Some(hir::Node::TraitItem(hir::TraitItem { + ident, + kind: hir::TraitItemKind::Method(sig, _), + .. + })) + | Some(hir::Node::ImplItem(hir::ImplItem { + ident, + kind: hir::ImplItemKind::Method(sig, _), + .. + })) => Some( + arg_pos + .and_then(|pos| { + sig.decl.inputs.get( + pos + if sig.decl.implicit_self.has_implicit_self() { + 1 + } else { + 0 + }, + ) + }) + .map(|arg| arg.span) + .unwrap_or(ident.span), + ), + _ => None, + }; + if let Some(span) = arg { + err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); + err.span_label(func.span, "expects `Fn` instead of `FnMut`"); + if self.infcx.tcx.sess.source_map().is_multiline(self.body.span) { + err.span_label(self.body.span, "in this closure"); + } + look_at_return = false; + } + } + } + _ => {} + } + if look_at_return && hir.get_return_block(closure_id).is_some() { + // ...otherwise we are probably in the tail expression of the function, point at the + // return type. + match hir.get(hir.get_parent_item(fn_call_id)) { + hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. }) + | hir::Node::TraitItem(hir::TraitItem { + ident, + kind: hir::TraitItemKind::Method(sig, _), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + ident, + kind: hir::ImplItemKind::Method(sig, _), + .. + }) => { + err.span_label(ident.span, "you might have to change this..."); + err.span_label(sig.decl.output.span(), "...to return `FnMut` instead of `Fn`"); + err.span_label(self.body.span, "in this closure"); + } + parent => { + err.note(&format!("parent {:?}", parent)); + } + } + } + } } fn suggest_ampmut_self<'tcx>( diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs index fed8bc95b6b86..62e27bcf1643f 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs @@ -18,7 +18,10 @@ fn main() { let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow let mut z = 0; - let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); //~ ERROR cannot assign + let _h = to_fn_mut(|| { + set(&mut z); + to_fn(|| z = 42); //~ ERROR cannot assign + }); } // By-value captures @@ -33,3 +36,19 @@ fn main() { let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign } } + +fn foo() -> Box usize> { + let mut x = 0; + Box::new(move || { + x += 1; //~ ERROR cannot assign + x + }) +} + +fn bar() -> impl Fn() -> usize { + let mut x = 0; + move || { + x += 1; //~ ERROR cannot assign + x + } +} diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr index 097e4c75065c9..a97d694685d76 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr @@ -1,76 +1,101 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:15:27 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _f = to_fn(|| x = 42); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:15:24 - | -LL | let _f = to_fn(|| x = 42); - | ^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:18:31 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _g = to_fn(|| set(&mut y)); - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:18:24 - | -LL | let _g = to_fn(|| set(&mut y)); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:21:55 - | -LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:21:52 - | -LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); - | ^^^^^^^^^ + --> $DIR/borrow-immutable-upvar-mutation.rs:23:22 + | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... +LL | to_fn(|| z = 42); + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:27:32 - | -LL | let _f = to_fn(move || x = 42); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:27:24 + --> $DIR/borrow-immutable-upvar-mutation.rs:30:32 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _f = to_fn(move || x = 42); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:30:36 - | -LL | let _g = to_fn(move || set(&mut y)); - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:30:24 + --> $DIR/borrow-immutable-upvar-mutation.rs:33:36 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _g = to_fn(move || set(&mut y)); - | ^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:33:65 + --> $DIR/borrow-immutable-upvar-mutation.rs:36:65 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:33:57 - | -LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` + +error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure + --> $DIR/borrow-immutable-upvar-mutation.rs:43:9 + | +LL | fn foo() -> Box usize> { + | --- ---------------------- ...to return `FnMut` instead of `Fn` + | | + | you might have to change this... +LL | let mut x = 0; +LL | Box::new(move || { + | ______________- +LL | | x += 1; + | | ^^^^^^ cannot assign +LL | | x +LL | | }) + | |_____- in this closure + +error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure + --> $DIR/borrow-immutable-upvar-mutation.rs:51:9 + | +LL | fn bar() -> impl Fn() -> usize { + | --- ------------------ ...to return `FnMut` instead of `Fn` + | | + | you might have to change this... +LL | let mut x = 0; +LL | / move || { +LL | | x += 1; + | | ^^^^^^ cannot assign +LL | | x +LL | | } + | |_____- in this closure -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0594, E0596. For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr index cf01c362d50bc..44dde0fd80b0d 100644 --- a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr +++ b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr @@ -27,32 +27,32 @@ LL | f(); error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-raw-address-of-mutability.rs:29:17 | -LL | let y = &raw mut x; - | ^^^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-raw-address-of-mutability.rs:28:21 - | +LL | fn make_fn(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let f = make_fn(|| { - | _____________________^ + | _____________-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | let y = &raw mut x; + | | ^^^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-raw-address-of-mutability.rs:37:17 | -LL | let y = &raw mut x; - | ^^^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-raw-address-of-mutability.rs:36:21 - | +LL | fn make_fn(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let f = make_fn(move || { - | _____________________^ + | _____________-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | let y = &raw mut x; + | | ^^^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 5 previous errors diff --git a/src/test/ui/borrowck/mutability-errors.stderr b/src/test/ui/borrowck/mutability-errors.stderr index 72547a40352c9..5361ebe3916d7 100644 --- a/src/test/ui/borrowck/mutability-errors.stderr +++ b/src/test/ui/borrowck/mutability-errors.stderr @@ -119,146 +119,146 @@ LL | &mut (*f()).0; error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:40:9 | -LL | x = (1,); - | ^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); + | | ^^^^^^^^ cannot assign LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:41:9 | -LL | x.0 = 1; - | ^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; + | | ^^^^^^^ cannot assign LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:42:9 | -LL | &mut x; - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; + | | ^^^^^^ cannot borrow as mutable LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:43:9 | -LL | &mut x.0; - | ^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; + | | ^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:46:9 | -LL | x = (1,); - | ^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); + | | ^^^^^^^^ cannot assign LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:47:9 | -LL | x.0 = 1; - | ^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; + | | ^^^^^^^ cannot assign LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:48:9 | -LL | &mut x; - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; + | | ^^^^^^ cannot borrow as mutable LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:49:9 | -LL | &mut x.0; - | ^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; + | | ^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/mutability-errors.rs:54:5 diff --git a/src/test/ui/fn/fn-closure-mutable-capture.rs b/src/test/ui/fn/fn-closure-mutable-capture.rs index 81376af091b45..0e427b9cf318f 100644 --- a/src/test/ui/fn/fn-closure-mutable-capture.rs +++ b/src/test/ui/fn/fn-closure-mutable-capture.rs @@ -1,11 +1,11 @@ -pub fn bar(_f: F) {} +pub fn bar(_f: F) {} //~ NOTE change this to accept `FnMut` instead of `Fn` pub fn foo() { let mut x = 0; bar(move || x = 1); //~^ ERROR cannot assign to `x`, as it is a captured variable in a `Fn` closure //~| NOTE cannot assign - //~| HELP consider changing this to accept closures that implement `FnMut` + //~| NOTE expects `Fn` instead of `FnMut` } fn main() {} diff --git a/src/test/ui/fn/fn-closure-mutable-capture.stderr b/src/test/ui/fn/fn-closure-mutable-capture.stderr index f7ab56da8de97..d23c363ae1582 100644 --- a/src/test/ui/fn/fn-closure-mutable-capture.stderr +++ b/src/test/ui/fn/fn-closure-mutable-capture.stderr @@ -1,14 +1,13 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/fn-closure-mutable-capture.rs:5:17 | +LL | pub fn bar(_f: F) {} + | - change this to accept `FnMut` instead of `Fn` +... LL | bar(move || x = 1); - | ^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/fn-closure-mutable-capture.rs:5:9 - | -LL | bar(move || x = 1); - | ^^^^^^^^^^^^^ + | --- ^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21600.stderr b/src/test/ui/issues/issue-21600.stderr index 9c534809dbee3..84c7106e89016 100644 --- a/src/test/ui/issues/issue-21600.stderr +++ b/src/test/ui/issues/issue-21600.stderr @@ -1,34 +1,33 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/issue-21600.rs:14:20 | +LL | fn call_it(f: F) where F: Fn() { f(); } + | - change this to accept `FnMut` instead of `Fn` +... LL | call_it(|| x.gen_mut()); - | ^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/issue-21600.rs:14:17 - | -LL | call_it(|| x.gen_mut()); - | ^^^^^^^^^^^^^^ + | ------- ^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/issue-21600.rs:14:17 | -LL | call_it(|| x.gen_mut()); - | ^^ - mutable borrow occurs due to use of `x` in closure - | | - | cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/issue-21600.rs:12:13 - | +LL | fn call_it(f: F) where F: Fn() { f(); } + | - change this to accept `FnMut` instead of `Fn` +... LL | call_it(|| { - | _____________^ + | _____-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | call_it(|| x.gen()); LL | | call_it(|| x.gen_mut()); + | | ^^ - mutable borrow occurs due to use of `x` in closure + | | | + | | cannot borrow as mutable LL | | LL | | LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-captures.stderr b/src/test/ui/nll/closure-captures.stderr index b8f5cc86500c5..dd5f32ef4f581 100644 --- a/src/test/ui/nll/closure-captures.stderr +++ b/src/test/ui/nll/closure-captures.stderr @@ -37,36 +37,36 @@ LL | x = 1; error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:27:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;} - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:26:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;} - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:31:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:30:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;}); - | |___________^ + | |_____-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:39:10 @@ -80,19 +80,19 @@ LL | x = 1;} error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:38:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;} - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:37:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;} - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:43:5 @@ -106,53 +106,53 @@ LL | x = 1;}); error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:42:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:41:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;}); - | |___________^ + | |_____-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:48:9 | -LL | || - | ^^ cannot borrow as mutable -LL | *x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:47:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:51:9 | -LL | || - | ^^ cannot borrow as mutable -LL | *x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:50:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error: aborting due to 12 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr index 6bba38510b676..48ec620d92ea7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr @@ -28,17 +28,17 @@ LL | n += 1; error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutate-upvar.rs:53:9 | -LL | n += 1; - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/unboxed-closures-mutate-upvar.rs:52:23 - | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let mut f = to_fn(move || { - | _______________________^ + | _________________-----_- + | | | + | | expects `Fn` instead of `FnMut` LL | | n += 1; + | | ^^^^^^ cannot assign LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 4 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr index a38c612e1dea9..80e84fb7cad3f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr @@ -1,18 +1,18 @@ error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutated-upvar-from-fn-closure.rs:11:9 | -LL | counter += 1; - | ^^^^^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/unboxed-closures-mutated-upvar-from-fn-closure.rs:10:10 - | +LL | fn call(f: F) where F : Fn() { + | - change this to accept `FnMut` instead of `Fn` +... LL | call(|| { - | __________^ + | _____----_- + | | | + | | expects `Fn` instead of `FnMut` LL | | counter += 1; + | | ^^^^^^^^^^^^ cannot assign LL | | LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to previous error From e5901641755dfd2e758c7e855b82ee0bcd8b29c0 Mon Sep 17 00:00:00 2001 From: msizanoen1 Date: Tue, 21 Jan 2020 21:52:19 +0700 Subject: [PATCH 0869/1253] Implement proper C ABI lowering for RISC-V --- src/librustc/ty/layout.rs | 1 + src/librustc_target/abi/call/mod.rs | 10 +- src/librustc_target/abi/call/riscv.rs | 335 +++++++++++++++++++++++++- 3 files changed, 331 insertions(+), 15 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index bda42db40b0ae..c70473b667ea9 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2650,6 +2650,7 @@ where .map(|(i, ty)| arg_of(ty, Some(i))) .collect(), c_variadic: sig.c_variadic, + fixed_count: inputs.len(), conv, }; fn_abi.adjust_for_abi(cx, sig.abi); diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index af82f9e318371..175eb93e4e55f 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -120,6 +120,7 @@ impl Reg { reg_ctor!(i16, Integer, 16); reg_ctor!(i32, Integer, 32); reg_ctor!(i64, Integer, 64); + reg_ctor!(i128, Integer, 128); reg_ctor!(f32, Float, 32); reg_ctor!(f64, Float, 64); @@ -493,6 +494,12 @@ pub struct FnAbi<'a, Ty> { pub c_variadic: bool, + /// The count of non-variadic arguments. + /// + /// Should only be different from args.len() when c_variadic is true. + /// This can be used to know wether an argument is variadic or not. + pub fixed_count: usize, + pub conv: Conv, } @@ -534,8 +541,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "nvptx" => nvptx::compute_abi_info(self), "nvptx64" => nvptx64::compute_abi_info(self), "hexagon" => hexagon::compute_abi_info(self), - "riscv32" => riscv::compute_abi_info(self, 32), - "riscv64" => riscv::compute_abi_info(self, 64), + "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" if cx.target_spec().target_os != "emscripten" => { wasm32_bindgen_compat::compute_abi_info(self) } diff --git a/src/librustc_target/abi/call/riscv.rs b/src/librustc_target/abi/call/riscv.rs index 095e5aff74422..11d6c4d819107 100644 --- a/src/librustc_target/abi/call/riscv.rs +++ b/src/librustc_target/abi/call/riscv.rs @@ -1,49 +1,358 @@ // Reference: RISC-V ELF psABI specification // https://github.com/riscv/riscv-elf-psabi-doc +// +// Reference: Clang RISC-V ELF psABI lowering code +// https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773 -use crate::abi::call::{ArgAbi, FnAbi}; +use crate::abi::call::{ArgAbi, ArgAttribute, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform}; +use crate::abi::{ + self, Abi, FieldPlacement, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods, +}; +use crate::spec::HasTargetSpec; + +#[derive(Copy, Clone)] +enum RegPassKind { + Float(Reg), + Integer(Reg), + Unknown, +} + +#[derive(Copy, Clone)] +enum FloatConv { + FloatPair(Reg, Reg), + Float(Reg), + MixedPair(Reg, Reg), +} + +#[derive(Copy, Clone)] +struct CannotUseFpConv; + +fn is_riscv_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool { + match arg.layout.abi { + Abi::Vector { .. } => true, + _ => arg.layout.is_aggregate(), + } +} + +fn should_use_fp_conv_helper<'a, Ty, C>( + cx: &C, + arg_layout: &TyLayout<'a, Ty>, + xlen: u64, + flen: u64, + field1_kind: &mut RegPassKind, + field2_kind: &mut RegPassKind, +) -> Result<(), CannotUseFpConv> +where + Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf>, +{ + match arg_layout.abi { + Abi::Scalar(ref scalar) => match scalar.value { + abi::Int(..) | abi::Pointer => { + if arg_layout.size.bits() > xlen { + return Err(CannotUseFpConv); + } + match (*field1_kind, *field2_kind) { + (RegPassKind::Unknown, _) => { + *field1_kind = RegPassKind::Integer(Reg { + kind: RegKind::Integer, + size: arg_layout.size, + }); + } + (RegPassKind::Float(_), RegPassKind::Unknown) => { + *field2_kind = RegPassKind::Integer(Reg { + kind: RegKind::Integer, + size: arg_layout.size, + }); + } + _ => return Err(CannotUseFpConv), + } + } + abi::F32 | abi::F64 => { + if arg_layout.size.bits() > flen { + return Err(CannotUseFpConv); + } + match (*field1_kind, *field2_kind) { + (RegPassKind::Unknown, _) => { + *field1_kind = + RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size }); + } + (_, RegPassKind::Unknown) => { + *field2_kind = + RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size }); + } + _ => return Err(CannotUseFpConv), + } + } + }, + Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv), + Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields { + FieldPlacement::Union(_) => { + if !arg_layout.is_zst() { + return Err(CannotUseFpConv); + } + } + FieldPlacement::Array { count, .. } => { + for _ in 0..count { + let elem_layout = arg_layout.field(cx, 0); + should_use_fp_conv_helper( + cx, + &elem_layout, + xlen, + flen, + field1_kind, + field2_kind, + )?; + } + } + FieldPlacement::Arbitrary { .. } => { + match arg_layout.variants { + abi::Variants::Multiple { .. } => return Err(CannotUseFpConv), + abi::Variants::Single { .. } => (), + } + for i in arg_layout.fields.index_by_increasing_offset() { + let field = arg_layout.field(cx, i); + should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?; + } + } + }, + } + Ok(()) +} + +fn should_use_fp_conv<'a, Ty, C>( + cx: &C, + arg: &TyLayout<'a, Ty>, + xlen: u64, + flen: u64, +) -> Option +where + Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf>, +{ + let mut field1_kind = RegPassKind::Unknown; + let mut field2_kind = RegPassKind::Unknown; + if should_use_fp_conv_helper(cx, arg, xlen, flen, &mut field1_kind, &mut field2_kind).is_err() { + return None; + } + match (field1_kind, field2_kind) { + (RegPassKind::Integer(l), RegPassKind::Float(r)) => Some(FloatConv::MixedPair(l, r)), + (RegPassKind::Float(l), RegPassKind::Integer(r)) => Some(FloatConv::MixedPair(l, r)), + (RegPassKind::Float(l), RegPassKind::Float(r)) => Some(FloatConv::FloatPair(l, r)), + (RegPassKind::Float(f), RegPassKind::Unknown) => Some(FloatConv::Float(f)), + _ => None, + } +} + +fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool +where + Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf>, +{ + if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) { + match conv { + FloatConv::Float(f) => { + arg.cast_to(f); + } + FloatConv::FloatPair(l, r) => { + arg.cast_to(CastTarget::pair(l, r)); + } + FloatConv::MixedPair(l, r) => { + arg.cast_to(CastTarget::pair(l, r)); + } + } + return false; + } + + let total = arg.layout.size; -fn classify_ret(arg: &mut ArgAbi<'_, Ty>, xlen: u64) { // "Scalars wider than 2✕XLEN are passed by reference and are replaced in // the argument list with the address." // "Aggregates larger than 2✕XLEN bits are passed by reference and are // replaced in the argument list with the address, as are C++ aggregates // with nontrivial copy constructors, destructors, or vtables." - if arg.layout.size.bits() > 2 * xlen { - arg.make_indirect(); + if total.bits() > 2 * xlen { + // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN. + if is_riscv_aggregate(arg) { + arg.make_indirect(); + } + return true; + } + + let xlen_reg = match xlen { + 32 => Reg::i32(), + 64 => Reg::i64(), + _ => unreachable!("Unsupported XLEN: {}", xlen), + }; + if is_riscv_aggregate(arg) { + if total.bits() <= xlen { + arg.cast_to(xlen_reg); + } else { + arg.cast_to(Uniform { unit: xlen_reg, total: Size::from_bits(xlen * 2) }); + } + return false; } // "When passed in registers, scalars narrower than XLEN bits are widened // according to the sign of their type up to 32 bits, then sign-extended to // XLEN bits." - arg.extend_integer_width_to(xlen); // this method only affects integer scalars + extend_integer_width(arg, xlen); + false } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>, xlen: u64) { +fn classify_arg<'a, Ty, C>( + cx: &C, + arg: &mut ArgAbi<'a, Ty>, + xlen: u64, + flen: u64, + is_vararg: bool, + avail_gprs: &mut u64, + avail_fprs: &mut u64, +) where + Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf>, +{ + if !is_vararg { + match should_use_fp_conv(cx, &arg.layout, xlen, flen) { + Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { + *avail_fprs -= 1; + arg.cast_to(f); + return; + } + Some(FloatConv::FloatPair(l, r)) if *avail_fprs >= 2 => { + *avail_fprs -= 2; + arg.cast_to(CastTarget::pair(l, r)); + return; + } + Some(FloatConv::MixedPair(l, r)) if *avail_fprs >= 1 && *avail_gprs >= 1 => { + *avail_gprs -= 1; + *avail_fprs -= 1; + arg.cast_to(CastTarget::pair(l, r)); + return; + } + _ => (), + } + } + + let total = arg.layout.size; + let align = arg.layout.align.abi.bits(); + // "Scalars wider than 2✕XLEN are passed by reference and are replaced in // the argument list with the address." // "Aggregates larger than 2✕XLEN bits are passed by reference and are // replaced in the argument list with the address, as are C++ aggregates // with nontrivial copy constructors, destructors, or vtables." - if arg.layout.size.bits() > 2 * xlen { - arg.make_indirect(); + if total.bits() > 2 * xlen { + // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN. + if is_riscv_aggregate(arg) { + arg.make_indirect(); + } + if *avail_gprs >= 1 { + *avail_gprs -= 1; + } + return; + } + + let double_xlen_reg = match xlen { + 32 => Reg::i64(), + 64 => Reg::i128(), + _ => unreachable!("Unsupported XLEN: {}", xlen), + }; + + let xlen_reg = match xlen { + 32 => Reg::i32(), + 64 => Reg::i64(), + _ => unreachable!("Unsupported XLEN: {}", xlen), + }; + + if total.bits() > xlen { + let align_regs = align > xlen; + if is_riscv_aggregate(arg) { + arg.cast_to(Uniform { + unit: if align_regs { double_xlen_reg } else { xlen_reg }, + total: Size::from_bits(xlen * 2), + }); + } + if align_regs && is_vararg { + *avail_gprs -= *avail_gprs % 2; + } + if *avail_gprs >= 2 { + *avail_gprs -= 2; + } else { + *avail_gprs = 0; + } + return; + } else if is_riscv_aggregate(arg) { + arg.cast_to(xlen_reg); + if *avail_gprs >= 1 { + *avail_gprs -= 1; + } + return; } // "When passed in registers, scalars narrower than XLEN bits are widened // according to the sign of their type up to 32 bits, then sign-extended to // XLEN bits." - arg.extend_integer_width_to(xlen); // this method only affects integer scalars + if *avail_gprs >= 1 { + extend_integer_width(arg, xlen); + *avail_gprs -= 1; + } } -pub fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>, xlen: u64) { +fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) { + match arg.layout.abi { + Abi::Scalar(ref scalar) => { + match scalar.value { + abi::Int(i, _) => { + // 32-bit integers are always sign-extended + if i.size().bits() == 32 && xlen > 32 { + if let PassMode::Direct(ref mut attrs) = arg.mode { + attrs.set(ArgAttribute::SExt); + return; + } + } + } + _ => (), + } + } + _ => (), + } + arg.extend_integer_width_to(xlen); +} + +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout + HasTargetSpec, +{ + let flen = match &cx.target_spec().options.llvm_abiname[..] { + "ilp32f" | "lp64f" => 32, + "ilp32d" | "lp64d" => 64, + _ => 0, + }; + let xlen = cx.data_layout().pointer_size.bits(); + + let mut avail_gprs = 8; + let mut avail_fprs = 8; + if !fn_abi.ret.is_ignore() { - classify_ret(&mut fn_abi.ret, xlen); + if classify_ret(cx, &mut fn_abi.ret, xlen, flen) { + avail_gprs -= 1; + } } - for arg in &mut fn_abi.args { + for (i, arg) in fn_abi.args.iter_mut().enumerate() { if arg.is_ignore() { continue; } - classify_arg(arg, xlen); + classify_arg( + cx, + arg, + xlen, + flen, + i >= fn_abi.fixed_count, + &mut avail_gprs, + &mut avail_fprs, + ); } } From 39633874ae7d0150669004a80740ff3b0708d08d Mon Sep 17 00:00:00 2001 From: msizanoen1 Date: Mon, 3 Feb 2020 22:04:44 +0700 Subject: [PATCH 0870/1253] Add tests for RISC-V C ABI --- src/test/auxiliary/rust_test_helpers.c | 29 ++ .../riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs | 181 +++++++++++ .../codegen/riscv-abi/riscv64-lp64d-abi.rs | 293 ++++++++++++++++++ .../riscv-abi/riscv64-lp64f-lp64d-abi.rs | 277 +++++++++++++++++ src/test/ui/abi/struct-enums/struct-return.rs | 52 +++- 5 files changed, 831 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs create mode 100644 src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs create mode 100644 src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c index b95b0ca1a89c0..22bb54988365c 100644 --- a/src/test/auxiliary/rust_test_helpers.c +++ b/src/test/auxiliary/rust_test_helpers.c @@ -168,6 +168,18 @@ struct floats { double c; }; +struct char_char_double { + uint8_t a; + uint8_t b; + double c; +}; + +struct char_char_float { + uint8_t a; + uint8_t b; + float c; +}; + struct quad rust_dbg_abi_1(struct quad q) { struct quad qq = { q.c + 1, @@ -185,6 +197,23 @@ rust_dbg_abi_2(struct floats f) { return ff; } +struct char_char_double +rust_dbg_abi_3(struct char_char_double a) { + struct char_char_double ccd = { a.a + 1, + a.b - 1, + a.c + 1.0 }; + return ccd; +} + +struct char_char_float +rust_dbg_abi_4(struct char_char_float a) { + struct char_char_float ccd = { a.a + 1, + a.b - 1, + a.c + 1.0 }; + return ccd; +} + + int rust_dbg_static_mut = 3; diff --git a/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs new file mode 100644 index 0000000000000..f0f052fe5c557 --- /dev/null +++ b/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -0,0 +1,181 @@ +// ignore-tidy-linelength +// compile-flags: -C no-prepopulate-passes +// only-riscv64 +// only-linux +#![crate_type = "lib"] +#![allow(improper_ctypes)] + +// CHECK: define void @f_void() +#[no_mangle] +pub extern "C" fn f_void() {} + +// CHECK: define zeroext i1 @f_scalar_0(i1 zeroext %a) +#[no_mangle] +pub extern "C" fn f_scalar_0(a: bool) -> bool { + a +} + +// CHECK: define signext i8 @f_scalar_1(i8 signext %x) +#[no_mangle] +pub extern "C" fn f_scalar_1(x: i8) -> i8 { + x +} + +// CHECK: define zeroext i8 @f_scalar_2(i8 zeroext %x) +#[no_mangle] +pub extern "C" fn f_scalar_2(x: u8) -> u8 { + x +} + +// CHECK: define signext i32 @f_scalar_3(i32 signext %x) +#[no_mangle] +pub extern "C" fn f_scalar_3(x: i32) -> u32 { + x as u32 +} + +// CHECK: define i64 @f_scalar_4(i64 %x) +#[no_mangle] +pub extern "C" fn f_scalar_4(x: i64) -> i64 { + x +} + +// CHECK: define float @f_fp_scalar_1(float) +#[no_mangle] +pub extern "C" fn f_fp_scalar_1(x: f32) -> f32 { + x +} +// CHECK: define double @f_fp_scalar_2(double) +#[no_mangle] +pub extern "C" fn f_fp_scalar_2(x: f64) -> f64 { + x +} + +#[repr(C)] +pub struct Empty {} + +// CHECK: define void @f_agg_empty_struct() +#[no_mangle] +pub extern "C" fn f_agg_empty_struct(e: Empty) -> Empty { + e +} + +#[repr(C)] +pub struct Tiny { + a: u16, + b: u16, + c: u16, + d: u16, +} + +// CHECK: define void @f_agg_tiny(i64) +#[no_mangle] +pub extern "C" fn f_agg_tiny(mut e: Tiny) { + e.a += e.b; + e.c += e.d; +} + +// CHECK: define i64 @f_agg_tiny_ret() +#[no_mangle] +pub extern "C" fn f_agg_tiny_ret() -> Tiny { + Tiny { a: 1, b: 2, c: 3, d: 4 } +} + +#[repr(C)] +pub struct Small { + a: i64, + b: *mut i64, +} + +// CHECK: define void @f_agg_small([2 x i64]) +#[no_mangle] +pub extern "C" fn f_agg_small(mut x: Small) { + x.a += unsafe { *x.b }; + x.b = &mut x.a; +} + +// CHECK: define [2 x i64] @f_agg_small_ret() +#[no_mangle] +pub extern "C" fn f_agg_small_ret() -> Small { + Small { a: 1, b: core::ptr::null_mut() } +} + +#[repr(C)] +pub struct SmallAligned { + a: i128, +} + +// CHECK: define void @f_agg_small_aligned(i128) +#[no_mangle] +pub extern "C" fn f_agg_small_aligned(mut x: SmallAligned) { + x.a += x.a; +} + +#[repr(C)] +pub struct Large { + a: i64, + b: i64, + c: i64, + d: i64, +} + +// CHECK: define void @f_agg_large(%Large* {{.*}}%x) +#[no_mangle] +pub extern "C" fn f_agg_large(mut x: Large) { + x.a = x.b + x.c + x.d; +} + +// CHECK: define void @f_agg_large_ret(%Large* {{.*}}sret{{.*}}, i32 signext %i, i8 signext %j) +#[no_mangle] +pub extern "C" fn f_agg_large_ret(i: i32, j: i8) -> Large { + Large { a: 1, b: 2, c: 3, d: 4 } +} + +// CHECK: define void @f_scalar_stack_1(i64, [2 x i64], i128, %Large* {{.*}}%d, i8 zeroext %e, i8 signext %f, i8 %g, i8 %h) +#[no_mangle] +pub extern "C" fn f_scalar_stack_1( + a: Tiny, + b: Small, + c: SmallAligned, + d: Large, + e: u8, + f: i8, + g: u8, + h: i8, +) { +} + +// CHECK: define void @f_scalar_stack_2(%Large* {{.*}}sret{{.*}}, i64 %a, i128, i128, i64 %d, i8 zeroext %e, i8 %f, i8 %g) +#[no_mangle] +pub extern "C" fn f_scalar_stack_2( + a: u64, + b: SmallAligned, + c: SmallAligned, + d: u64, + e: u8, + f: i8, + g: u8, +) -> Large { + Large { a: a as i64, b: e as i64, c: f as i64, d: g as i64 } +} + +extern "C" { + fn f_va_callee(_: i32, ...) -> i32; +} + +#[no_mangle] +pub unsafe extern "C" fn f_va_caller() { + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i64 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, %Large* {{.*}}) + f_va_callee( + 1, + 2i32, + 3i64, + 4.0f64, + 5.0f64, + Tiny { a: 1, b: 2, c: 3, d: 4 }, + Small { a: 10, b: core::ptr::null_mut() }, + SmallAligned { a: 11 }, + Large { a: 12, b: 13, c: 14, d: 15 }, + ); + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i32 signext 3, i32 signext 4, i128 {{.*}}, i32 signext 6, i32 signext 7, i32 8, i32 9) + f_va_callee(1, 2i32, 3i32, 4i32, SmallAligned { a: 5 }, 6i32, 7i32, 8i32, 9i32); +} diff --git a/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs new file mode 100644 index 0000000000000..66a3b9e4952a9 --- /dev/null +++ b/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs @@ -0,0 +1,293 @@ +// ignore-tidy-linelength +// compile-flags: -C no-prepopulate-passes +// only-riscv64 +// only-linux +#![crate_type = "lib"] + +// CHECK: define void @f_fpr_tracking(double, double, double, double, double, double, double, double, i8 zeroext %i) +#[no_mangle] +pub extern "C" fn f_fpr_tracking( + a: f64, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: f64, + i: u8, +) { +} + +#[repr(C)] +pub struct Double { + f: f64, +} + +#[repr(C)] +pub struct DoubleDouble { + f: f64, + g: f64, +} + +#[repr(C)] +pub struct DoubleFloat { + f: f64, + g: f32, +} + +// CHECK: define void @f_double_s_arg(double) +#[no_mangle] +pub extern "C" fn f_double_s_arg(a: Double) {} + +// CHECK: define double @f_ret_double_s() +#[no_mangle] +pub extern "C" fn f_ret_double_s() -> Double { + Double { f: 1. } +} + +// CHECK: define void @f_double_double_s_arg({ double, double }) +#[no_mangle] +pub extern "C" fn f_double_double_s_arg(a: DoubleDouble) {} + +// CHECK: define { double, double } @f_ret_double_double_s() +#[no_mangle] +pub extern "C" fn f_ret_double_double_s() -> DoubleDouble { + DoubleDouble { f: 1., g: 2. } +} + +// CHECK: define void @f_double_float_s_arg({ double, float }) +#[no_mangle] +pub extern "C" fn f_double_float_s_arg(a: DoubleFloat) {} + +// CHECK: define { double, float } @f_ret_double_float_s() +#[no_mangle] +pub extern "C" fn f_ret_double_float_s() -> DoubleFloat { + DoubleFloat { f: 1., g: 2. } +} + +// CHECK: define void @f_double_double_s_arg_insufficient_fprs(double, double, double, double, double, double, double, [2 x i64]) +#[no_mangle] +pub extern "C" fn f_double_double_s_arg_insufficient_fprs( + a: f64, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: DoubleDouble, +) { +} + +#[repr(C)] +pub struct DoubleInt8 { + f: f64, + i: i8, +} + +#[repr(C)] +pub struct DoubleUInt8 { + f: f64, + i: u8, +} + +#[repr(C)] +pub struct DoubleInt32 { + f: f64, + i: i32, +} + +#[repr(C)] +pub struct DoubleInt64 { + f: f64, + i: i64, +} + +// CHECK: define void @f_double_int8_s_arg({ double, i8 }) +#[no_mangle] +pub extern "C" fn f_double_int8_s_arg(a: DoubleInt8) {} + +// CHECK: define { double, i8 } @f_ret_double_int8_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int8_s() -> DoubleInt8 { + DoubleInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int32_s_arg({ double, i32 }) +#[no_mangle] +pub extern "C" fn f_double_int32_s_arg(a: DoubleInt32) {} + +// CHECK: define { double, i32 } @f_ret_double_int32_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int32_s() -> DoubleInt32 { + DoubleInt32 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_uint8_s_arg({ double, i8 }) +#[no_mangle] +pub extern "C" fn f_double_uint8_s_arg(a: DoubleUInt8) {} + +// CHECK: define { double, i8 } @f_ret_double_uint8_s() +#[no_mangle] +pub extern "C" fn f_ret_double_uint8_s() -> DoubleUInt8 { + DoubleUInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int64_s_arg({ double, i64 }) +#[no_mangle] +pub extern "C" fn f_double_int64_s_arg(a: DoubleInt64) {} + +// CHECK: define { double, i64 } @f_ret_double_int64_s() +#[no_mangle] +pub extern "C" fn f_ret_double_int64_s() -> DoubleInt64 { + DoubleInt64 { f: 1., i: 2 } +} + +// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, [2 x i64]) +#[no_mangle] +pub extern "C" fn f_double_int8_s_arg_insufficient_gprs( + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: DoubleInt8, +) { +} + +// CHECK: define void @f_struct_double_int8_insufficient_fprs(float, double, double, double, double, double, double, double, [2 x i64]) +#[no_mangle] +pub extern "C" fn f_struct_double_int8_insufficient_fprs( + a: f32, + b: f64, + c: f64, + d: f64, + e: f64, + f: f64, + g: f64, + h: f64, + i: DoubleInt8, +) { +} + +#[repr(C)] +pub struct DoubleArr1 { + a: [f64; 1], +} + +// CHECK: define void @f_doublearr1_s_arg(double) +#[no_mangle] +pub extern "C" fn f_doublearr1_s_arg(a: DoubleArr1) {} + +// CHECK: define double @f_ret_doublearr1_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr1_s() -> DoubleArr1 { + DoubleArr1 { a: [1.] } +} + +#[repr(C)] +pub struct DoubleArr2 { + a: [f64; 2], +} + +// CHECK: define void @f_doublearr2_s_arg({ double, double }) +#[no_mangle] +pub extern "C" fn f_doublearr2_s_arg(a: DoubleArr2) {} + +// CHECK: define { double, double } @f_ret_doublearr2_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_s() -> DoubleArr2 { + DoubleArr2 { a: [1., 2.] } +} + +#[repr(C)] +pub struct Tricky1 { + f: [f64; 1], +} + +#[repr(C)] +pub struct DoubleArr2Tricky1 { + g: [Tricky1; 2], +} + +// CHECK: define void @f_doublearr2_tricky1_s_arg({ double, double }) +#[no_mangle] +pub extern "C" fn f_doublearr2_tricky1_s_arg(a: DoubleArr2Tricky1) {} + +// CHECK: define { double, double } @f_ret_doublearr2_tricky1_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_tricky1_s() -> DoubleArr2Tricky1 { + DoubleArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct EmptyStruct {} + +#[repr(C)] +pub struct DoubleArr2Tricky2 { + s: EmptyStruct, + g: [Tricky1; 2], +} + +// CHECK: define void @f_doublearr2_tricky2_s_arg({ double, double }) +#[no_mangle] +pub extern "C" fn f_doublearr2_tricky2_s_arg(a: DoubleArr2Tricky2) {} + +// CHECK: define { double, double } @f_ret_doublearr2_tricky2_s() +#[no_mangle] +pub extern "C" fn f_ret_doublearr2_tricky2_s() -> DoubleArr2Tricky2 { + DoubleArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct IntDoubleInt { + a: i32, + b: f64, + c: i32, +} + +// CHECK: define void @f_int_double_int_s_arg(%IntDoubleInt* {{.*}}%a) +#[no_mangle] +pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} + +// CHECK: define void @f_ret_int_double_int_s(%IntDoubleInt* {{.*}}sret +#[no_mangle] +pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { + IntDoubleInt { a: 1, b: 2., c: 3 } +} + +#[repr(C)] +pub struct CharCharDouble { + a: u8, + b: u8, + c: f64, +} + +// CHECK: define void @f_char_char_double_s_arg([2 x i64]) +#[no_mangle] +pub extern "C" fn f_char_char_double_s_arg(a: CharCharDouble) {} + +// CHECK: define [2 x i64] @f_ret_char_char_double_s() +#[no_mangle] +pub extern "C" fn f_ret_char_char_double_s() -> CharCharDouble { + CharCharDouble { a: 1, b: 2, c: 3. } +} + +#[repr(C)] +pub union DoubleU { + a: f64, +} + +// CHECK: define void @f_double_u_arg(i64) +#[no_mangle] +pub extern "C" fn f_double_u_arg(a: DoubleU) {} + +// CHECK: define i64 @f_ret_double_u() +#[no_mangle] +pub extern "C" fn f_ret_double_u() -> DoubleU { + unsafe { DoubleU { a: 1. } } +} diff --git a/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs new file mode 100644 index 0000000000000..d843331f425de --- /dev/null +++ b/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs @@ -0,0 +1,277 @@ +// ignore-tidy-linelength +// compile-flags: -C no-prepopulate-passes +// only-riscv64 +// only-linux +#![crate_type = "lib"] + +// CHECK: define void @f_fpr_tracking(float, float, float, float, float, float, float, float, i8 zeroext %i) +#[no_mangle] +pub extern "C" fn f_fpr_tracking( + a: f32, + b: f32, + c: f32, + d: f32, + e: f32, + f: f32, + g: f32, + h: f32, + i: u8, +) { +} + +#[repr(C)] +pub struct Float { + f: f32, +} + +#[repr(C)] +pub struct FloatFloat { + f: f32, + g: f32, +} + +// CHECK: define void @f_float_s_arg(float) +#[no_mangle] +pub extern "C" fn f_float_s_arg(a: Float) {} + +// CHECK: define float @f_ret_float_s() +#[no_mangle] +pub extern "C" fn f_ret_float_s() -> Float { + Float { f: 1. } +} + +// CHECK: define void @f_float_float_s_arg({ float, float }) +#[no_mangle] +pub extern "C" fn f_float_float_s_arg(a: FloatFloat) {} + +// CHECK: define { float, float } @f_ret_float_float_s() +#[no_mangle] +pub extern "C" fn f_ret_float_float_s() -> FloatFloat { + FloatFloat { f: 1., g: 2. } +} + +// CHECK: define void @f_float_float_s_arg_insufficient_fprs(float, float, float, float, float, float, float, i64) +#[no_mangle] +pub extern "C" fn f_float_float_s_arg_insufficient_fprs( + a: f32, + b: f32, + c: f32, + d: f32, + e: f32, + f: f32, + g: f32, + h: FloatFloat, +) { +} + +#[repr(C)] +pub struct FloatInt8 { + f: f32, + i: i8, +} + +#[repr(C)] +pub struct FloatUInt8 { + f: f32, + i: u8, +} + +#[repr(C)] +pub struct FloatInt32 { + f: f32, + i: i32, +} + +#[repr(C)] +pub struct FloatInt64 { + f: f32, + i: i64, +} + +// CHECK: define void @f_float_int8_s_arg({ float, i8 }) +#[no_mangle] +pub extern "C" fn f_float_int8_s_arg(a: FloatInt8) {} + +// CHECK: define { float, i8 } @f_ret_float_int8_s() +#[no_mangle] +pub extern "C" fn f_ret_float_int8_s() -> FloatInt8 { + FloatInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_float_int32_s_arg({ float, i32 }) +#[no_mangle] +pub extern "C" fn f_float_int32_s_arg(a: FloatInt32) {} + +// CHECK: define { float, i32 } @f_ret_float_int32_s() +#[no_mangle] +pub extern "C" fn f_ret_float_int32_s() -> FloatInt32 { + FloatInt32 { f: 1., i: 2 } +} + +// CHECK: define void @f_float_uint8_s_arg({ float, i8 }) +#[no_mangle] +pub extern "C" fn f_float_uint8_s_arg(a: FloatUInt8) {} + +// CHECK: define { float, i8 } @f_ret_float_uint8_s() +#[no_mangle] +pub extern "C" fn f_ret_float_uint8_s() -> FloatUInt8 { + FloatUInt8 { f: 1., i: 2 } +} + +// CHECK: define void @f_float_int64_s_arg({ float, i64 }) +#[no_mangle] +pub extern "C" fn f_float_int64_s_arg(a: FloatInt64) {} + +// CHECK: define { float, i64 } @f_ret_float_int64_s() +#[no_mangle] +pub extern "C" fn f_ret_float_int64_s() -> FloatInt64 { + FloatInt64 { f: 1., i: 2 } +} + +// CHECK: define void @f_float_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, i64) +#[no_mangle] +pub extern "C" fn f_float_int8_s_arg_insufficient_gprs( + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: FloatInt8, +) { +} + +// CHECK: define void @f_struct_float_int8_insufficient_fprs(float, float, float, float, float, float, float, float, i64) +#[no_mangle] +pub extern "C" fn f_struct_float_int8_insufficient_fprs( + a: f32, + b: f32, + c: f32, + d: f32, + e: f32, + f: f32, + g: f32, + h: f32, + i: FloatInt8, +) { +} + +#[repr(C)] +pub struct FloatArr1 { + a: [f32; 1], +} + +// CHECK: define void @f_floatarr1_s_arg(float) +#[no_mangle] +pub extern "C" fn f_floatarr1_s_arg(a: FloatArr1) {} + +// CHECK: define float @f_ret_floatarr1_s() +#[no_mangle] +pub extern "C" fn f_ret_floatarr1_s() -> FloatArr1 { + FloatArr1 { a: [1.] } +} + +#[repr(C)] +pub struct FloatArr2 { + a: [f32; 2], +} + +// CHECK: define void @f_floatarr2_s_arg({ float, float }) +#[no_mangle] +pub extern "C" fn f_floatarr2_s_arg(a: FloatArr2) {} + +// CHECK: define { float, float } @f_ret_floatarr2_s() +#[no_mangle] +pub extern "C" fn f_ret_floatarr2_s() -> FloatArr2 { + FloatArr2 { a: [1., 2.] } +} + +#[repr(C)] +pub struct Tricky1 { + f: [f32; 1], +} + +#[repr(C)] +pub struct FloatArr2Tricky1 { + g: [Tricky1; 2], +} + +// CHECK: define void @f_floatarr2_tricky1_s_arg({ float, float }) +#[no_mangle] +pub extern "C" fn f_floatarr2_tricky1_s_arg(a: FloatArr2Tricky1) {} + +// CHECK: define { float, float } @f_ret_floatarr2_tricky1_s() +#[no_mangle] +pub extern "C" fn f_ret_floatarr2_tricky1_s() -> FloatArr2Tricky1 { + FloatArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct EmptyStruct {} + +#[repr(C)] +pub struct FloatArr2Tricky2 { + s: EmptyStruct, + g: [Tricky1; 2], +} + +// CHECK: define void @f_floatarr2_tricky2_s_arg({ float, float }) +#[no_mangle] +pub extern "C" fn f_floatarr2_tricky2_s_arg(a: FloatArr2Tricky2) {} + +// CHECK: define { float, float } @f_ret_floatarr2_tricky2_s() +#[no_mangle] +pub extern "C" fn f_ret_floatarr2_tricky2_s() -> FloatArr2Tricky2 { + FloatArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] } +} + +#[repr(C)] +pub struct IntFloatInt { + a: i32, + b: f32, + c: i32, +} + +// CHECK: define void @f_int_float_int_s_arg([2 x i64]) +#[no_mangle] +pub extern "C" fn f_int_float_int_s_arg(a: IntFloatInt) {} + +// CHECK: define [2 x i64] @f_ret_int_float_int_s() +#[no_mangle] +pub extern "C" fn f_ret_int_float_int_s() -> IntFloatInt { + IntFloatInt { a: 1, b: 2., c: 3 } +} + +#[repr(C)] +pub struct CharCharFloat { + a: u8, + b: u8, + c: f32, +} + +// CHECK: define void @f_char_char_float_s_arg(i64) +#[no_mangle] +pub extern "C" fn f_char_char_float_s_arg(a: CharCharFloat) {} + +// CHECK: define i64 @f_ret_char_char_float_s() +#[no_mangle] +pub extern "C" fn f_ret_char_char_float_s() -> CharCharFloat { + CharCharFloat { a: 1, b: 2, c: 3. } +} + +#[repr(C)] +pub union FloatU { + a: f32, +} + +// CHECK: define void @f_float_u_arg(i64) +#[no_mangle] +pub extern "C" fn f_float_u_arg(a: FloatU) {} + +// CHECK: define i64 @f_ret_float_u() +#[no_mangle] +pub extern "C" fn f_ret_float_u() -> FloatU { + unsafe { FloatU { a: 1. } } +} diff --git a/src/test/ui/abi/struct-enums/struct-return.rs b/src/test/ui/abi/struct-enums/struct-return.rs index 5930fc4acbbe3..a3e70bbdb0809 100644 --- a/src/test/ui/abi/struct-enums/struct-return.rs +++ b/src/test/ui/abi/struct-enums/struct-return.rs @@ -10,13 +10,23 @@ pub struct Quad { a: u64, b: u64, c: u64, d: u64 } #[derive(Copy, Clone)] pub struct Floats { a: f64, b: u8, c: f64 } +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CharCharDouble { a: u8, b: u8, c: f64 } + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CharCharFloat { a: u8, b: u8, c: f32 } + mod rustrt { - use super::{Floats, Quad}; + use super::{Floats, Quad, CharCharDouble, CharCharFloat}; #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_abi_1(q: Quad) -> Quad; pub fn rust_dbg_abi_2(f: Floats) -> Floats; + pub fn rust_dbg_abi_3(a: CharCharDouble) -> CharCharDouble; + pub fn rust_dbg_abi_4(a: CharCharFloat) -> CharCharFloat; } } @@ -58,7 +68,47 @@ fn test2() { fn test2() { } +#[cfg(target_pointer_width = "64")] +fn test3() { + unsafe { + let a = CharCharDouble { + a: 1, + b: 2, + c: 3., + }; + let b = rustrt::rust_dbg_abi_3(a); + println!("a: {}", b.a); + println!("b: {}", b.b); + println!("c: {}", b.c); + assert_eq!(b.a, a.a + 1); + assert_eq!(b.b, a.b - 1); + assert_eq!(b.c, a.c + 1.0); + } +} + +#[cfg(target_pointer_width = "32")] +fn test3() {} + +fn test4() { + unsafe { + let a = CharCharFloat { + a: 1, + b: 2, + c: 3., + }; + let b = rustrt::rust_dbg_abi_4(a); + println!("a: {}", b.a); + println!("b: {}", b.b); + println!("c: {}", b.c); + assert_eq!(b.a, a.a + 1); + assert_eq!(b.b, a.b - 1); + assert_eq!(b.c, a.c + 1.0); + } +} + pub fn main() { test1(); test2(); + test3(); + test4(); } From 341eaf5f55c2fcf5f58a04cb4184306d0263b4f5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 13:18:29 +0100 Subject: [PATCH 0871/1253] Add more tests for generator resume arguments --- src/test/ui/generator/panic-drops-resume.rs | 35 +++++++++++++++++++ .../ui/generator/resume-arg-late-bound.rs | 17 +++++++++ .../ui/generator/resume-arg-late-bound.stderr | 15 ++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/test/ui/generator/panic-drops-resume.rs create mode 100644 src/test/ui/generator/resume-arg-late-bound.rs create mode 100644 src/test/ui/generator/resume-arg-late-bound.stderr diff --git a/src/test/ui/generator/panic-drops-resume.rs b/src/test/ui/generator/panic-drops-resume.rs new file mode 100644 index 0000000000000..4a482d3f6df39 --- /dev/null +++ b/src/test/ui/generator/panic-drops-resume.rs @@ -0,0 +1,35 @@ +//! Tests that panics inside a generator will correctly drop the initial resume argument. + +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic::{catch_unwind, AssertUnwindSafe}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP: AtomicUsize = AtomicUsize::new(0); + +struct Dropper {} + +impl Drop for Dropper { + fn drop(&mut self) { + DROP.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + let mut gen = |_arg| { + if true { + panic!(); + } + yield (); + }; + let mut gen = Pin::new(&mut gen); + + assert_eq!(DROP.load(Ordering::Acquire), 0); + let res = catch_unwind(AssertUnwindSafe(|| gen.as_mut().resume(Dropper {}))); + assert!(res.is_err()); + assert_eq!(DROP.load(Ordering::Acquire), 1); +} diff --git a/src/test/ui/generator/resume-arg-late-bound.rs b/src/test/ui/generator/resume-arg-late-bound.rs new file mode 100644 index 0000000000000..87b1f1a065bc8 --- /dev/null +++ b/src/test/ui/generator/resume-arg-late-bound.rs @@ -0,0 +1,17 @@ +//! Tests that we cannot produce a generator that accepts a resume argument +//! with any lifetime and then stores it across a `yield`. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn test(a: impl for<'a> Generator<&'a mut bool>) {} + +fn main() { + let gen = |arg: &mut bool| { + yield (); + *arg = true; + }; + test(gen); + //~^ ERROR type mismatch in function arguments +} diff --git a/src/test/ui/generator/resume-arg-late-bound.stderr b/src/test/ui/generator/resume-arg-late-bound.stderr new file mode 100644 index 0000000000000..7719d5123f466 --- /dev/null +++ b/src/test/ui/generator/resume-arg-late-bound.stderr @@ -0,0 +1,15 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/resume-arg-late-bound.rs:15:10 + | +LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {} + | ---- ------------------------------- required by this bound in `test` +... +LL | test(gen); + | ^^^ + | | + | expected signature of `for<'a> fn(&'a mut bool) -> _` + | found signature of `fn(&mut bool) -> _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`. From cc66d29e43b0fa9e49e054ade0b2b2299203afab Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 13:35:38 +0100 Subject: [PATCH 0872/1253] Update error message with too many parameters --- src/librustc_ast_lowering/expr.rs | 2 +- src/test/ui/generator/too-many-parameters.rs | 3 ++- src/test/ui/generator/too-many-parameters.stderr | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 0c4cfa1f6505a..dd3316979f6a2 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -693,7 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.sess, fn_decl_span, E0628, - "too many parameters for generator (expected 0 or 1 parameters)" + "too many parameters for a generator (expected 0 or 1 parameters)" ) .emit(); } diff --git a/src/test/ui/generator/too-many-parameters.rs b/src/test/ui/generator/too-many-parameters.rs index a0a27d9068241..7a353ea298b26 100644 --- a/src/test/ui/generator/too-many-parameters.rs +++ b/src/test/ui/generator/too-many-parameters.rs @@ -1,7 +1,8 @@ #![feature(generators)] fn main() { - |(), ()| { //~ error: too many parameters for generator + |(), ()| { + //~^ error: too many parameters for a generator yield; }; } diff --git a/src/test/ui/generator/too-many-parameters.stderr b/src/test/ui/generator/too-many-parameters.stderr index 0dbe5f3f6fde9..a297ee43de969 100644 --- a/src/test/ui/generator/too-many-parameters.stderr +++ b/src/test/ui/generator/too-many-parameters.stderr @@ -1,4 +1,4 @@ -error[E0628]: too many parameters for generator (expected 0 or 1 parameters) +error[E0628]: too many parameters for a generator (expected 0 or 1 parameters) --> $DIR/too-many-parameters.rs:4:5 | LL | |(), ()| { From 72776e6b5d355112ad5d320789cc2b3c6232b953 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 13:35:43 +0100 Subject: [PATCH 0873/1253] Remove obsolete test --- .../generator/no-parameters-on-generators.rs | 10 ----- .../no-parameters-on-generators.stderr | 39 ------------------- 2 files changed, 49 deletions(-) delete mode 100644 src/test/ui/generator/no-parameters-on-generators.rs delete mode 100644 src/test/ui/generator/no-parameters-on-generators.stderr diff --git a/src/test/ui/generator/no-parameters-on-generators.rs b/src/test/ui/generator/no-parameters-on-generators.rs deleted file mode 100644 index cad004895349f..0000000000000 --- a/src/test/ui/generator/no-parameters-on-generators.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(generators)] - -fn main() { - let gen = |start| { - //~^ ERROR type inside generator must be known in this context - yield; - //~^ ERROR type inside generator must be known in this context - //~| ERROR type inside generator must be known in this context - }; -} diff --git a/src/test/ui/generator/no-parameters-on-generators.stderr b/src/test/ui/generator/no-parameters-on-generators.stderr deleted file mode 100644 index f5f83b0476905..0000000000000 --- a/src/test/ui/generator/no-parameters-on-generators.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0698]: type inside generator must be known in this context - --> $DIR/no-parameters-on-generators.rs:4:16 - | -LL | let gen = |start| { - | ^^^^^ cannot infer type - | -note: the type is part of the generator because of this `yield` - --> $DIR/no-parameters-on-generators.rs:6:9 - | -LL | yield; - | ^^^^^ - -error[E0698]: type inside generator must be known in this context - --> $DIR/no-parameters-on-generators.rs:6:9 - | -LL | yield; - | ^^^^^ cannot infer type - | -note: the type is part of the generator because of this `yield` - --> $DIR/no-parameters-on-generators.rs:6:9 - | -LL | yield; - | ^^^^^ - -error[E0698]: type inside generator must be known in this context - --> $DIR/no-parameters-on-generators.rs:6:9 - | -LL | yield; - | ^^^^^ cannot infer type - | -note: the type is part of the generator because of this `yield` - --> $DIR/no-parameters-on-generators.rs:6:9 - | -LL | yield; - | ^^^^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0698`. From 895aab22633abe3e8617c3e2aaa246a7b2ff1492 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 13:52:09 +0100 Subject: [PATCH 0874/1253] Take resume argument from the right generator type I suppose we could also just put `tcx.mk_unit()` here, but this works too --- src/librustc_mir_build/build/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 4c8d8e3a0eac8..ccfee2d2bb2ee 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -83,12 +83,18 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { abi = Abi::Rust; vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)] } - ty::Generator(def_id, substs, _) => { + ty::Generator(def_id, _, _) => { let gen_ty = tcx.body_tables(body_id).node_type(id); - let resume_ty = substs.as_generator().resume_ty(def_id, tcx); // The resume argument may be missing, in that case we need to provide it here. if body.params.is_empty() { + let resume_ty = match gen_ty.kind { + ty::Generator(_, substs, _) => { + substs.as_generator().resume_ty(def_id, tcx) + } + _ => bug!(), + }; + vec![ ArgInfo(gen_ty, None, None, None), ArgInfo(resume_ty, None, None, None), From dbc9894095d7ebc35e521075c98ea0d55175fdd3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 4 Feb 2020 08:14:08 -0500 Subject: [PATCH 0875/1253] Drop unused extern crates --- src/librustc_macros/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index 3f55d81ce7d1b..6b30ae42a1940 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -1,8 +1,6 @@ #![allow(rustc::default_hash_types)] #![recursion_limit = "128"] -extern crate proc_macro; - use synstructure::decl_derive; use proc_macro::TokenStream; From fb66b9ee3bd46448480560110ff3095e4f7488a0 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 14:25:55 +0100 Subject: [PATCH 0876/1253] Don't emit StorageDead for the resume argument --- src/librustc_mir/transform/generator.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 414d91a18be12..267e77ba48128 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1128,10 +1128,6 @@ fn create_cases<'tcx>( Rvalue::Use(Operand::Move(resume_arg.into())), )), }); - statements.push(Statement { - source_info, - kind: StatementKind::StorageDead(resume_arg), - }); } // Then jump to the real target From bdacdf49e532ce869d1eb96e967fd77991566a7f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 16:34:03 +0100 Subject: [PATCH 0877/1253] Remove unused core_intrinsics feature gate from bootstrap --- src/bootstrap/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 637323331f582..042e3b55cc994 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -103,7 +103,6 @@ //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. -#![feature(core_intrinsics)] #![feature(drain_filter)] use std::cell::{Cell, RefCell}; From 095963f91d525951cb0183648c47c427fb69f16d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 18:49:26 +0100 Subject: [PATCH 0878/1253] Remove unused feature gates from librustc --- src/librustc/lib.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 744ee1a65e154..33552ffb03e6d 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -27,7 +27,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(arbitrary_self_types)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] @@ -39,21 +38,15 @@ #![feature(overlapping_marker_traits)] #![feature(extern_types)] #![feature(nll)] -#![feature(optin_builtin_traits)] #![feature(option_expect_none)] #![feature(range_is_empty)] #![feature(specialization)] -#![feature(unboxed_closures)] -#![feature(thread_local)] -#![feature(trace_macros)] #![feature(trusted_len)] #![feature(vec_remove_item)] #![feature(stmt_expr_attributes)] -#![feature(integer_atomics)] #![feature(test)] #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] -#![feature(log_syntax)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(hash_raw_entry)] From f9971c5cba0a141d3f00737292a40e3cacf44ac0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 18:54:13 +0100 Subject: [PATCH 0879/1253] Remove unused feature gates from cg_llvm Also turns a few `box` into `Box::new` --- src/librustc_codegen_llvm/lib.rs | 15 ++++----------- src/librustc_codegen_llvm/metadata.rs | 4 ++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8091a74854070..98a3e695fa079 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -6,18 +6,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] -#![feature(box_patterns)] -#![feature(box_syntax)] #![feature(const_cstr_unchecked)] #![feature(crate_visibility_modifier)] #![feature(extern_types)] #![feature(in_band_lifetimes)] -#![feature(libc)] #![feature(nll)] -#![feature(optin_builtin_traits)] -#![feature(concat_idents)] -#![feature(link_args)] -#![feature(static_nobundle)] #![feature(trusted_len)] #![recursion_limit = "256"] @@ -196,7 +189,7 @@ unsafe impl Sync for LlvmCodegenBackend {} impl LlvmCodegenBackend { pub fn new() -> Box { - box LlvmCodegenBackend(()) + Box::new(LlvmCodegenBackend(())) } } @@ -245,7 +238,7 @@ impl CodegenBackend for LlvmCodegenBackend { } fn metadata_loader(&self) -> Box { - box metadata::LlvmMetadataLoader + Box::new(metadata::LlvmMetadataLoader) } fn provide(&self, providers: &mut ty::query::Providers<'_>) { @@ -262,12 +255,12 @@ impl CodegenBackend for LlvmCodegenBackend { metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box { - box rustc_codegen_ssa::base::codegen_crate( + Box::new(rustc_codegen_ssa::base::codegen_crate( LlvmCodegenBackend(()), tcx, metadata, need_metadata_module, - ) + )) } fn join_codegen( diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index abe34bb148ce5..36b12f1a7b184 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -22,7 +22,7 @@ impl MetadataLoader for LlvmMetadataLoader { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. - let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(box ar)).map_err(|e| { + let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| { debug!("llvm didn't like `{}`: {}", filename.display(), e); format!("failed to read rlib metadata in '{}': {}", filename.display(), e) })?; @@ -44,7 +44,7 @@ impl MetadataLoader for LlvmMetadataLoader { let buf = path_to_c_string(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; - let of = ObjectFile::new(mb).map(|of| OwningRef::new(box of)).ok_or_else(|| { + let of = ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| { format!("provided path not an object file: '{}'", filename.display()) })?; let buf = of.try_map(|of| search_meta_section(of, target, filename))?; From c2da8b3f0d669cb5d6e7d1338aed91fd1c76b8a3 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:04:56 +0100 Subject: [PATCH 0880/1253] Remove unused feature gates from cg_ssa and cg_utils --- src/librustc_codegen_ssa/lib.rs | 4 ---- src/librustc_codegen_utils/lib.rs | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index f39587122c56d..a2bb39b9e4019 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -1,10 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] #![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(core_intrinsics)] -#![feature(libc)] -#![feature(stmt_expr_attributes)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 6b802bf530e86..38906bbaef810 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -3,10 +3,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(arbitrary_self_types)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(core_intrinsics)] #![feature(never_type)] #![feature(nll)] #![feature(in_band_lifetimes)] From 2a4596abfb4449371982c824c330e30f4ae0d1ee Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:08:28 +0100 Subject: [PATCH 0881/1253] Remove unused feature gates from librustc_data_structures --- src/librustc_data_structures/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index aaac7fb4460cd..13792a0c890c4 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -12,7 +12,6 @@ #![feature(generators)] #![feature(generator_trait)] #![feature(fn_traits)] -#![feature(unsize)] #![feature(specialization)] #![feature(optin_builtin_traits)] #![feature(nll)] @@ -20,11 +19,9 @@ #![feature(hash_raw_entry)] #![feature(stmt_expr_attributes)] #![feature(core_intrinsics)] -#![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] #![feature(thread_id_value)] -#![cfg_attr(unix, feature(libc))] #![allow(rustc::default_hash_types)] #[macro_use] From cf862df494438923295ae4ca78b40787c6b89d53 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:10:39 +0100 Subject: [PATCH 0882/1253] Remove unused feature gates from librustc_driver --- src/librustc_driver/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 019ff431bcb97..52c6399498534 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -5,12 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(box_syntax)] -#![cfg_attr(unix, feature(libc))] #![feature(nll)] -#![feature(set_stdio)] -#![feature(no_debug)] -#![feature(integer_atomics)] #![recursion_limit = "256"] pub extern crate getopts; From 3e61d52784bd20140a8124d41a9661378b65f40e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:11:41 +0100 Subject: [PATCH 0883/1253] Remove unused feature gates from librustc_errors --- src/librustc_errors/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 17b293401f89e..109b151e4140b 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -4,9 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] -#![cfg_attr(unix, feature(libc))] #![feature(nll)] -#![feature(optin_builtin_traits)] pub use emitter::ColorConfig; From 302f8c97ea92d010f39a19563e8881a704c6f136 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 25 Jan 2020 15:30:19 -0500 Subject: [PATCH 0884/1253] Remove the `overlapping_marker_traits` feature See #29864 This has been replaced by `#[feature(marker_trait_attr)]` A few notes: * Due to PR #68057 not yet being in the bootstrap compiler, it's necessary to continue using `#![feature(overlapping_marker_traits)]` under `#[cfg(bootstrap)]` to work around type inference issues. * I've updated tests that used `overlapping_marker_traits` to now use `marker_trait_attr` where applicable The test `src/test/ui/overlap-marker-trait.rs` doesn't make any sense now that `overlapping_marker_traits`, so I removed it. The test `src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs` now fails, since it's no longer possible to have multiple overlapping negative impls of `Send`. I believe that this is the behavior we want (assuming that `Send` is not going to become a `#[marker]` trait, so I renamed the test to `overlap-permitted-for-marker-traits-neg` --- src/librustc/arena.rs | 1 + src/librustc/lib.rs | 2 +- src/librustc/ty/mod.rs | 14 ++------- src/librustc_feature/active.rs | 3 -- src/librustc_feature/removed.rs | 4 ++- ...herence-conflicting-negative-trait-impl.rs | 7 +++-- ...nce-conflicting-negative-trait-impl.stderr | 14 ++++----- src/test/ui/coherence/coherence-impls-send.rs | 4 +-- .../ui/coherence/coherence-impls-send.stderr | 23 ++++++++++---- ...lap-doesnt-conflict-with-specialization.rs | 3 +- src/test/ui/overlap-marker-trait.rs | 31 ------------------- src/test/ui/overlap-marker-trait.stderr | 12 ------- ...verlap-not-permitted-for-builtin-trait.rs} | 5 ++- ...lap-not-permitted-for-builtin-trait.stderr | 11 +++++++ .../overlap-permitted-for-marker-traits.rs | 27 ---------------- 15 files changed, 52 insertions(+), 109 deletions(-) delete mode 100644 src/test/ui/overlap-marker-trait.rs delete mode 100644 src/test/ui/overlap-marker-trait.stderr rename src/test/ui/traits/{overlap-permitted-for-marker-traits-neg.rs => overlap-not-permitted-for-builtin-trait.rs} (55%) create mode 100644 src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr delete mode 100644 src/test/ui/traits/overlap-permitted-for-marker-traits.rs diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 15e92d8d84219..92f5bf87535e6 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -216,6 +216,7 @@ arena_types!(declare_arena, [], 'tcx); arena_types!(impl_arena_allocatable, [], 'tcx); +#[marker] pub trait ArenaAllocatable {} impl ArenaAllocatable for T {} diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 744ee1a65e154..2f77792f7a198 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -36,7 +36,7 @@ #![feature(drain_filter)] #![feature(never_type)] #![feature(exhaustive_patterns)] -#![feature(overlapping_marker_traits)] +#![feature(marker_trait_attr)] #![feature(extern_types)] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..36ac0e68336a4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2642,9 +2642,7 @@ impl<'tcx> ::std::ops::Deref for Attributes<'tcx> { pub enum ImplOverlapKind { /// These impls are always allowed to overlap. Permitted { - /// Whether or not the impl is permitted due to the trait being - /// a marker trait (a trait with #[marker], or a trait with - /// no associated items and #![feature(overlapping_marker_traits)] enabled) + /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait marker: bool, }, /// These impls are allowed to overlap, but that raises @@ -2791,15 +2789,7 @@ impl<'tcx> TyCtxt<'tcx> { | (ImplPolarity::Negative, ImplPolarity::Negative) => {} }; - let is_marker_overlap = if self.features().overlapping_marker_traits { - let trait1_is_empty = self.impl_trait_ref(def_id1).map_or(false, |trait_ref| { - self.associated_item_def_ids(trait_ref.def_id).is_empty() - }); - let trait2_is_empty = self.impl_trait_ref(def_id2).map_or(false, |trait_ref| { - self.associated_item_def_ids(trait_ref.def_id).is_empty() - }); - trait1_is_empty && trait2_is_empty - } else { + let is_marker_overlap = { let is_marker_impl = |def_id: DefId| -> bool { let trait_ref = self.impl_trait_ref(def_id); trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker) diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 0252d88e73889..4ae79f9ccaa6c 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -344,9 +344,6 @@ declare_features! ( /// Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - /// Allows overlapping impls of marker traits. - (active, overlapping_marker_traits, "1.18.0", Some(29864), None), - /// Allows a test to fail without failing the whole suite. (active, allow_fail, "1.19.0", Some(46488), None), diff --git a/src/librustc_feature/removed.rs b/src/librustc_feature/removed.rs index d5b6fe81c7be8..e6ea093fe89c7 100644 --- a/src/librustc_feature/removed.rs +++ b/src/librustc_feature/removed.rs @@ -108,7 +108,9 @@ declare_features! ( /// Allows using `#[on_unimplemented(..)]` on traits. /// (Moved to `rustc_attrs`.) (removed, on_unimplemented, "1.40.0", None, None, None), - + /// Allows overlapping impls of marker traits. + (removed, overlapping_marker_traits, "1.42.0", Some(29864), None, + Some("removed in favor of `#![feature(marker_trait_attr)]`")), // ------------------------------------------------------------------------- // feature-group-end: removed features // ------------------------------------------------------------------------- diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs index 66d0958e4c9a4..b4f5f9ef56bb1 100644 --- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -1,6 +1,7 @@ #![feature(optin_builtin_traits)] -#![feature(overlapping_marker_traits)] +#![feature(marker_trait_attr)] +#[marker] trait MyTrait {} struct TestType(::std::marker::PhantomData); @@ -8,11 +9,11 @@ struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} impl !Send for TestType {} -//~^ ERROR E0119 +//~^ ERROR conflicting implementations unsafe impl Send for TestType {} +//~^ ERROR conflicting implementations impl !Send for TestType {} -//~^ ERROR E0119 fn main() {} diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr index 0a8bbc4bc50a8..25d3d3ee997a5 100644 --- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`: - --> $DIR/coherence-conflicting-negative-trait-impl.rs:10:1 + --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1 | LL | unsafe impl Send for TestType {} | ---------------------------------------------------- first implementation here @@ -7,14 +7,14 @@ LL | LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType`: - --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1 +error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`: + --> $DIR/coherence-conflicting-negative-trait-impl.rs:14:1 | +LL | unsafe impl Send for TestType {} + | ---------------------------------------------------- first implementation here +... LL | unsafe impl Send for TestType {} - | ------------------------------------------- first implementation here -LL | -LL | impl !Send for TestType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-impls-send.rs b/src/test/ui/coherence/coherence-impls-send.rs index b2a9c5be65843..7898dc9831da2 100644 --- a/src/test/ui/coherence/coherence-impls-send.rs +++ b/src/test/ui/coherence/coherence-impls-send.rs @@ -1,5 +1,4 @@ #![feature(optin_builtin_traits)] -#![feature(overlapping_marker_traits)] use std::marker::Copy; @@ -24,7 +23,8 @@ unsafe impl Send for [MyType] {} //~^ ERROR E0117 unsafe impl Send for &'static [NotSync] {} -//~^ ERROR E0117 +//~^ ERROR conflicting implementations of trait +//~| ERROR only traits defined in the current crate fn main() { } diff --git a/src/test/ui/coherence/coherence-impls-send.stderr b/src/test/ui/coherence/coherence-impls-send.stderr index a5b3c7657bdfe..dbfc968332c5c 100644 --- a/src/test/ui/coherence/coherence-impls-send.stderr +++ b/src/test/ui/coherence/coherence-impls-send.stderr @@ -1,5 +1,16 @@ +error[E0119]: conflicting implementations of trait `std::marker::Send` for type `&[NotSync]`: + --> $DIR/coherence-impls-send.rs:25:1 + | +LL | unsafe impl Send for &'static [NotSync] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl std::marker::Send for &T + where T: std::marker::Sync, T: ?Sized; + = note: upstream crates may add a new impl of trait `std::marker::Sync` for type `[NotSync]` in future versions + error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-send.rs:17:1 + --> $DIR/coherence-impls-send.rs:16:1 | LL | unsafe impl Send for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^---------------- @@ -10,13 +21,13 @@ LL | unsafe impl Send for (MyType, MyType) {} = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync` - --> $DIR/coherence-impls-send.rs:20:1 + --> $DIR/coherence-impls-send.rs:19:1 | LL | unsafe impl Send for &'static NotSync {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-send.rs:23:1 + --> $DIR/coherence-impls-send.rs:22:1 | LL | unsafe impl Send for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^-------- @@ -27,7 +38,7 @@ LL | unsafe impl Send for [MyType] {} = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-send.rs:26:1 + --> $DIR/coherence-impls-send.rs:25:1 | LL | unsafe impl Send for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^------------------ @@ -37,7 +48,7 @@ LL | unsafe impl Send for &'static [NotSync] {} | = note: define and implement a trait or new type instead -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0117, E0321. +Some errors have detailed explanations: E0117, E0119, E0321. For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/overlap-doesnt-conflict-with-specialization.rs b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs index 3d4069f368d2a..dd09d68367ec3 100644 --- a/src/test/ui/overlap-doesnt-conflict-with-specialization.rs +++ b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs @@ -1,8 +1,9 @@ // run-pass -#![feature(overlapping_marker_traits)] +#![feature(marker_trait_attr)] #![feature(specialization)] +#[marker] trait MyMarker {} impl MyMarker for T {} diff --git a/src/test/ui/overlap-marker-trait.rs b/src/test/ui/overlap-marker-trait.rs deleted file mode 100644 index bf39d9c903f80..0000000000000 --- a/src/test/ui/overlap-marker-trait.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Test for RFC 1268: we allow overlapping impls of marker traits, -// that is, traits without items. In this case, a type `T` is -// `MyMarker` if it is either `Debug` or `Display`. This test just -// checks that we don't consider **all** types to be `MyMarker`. See -// also the companion test in -// `run-pass/overlap-permitted-for-marker-traits.rs`. - -#![feature(overlapping_marker_traits)] -#![feature(optin_builtin_traits)] - -use std::fmt::{Debug, Display}; - -trait Marker {} - -impl Marker for T {} -impl Marker for T {} - -fn is_marker() { } - -struct NotDebugOrDisplay; - -fn main() { - // Debug && Display: - is_marker::(); - - // Debug && !Display: - is_marker::>(); - - // !Debug && !Display - is_marker::(); //~ ERROR -} diff --git a/src/test/ui/overlap-marker-trait.stderr b/src/test/ui/overlap-marker-trait.stderr deleted file mode 100644 index 15ebcd17b0dbc..0000000000000 --- a/src/test/ui/overlap-marker-trait.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied - --> $DIR/overlap-marker-trait.rs:30:17 - | -LL | fn is_marker() { } - | --------- ------ required by this bound in `is_marker` -... -LL | is_marker::(); - | ^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs similarity index 55% rename from src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs rename to src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs index bc8dc8dbd05b5..86029473b513b 100644 --- a/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs +++ b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs @@ -1,12 +1,11 @@ -// run-pass #![allow(dead_code)] -#![feature(overlapping_marker_traits)] #![feature(optin_builtin_traits)] -// Overlapping negative impls for `MyStruct` are permitted: +// Overlapping negative impls for `MyStruct` are not permitted: struct MyStruct; impl !Send for MyStruct {} impl !Send for MyStruct {} +//~^ ERROR conflicting implementations of trait fn main() { } diff --git a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr new file mode 100644 index 0000000000000..94a0c287f4a32 --- /dev/null +++ b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `std::marker::Send` for type `MyStruct`: + --> $DIR/overlap-not-permitted-for-builtin-trait.rs:7:1 + | +LL | impl !Send for MyStruct {} + | ----------------------- first implementation here +LL | impl !Send for MyStruct {} + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/traits/overlap-permitted-for-marker-traits.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs deleted file mode 100644 index 59ec9d5689d8c..0000000000000 --- a/src/test/ui/traits/overlap-permitted-for-marker-traits.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// Tests for RFC 1268: we allow overlapping impls of marker traits, -// that is, traits without items. In this case, a type `T` is -// `MyMarker` if it is either `Debug` or `Display`. - -#![feature(overlapping_marker_traits)] -#![feature(optin_builtin_traits)] - -use std::fmt::{Debug, Display}; - -trait MyMarker {} - -impl MyMarker for T {} -impl MyMarker for T {} - -fn foo(t: T) -> T { - t -} - -fn main() { - // Debug && Display: - assert_eq!(1, foo(1)); - assert_eq!(2.0, foo(2.0)); - - // Debug && !Display: - assert_eq!(vec![1], foo(vec![1])); -} From d9e3d2a5314258e2b8adc86c1ded34c4995fcd67 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 12:31:39 -0800 Subject: [PATCH 0885/1253] Make euclidean division `const` Co-Authored-By: 9999years --- src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 48 ++++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 6edf253d4bb80..4fc7caa62b5cd 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -72,6 +72,7 @@ #![feature(concat_idents)] #![feature(const_alloc_layout)] #![feature(const_if_match)] +#![feature(const_int_euclidean)] #![feature(const_panic)] #![feature(const_fn_union)] #![feature(const_generics)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 39c7d6d24ed04..ede568da3e5bd 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -802,10 +802,11 @@ assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None); assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div_euclid(self, rhs: Self) -> Option { + pub const fn checked_div_euclid(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -860,10 +861,11 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem_euclid(self, rhs: Self) -> Option { + pub const fn checked_rem_euclid(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -1298,10 +1300,11 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); assert_eq!((-128i8).wrapping_div_euclid(-1), -128); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div_euclid(self, rhs: Self) -> Self { + pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { self.overflowing_div_euclid(rhs).0 } } @@ -1356,10 +1359,11 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); assert_eq!((-128i8).wrapping_rem_euclid(-1), 0); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem_euclid(self, rhs: Self) -> Self { + pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { self.overflowing_rem_euclid(rhs).0 } } @@ -1669,9 +1673,10 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (self, true) } else { @@ -1736,10 +1741,11 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (0, true) } else { @@ -1981,11 +1987,12 @@ assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2 assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2 ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn div_euclid(self, rhs: Self) -> Self { + pub const fn div_euclid(self, rhs: Self) -> Self { let q = self / rhs; if self % rhs < 0 { return if rhs > 0 { q - 1 } else { q + 1 } @@ -2020,11 +2027,12 @@ assert_eq!(a.rem_euclid(-b), 3); assert_eq!((-a).rem_euclid(-b), 1); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn rem_euclid(self, rhs: Self) -> Self { + pub const fn rem_euclid(self, rhs: Self) -> Self { let r = self % rhs; if r < 0 { if rhs < 0 { @@ -2939,10 +2947,11 @@ assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64)); assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div_euclid(self, rhs: Self) -> Option { + pub const fn checked_div_euclid(self, rhs: Self) -> Option { if rhs == 0 { None } else { @@ -2992,10 +3001,11 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1)); assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem_euclid(self, rhs: Self) -> Option { + pub const fn checked_rem_euclid(self, rhs: Self) -> Option { if rhs == 0 { None } else { @@ -3315,10 +3325,11 @@ Basic usage: assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div_euclid(self, rhs: Self) -> Self { + pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { self / rhs } } @@ -3366,10 +3377,11 @@ Basic usage: assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem_euclid(self, rhs: Self) -> Self { + pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { self % rhs } } @@ -3645,9 +3657,10 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false)); ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { (self / rhs, false) } } @@ -3704,9 +3717,10 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { (self % rhs, false) } } @@ -3897,11 +3911,12 @@ Basic usage: assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn div_euclid(self, rhs: Self) -> Self { + pub const fn div_euclid(self, rhs: Self) -> Self { self / rhs } } @@ -3926,11 +3941,12 @@ Basic usage: assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] + #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn rem_euclid(self, rhs: Self) -> Self { + pub const fn rem_euclid(self, rhs: Self) -> Self { self % rhs } } From 37c141885ac5972e7c858d65babe1753b0ad994c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 13:19:07 -0800 Subject: [PATCH 0886/1253] Make checked arithmetic besides division `const` Co-Authored-By: 9999years --- src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 39 ++++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4fc7caa62b5cd..78b1524f04f83 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -72,6 +72,7 @@ #![feature(concat_idents)] #![feature(const_alloc_layout)] #![feature(const_if_match)] +#![feature(const_int_checked)] #![feature(const_int_euclidean)] #![feature(const_panic)] #![feature(const_fn_union)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index ede568da3e5bd..91df649f121e7 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -701,10 +701,11 @@ assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_add(self, rhs: Self) -> Option { + pub const fn checked_add(self, rhs: Self) -> Option { let (a, b) = self.overflowing_add(rhs); if b {None} else {Some(a)} } @@ -725,10 +726,11 @@ assert_eq!((", stringify!($SelfT), "::min_value() + 2).checked_sub(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { + pub const fn checked_sub(self, rhs: Self) -> Option { let (a, b) = self.overflowing_sub(rhs); if b {None} else {Some(a)} } @@ -749,10 +751,11 @@ assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { + pub const fn checked_mul(self, rhs: Self) -> Option { let (a, b) = self.overflowing_mul(rhs); if b {None} else {Some(a)} } @@ -889,8 +892,9 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[inline] - pub fn checked_neg(self) -> Option { + pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); if b {None} else {Some(a)} } @@ -910,10 +914,11 @@ assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { + pub const fn checked_shl(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shl(rhs); if b {None} else {Some(a)} } @@ -933,10 +938,11 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { + pub const fn checked_shr(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shr(rhs); if b {None} else {Some(a)} } @@ -958,8 +964,9 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);", $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[inline] - pub fn checked_abs(self) -> Option { + pub const fn checked_abs(self) -> Option { if self.is_negative() { self.checked_neg() } else { @@ -2855,10 +2862,11 @@ Basic usage: assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_add(self, rhs: Self) -> Option { + pub const fn checked_add(self, rhs: Self) -> Option { let (a, b) = self.overflowing_add(rhs); if b {None} else {Some(a)} } @@ -2877,10 +2885,11 @@ Basic usage: assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { + pub const fn checked_sub(self, rhs: Self) -> Option { let (a, b) = self.overflowing_sub(rhs); if b {None} else {Some(a)} } @@ -2899,10 +2908,11 @@ Basic usage: assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { + pub const fn checked_mul(self, rhs: Self) -> Option { let (a, b) = self.overflowing_mul(rhs); if b {None} else {Some(a)} } @@ -3029,8 +3039,9 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[inline] - pub fn checked_neg(self) -> Option { + pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); if b {None} else {Some(a)} } @@ -3049,10 +3060,11 @@ Basic usage: assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { + pub const fn checked_shl(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shl(rhs); if b {None} else {Some(a)} } @@ -3071,10 +3083,11 @@ Basic usage: assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { + pub const fn checked_shr(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shr(rhs); if b {None} else {Some(a)} } From de52a541d5daab8393d4da8a9508fb7b5c1448e0 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 12:45:51 -0800 Subject: [PATCH 0887/1253] Make overflowing arithmetic `const` Co-Authored-By: 9999years --- src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 78b1524f04f83..f8857b9d73377 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -74,6 +74,7 @@ #![feature(const_if_match)] #![feature(const_int_checked)] #![feature(const_int_euclidean)] +#![feature(const_int_overflowing)] #![feature(const_panic)] #![feature(const_fn_union)] #![feature(const_generics)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 91df649f121e7..690a07ce68090 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1646,9 +1646,10 @@ $EndFeature, " ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (self, true) } else { @@ -1715,9 +1716,10 @@ $EndFeature, " ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (0, true) } else { @@ -3639,9 +3641,10 @@ Basic usage ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { (self / rhs, false) } } @@ -3699,9 +3702,10 @@ Basic usage ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { (self % rhs, false) } } From b422a19c4323e54f635e6d6aa7fc9900ce9f25a6 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 13:16:38 -0800 Subject: [PATCH 0888/1253] Make `saturating_mul` a `const fn` Co-Authored-By: 9999years --- src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f8857b9d73377..76e3d0d32997f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -75,6 +75,7 @@ #![feature(const_int_checked)] #![feature(const_int_euclidean)] #![feature(const_int_overflowing)] +#![feature(const_int_saturating)] #![feature(const_panic)] #![feature(const_fn_union)] #![feature(const_generics)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 690a07ce68090..1dccc87dd18b2 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1142,17 +1142,19 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($Self $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(rhs).unwrap_or_else(|| { - if (self < 0) == (rhs < 0) { + pub const fn saturating_mul(self, rhs: Self) -> Self { + match self.checked_mul(rhs) { + Some(x) => x, + None => if (self < 0) == (rhs < 0) { Self::max_value() } else { Self::min_value() } - }) + } } } @@ -3195,11 +3197,15 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se "::MAX);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(rhs).unwrap_or(Self::max_value()) + pub const fn saturating_mul(self, rhs: Self) -> Self { + match self.checked_mul(rhs) { + Some(x) => x, + None => Self::max_value(), + } } } From b46d1d27184bf78cc9181feadd192e887fe7d589 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 12:53:34 -0800 Subject: [PATCH 0889/1253] Make wrapping arithmetic `const` Co-Authored-By: 9999years --- src/libcore/num/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 1dccc87dd18b2..004e91c0eb3a6 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1280,10 +1280,11 @@ assert_eq!((-128i8).wrapping_div(-1), -128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] + #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { + pub const fn wrapping_div(self, rhs: Self) -> Self { self.overflowing_div(rhs).0 } } @@ -1340,10 +1341,11 @@ assert_eq!((-128i8).wrapping_rem(-1), 0);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] + #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { + pub const fn wrapping_rem(self, rhs: Self) -> Self { self.overflowing_rem(rhs).0 } } @@ -3320,10 +3322,11 @@ Basic usage: ", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] + #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { + pub const fn wrapping_div(self, rhs: Self) -> Self { self / rhs } } @@ -3371,10 +3374,11 @@ Basic usage: ", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] + #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { + pub const fn wrapping_rem(self, rhs: Self) -> Self { self % rhs } } From d4529bec02f5e61a6684ee8ffc40d84d35c23242 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 12:49:31 -0800 Subject: [PATCH 0890/1253] Const-stabilize some arithmetic intrinsics --- src/libcore/intrinsics.rs | 5 +++++ src/libcore/lib.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 416c73f50bd89..2cee23a5c752c 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1305,9 +1305,11 @@ extern "rust-intrinsic" { /// Performs an unchecked division, resulting in undefined behavior /// where y = 0 or x = `T::min_value()` and y = -1 + #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] pub fn unchecked_div(x: T, y: T) -> T; /// Returns the remainder of an unchecked division, resulting in /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1 + #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] pub fn unchecked_rem(x: T, y: T) -> T; /// Performs an unchecked left shift, resulting in undefined behavior when @@ -1321,14 +1323,17 @@ extern "rust-intrinsic" { /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`. + #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] pub fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked subtraction, resulting in /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`. + #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] pub fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`. + #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] pub fn unchecked_mul(x: T, y: T) -> T; /// Performs rotate left. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 76e3d0d32997f..b5baa42fdb3fc 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -76,6 +76,7 @@ #![feature(const_int_euclidean)] #![feature(const_int_overflowing)] #![feature(const_int_saturating)] +#![feature(const_int_unchecked_arith)] #![feature(const_panic)] #![feature(const_fn_union)] #![feature(const_generics)] From 526304da1621f6cd718a29d05a058de2beac954e Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 13:19:32 -0800 Subject: [PATCH 0891/1253] Make checked division `const` --- src/libcore/num/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 004e91c0eb3a6..f590c6bc7c285 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -777,10 +777,11 @@ assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div(self, rhs: Self) -> Option { + pub const fn checked_div(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -835,10 +836,11 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem(self, rhs: Self) -> Option { + pub const fn checked_rem(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -2937,10 +2939,11 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div(self, rhs: Self) -> Option { + pub const fn checked_div(self, rhs: Self) -> Option { match rhs { 0 => None, // SAFETY: div by zero has been checked above and unsigned types have no other @@ -2990,10 +2993,11 @@ Basic usage: assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem(self, rhs: Self) -> Option { + pub const fn checked_rem(self, rhs: Self) -> Option { if rhs == 0 { None } else { From dda015aebca79d508b74cae6a0ecfb0a093d8639 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 13:17:13 -0800 Subject: [PATCH 0892/1253] Make saturating arithmetic using intrinsics `const` --- src/libcore/num/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f590c6bc7c285..38989004f9147 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1091,8 +1091,9 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] + #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] #[inline] - pub fn saturating_neg(self) -> Self { + pub const fn saturating_neg(self) -> Self { intrinsics::saturating_sub(0, self) } } @@ -1117,8 +1118,9 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] + #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] #[inline] - pub fn saturating_abs(self) -> Self { + pub const fn saturating_abs(self) -> Self { if self.is_negative() { self.saturating_neg() } else { From 3e9fd80bd7c0b3aeb700c474edd93a078f822dbc Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 3 Feb 2020 14:23:21 -0800 Subject: [PATCH 0893/1253] Add tests for newly const arithmetic fns Co-Authored-By: 9999years --- src/test/ui/consts/const-int-arithmetic.rs | 166 +++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/test/ui/consts/const-int-arithmetic.rs diff --git a/src/test/ui/consts/const-int-arithmetic.rs b/src/test/ui/consts/const-int-arithmetic.rs new file mode 100644 index 0000000000000..703f21a3f2952 --- /dev/null +++ b/src/test/ui/consts/const-int-arithmetic.rs @@ -0,0 +1,166 @@ +// run-pass + +#![feature(const_int_checked)] +#![feature(const_int_euclidean)] +#![feature(const_int_overflowing)] +#![feature(const_int_saturating)] +#![feature(const_int_wrapping)] + +macro_rules! assert_same_const { + ($(const $ident:ident: $ty:ty = $exp:expr;)+) => { + $(const $ident: $ty = $exp;)+ + + pub fn main() { + $(assert_eq!($exp, $ident);)+ + } + } +} + +assert_same_const! { + // `const_int_checked` + const CHECKED_ADD_I32_A: Option = 5i32.checked_add(2); + const CHECKED_ADD_I8_A: Option = 127i8.checked_add(2); + const CHECKED_ADD_U8_A: Option = 255u8.checked_add(2); + + const CHECKED_SUB_I32_A: Option = 5i32.checked_sub(2); + const CHECKED_SUB_I8_A: Option = (-127 as i8).checked_sub(2); + const CHECKED_SUB_U8_A: Option = 1u8.checked_sub(2); + + const CHECKED_MUL_I32_A: Option = 5i32.checked_mul(7777); + const CHECKED_MUL_I8_A: Option = (-127 as i8).checked_mul(-99); + const CHECKED_MUL_U8_A: Option = 1u8.checked_mul(3); + + const CHECKED_DIV_I32_A: Option = 5i32.checked_div(7777); + const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div(-99); + const CHECKED_DIV_U8_A: Option = 1u8.checked_div(3); + + const CHECKED_REM_I32_A: Option = 5i32.checked_rem(7777); + const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem(-99); + const CHECKED_REM_U8_A: Option = 1u8.checked_rem(3); + const CHECKED_REM_U8_B: Option = 1u8.checked_rem(0); + + const CHECKED_NEG_I32_A: Option = 5i32.checked_neg(); + const CHECKED_NEG_I8_A: Option = (-127 as i8).checked_neg(); + const CHECKED_NEG_U8_A: Option = 1u8.checked_neg(); + const CHECKED_NEG_U8_B: Option = u8::min_value().checked_neg(); + + const CHECKED_SHL_I32_A: Option = 5i32.checked_shl(77777); + const CHECKED_SHL_I8_A: Option = (-127 as i8).checked_shl(2); + const CHECKED_SHL_U8_A: Option = 1u8.checked_shl(8); + const CHECKED_SHL_U8_B: Option = 1u8.checked_shl(0); + + const CHECKED_SHR_I32_A: Option = 5i32.checked_shr(77777); + const CHECKED_SHR_I8_A: Option = (-127 as i8).checked_shr(2); + const CHECKED_SHR_U8_A: Option = 1u8.checked_shr(8); + const CHECKED_SHR_U8_B: Option = 1u8.checked_shr(0); + + const CHECKED_ABS_I32_A: Option = 5i32.checked_abs(); + const CHECKED_ABS_I8_A: Option = (-127 as i8).checked_abs(); + const CHECKED_ABS_I8_B: Option = 1i8.checked_abs(); + const CHECKED_ABS_I8_C: Option = i8::min_value().checked_abs(); + + // `const_int_overflowing` + const DIV_A: (i8, bool) = 8i8.overflowing_div(2); + const DIV_B: (i8, bool) = 8i8.overflowing_div(3); + const DIV_C: (i8, bool) = i8::min_value().overflowing_div(-1i8); + const DIV_D: (u8, bool) = 8u8.overflowing_div(2); + const DIV_E: (u8, bool) = 8u8.overflowing_div(3); + + const REM_A: (i8, bool) = 8i8.overflowing_rem(2); + const REM_B: (i8, bool) = 8i8.overflowing_rem(3); + const REM_C: (i8, bool) = i8::min_value().overflowing_rem(-1i8); + const REM_D: (u8, bool) = 8u8.overflowing_rem(2); + const REM_E: (u8, bool) = 8u8.overflowing_rem(3); + + // `const_int_saturating` + const ADD_INT_U32_NO: u32 = (42 as u32).saturating_add(2); + const ADD_INT_U32: u32 = u32::max_value().saturating_add(1); + const ADD_INT_U128: u128 = u128::max_value().saturating_add(1); + const ADD_INT_I128: i128 = i128::max_value().saturating_add(1); + const ADD_INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); + + const SUB_INT_U32_NO: u32 = (42 as u32).saturating_sub(2); + const SUB_INT_U32: u32 = (1 as u32).saturating_sub(2); + const SUB_INT_I32_NO: i32 = (-42 as i32).saturating_sub(2); + const SUB_INT_I32_NEG: i32 = i32::min_value().saturating_sub(1); + const SUB_INT_I32_POS: i32 = i32::max_value().saturating_sub(-1); + const SUB_INT_U128: u128 = (0 as u128).saturating_sub(1); + const SUB_INT_I128_NEG: i128 = i128::min_value().saturating_sub(1); + const SUB_INT_I128_POS: i128 = i128::max_value().saturating_sub(-1); + + const MUL_INT_U32_NO: u32 = (42 as u32).saturating_mul(2); + const MUL_INT_U32: u32 = (1 as u32).saturating_mul(2); + const MUL_INT_I32_NO: i32 = (-42 as i32).saturating_mul(2); + const MUL_INT_I32_NEG: i32 = i32::min_value().saturating_mul(1); + const MUL_INT_I32_POS: i32 = i32::max_value().saturating_mul(2); + const MUL_INT_U128: u128 = (0 as u128).saturating_mul(1); + const MUL_INT_I128_NEG: i128 = i128::min_value().saturating_mul(2); + const MUL_INT_I128_POS: i128 = i128::max_value().saturating_mul(2); + + const NEG_INT_I8: i8 = (-42i8).saturating_neg(); + const NEG_INT_I8_B: i8 = i8::min_value().saturating_neg(); + const NEG_INT_I32: i32 = i32::min_value().saturating_neg(); + const NEG_INT_I32_B: i32 = i32::max_value().saturating_neg(); + const NEG_INT_I128: i128 = i128::min_value().saturating_neg(); + const NEG_INT_I128_B: i128 = i128::max_value().saturating_neg(); + + const ABS_INT_I8_A: i8 = 4i8.saturating_abs(); + const ABS_INT_I8_B: i8 = -4i8.saturating_abs(); + const ABS_INT_I8_C: i8 = i8::min_value().saturating_abs(); + const ABS_INT_I32_A: i32 = 4i32.saturating_abs(); + const ABS_INT_I32_B: i32 = -4i32.saturating_abs(); + const ABS_INT_I32_C: i32 = i32::min_value().saturating_abs(); + const ABS_INT_I128_A: i128 = 4i128.saturating_abs(); + const ABS_INT_I128_B: i128 = -4i128.saturating_abs(); + const ABS_INT_I128_C: i128 = i128::min_value().saturating_abs(); + + // `const_int_euclidean` + const CHECKED_DIV_I32_A: Option = 5i32.checked_div_euclid(7777); + const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div_euclid(-99); + const CHECKED_DIV_I8_B: Option = (-127 as i8).checked_div_euclid(1); + const CHECKED_DIV_I8_C: Option = i8::min_value().checked_div_euclid(-1); + const CHECKED_DIV_U8_A: Option = 1u8.checked_div_euclid(3); + + const CHECKED_REM_I32_A: Option = 5i32.checked_rem_euclid(7777); + const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem_euclid(-99); + const CHECKED_REM_I8_B: Option = (-127 as i8).checked_rem_euclid(0); + const CHECKED_REM_I8_C: Option = i8::min_value().checked_rem_euclid(-1); + const CHECKED_REM_U8_A: Option = 1u8.checked_rem_euclid(3); + + const WRAPPING_DIV_I32_A: i32 = 5i32.wrapping_div_euclid(7777); + const WRAPPING_DIV_I8_A: i8 = (-127 as i8).wrapping_div_euclid(-99); + const WRAPPING_DIV_I8_B: i8 = (-127 as i8).wrapping_div_euclid(1); + const WRAPPING_DIV_I8_C: i8 = i8::min_value().wrapping_div_euclid(-1); + const WRAPPING_DIV_U8_A: u8 = 1u8.wrapping_div_euclid(3); + + const WRAPPING_REM_I32_A: i32 = 5i32.wrapping_rem_euclid(7777); + const WRAPPING_REM_I8_A: i8 = (-127 as i8).wrapping_rem_euclid(-99); + const WRAPPING_REM_I8_B: i8 = (-127 as i8).wrapping_rem_euclid(1); + const WRAPPING_REM_I8_C: i8 = i8::min_value().wrapping_rem_euclid(-1); + const WRAPPING_REM_U8_A: u8 = 1u8.wrapping_rem_euclid(3); + + const OVERFLOWING_DIV_I32_A: (i32, bool) = 5i32.overflowing_div_euclid(7777); + const OVERFLOWING_DIV_I8_A: (i8, bool) = (-127 as i8).overflowing_div_euclid(-99); + const OVERFLOWING_DIV_I8_B: (i8, bool) = (-127 as i8).overflowing_div_euclid(1); + const OVERFLOWING_DIV_I8_C: (i8, bool) = i8::min_value().overflowing_div_euclid(-1); + const OVERFLOWING_DIV_U8_A: (u8, bool) = 1u8.overflowing_div_euclid(3); + + const OVERFLOWING_REM_I32_A: (i32, bool) = 5i32.overflowing_rem_euclid(7777); + const OVERFLOWING_REM_I8_A: (i8, bool) = (-127 as i8).overflowing_rem_euclid(-99); + const OVERFLOWING_REM_I8_B: (i8, bool) = (-127 as i8).overflowing_rem_euclid(1); + const OVERFLOWING_REM_I8_C: (i8, bool) = i8::min_value().overflowing_rem_euclid(-1); + const OVERFLOWING_REM_U8_A: (u8, bool) = 1u8.overflowing_rem_euclid(3); + + // `const_int_wrapping` + const DIV_A: i8 = 8i8.wrapping_div(2); + const DIV_B: i8 = 8i8.wrapping_div(3); + const DIV_C: i8 = i8::min_value().wrapping_div(-1i8); + const DIV_D: u8 = 8u8.wrapping_div(2); + const DIV_E: u8 = 8u8.wrapping_div(3); + + const REM_A: i8 = 8i8.wrapping_rem(2); + const REM_B: i8 = 8i8.wrapping_rem(3); + const REM_C: i8 = i8::min_value().wrapping_rem(-1i8); + const REM_D: u8 = 8u8.wrapping_rem(2); + const REM_E: u8 = 8u8.wrapping_rem(3); +} From 11eee614f0bf275bd14566457203ba917fe5debd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 4 Feb 2020 22:03:54 +0100 Subject: [PATCH 0894/1253] Clean up E0264, E0267 and E0268 explanations --- src/librustc_error_codes/error_codes/E0264.md | 4 +++- src/librustc_error_codes/error_codes/E0267.md | 6 ++++-- src/librustc_error_codes/error_codes/E0268.md | 7 ++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0264.md b/src/librustc_error_codes/error_codes/E0264.md index e1e7516cec2c7..708eac8837a7c 100644 --- a/src/librustc_error_codes/error_codes/E0264.md +++ b/src/librustc_error_codes/error_codes/E0264.md @@ -1,4 +1,6 @@ -An unknown external lang item was used. Erroneous code example: +An unknown external lang item was used. + +Erroneous code example: ```compile_fail,E0264 #![feature(lang_items)] diff --git a/src/librustc_error_codes/error_codes/E0267.md b/src/librustc_error_codes/error_codes/E0267.md index 066ebee0ffb74..951490df87403 100644 --- a/src/librustc_error_codes/error_codes/E0267.md +++ b/src/librustc_error_codes/error_codes/E0267.md @@ -1,5 +1,7 @@ -This error indicates the use of a loop keyword (`break` or `continue`) inside a -closure but outside of any loop. Erroneous code example: +A loop keyword (`break` or `continue`) was used inside a closure but outside of +any loop. + +Erroneous code example: ```compile_fail,E0267 let w = || { break; }; // error: `break` inside of a closure diff --git a/src/librustc_error_codes/error_codes/E0268.md b/src/librustc_error_codes/error_codes/E0268.md index 7f3ac1186018a..436aef79fe0b3 100644 --- a/src/librustc_error_codes/error_codes/E0268.md +++ b/src/librustc_error_codes/error_codes/E0268.md @@ -1,6 +1,6 @@ -This error indicates the use of a loop keyword (`break` or `continue`) outside -of a loop. Without a loop to break out of or continue in, no sensible action can -be taken. Erroneous code example: +A loop keyword (`break` or `continue`) was used outside of a loop. + +Erroneous code example: ```compile_fail,E0268 fn some_func() { @@ -8,6 +8,7 @@ fn some_func() { } ``` +Without a loop to break out of or continue in, no sensible action can be taken. Please verify that you are using `break` and `continue` only in loops. Example: ``` From fa9bfebfc9256369c03cbe8bba2e737de3cb38fc Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 4 Feb 2020 22:19:05 +0100 Subject: [PATCH 0895/1253] Fix and test implementation of BTreeMap's first_entry, last_entry, pop_first, pop_last --- src/liballoc/collections/btree/map.rs | 24 ++++++++++++++---------- src/liballoc/tests/btree/map.rs | 5 +++++ src/liballoc/tests/btree/set.rs | 27 ++++++++++++++++----------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 8eabc1773042f..c1778f2065d40 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -675,13 +675,15 @@ impl BTreeMap { T: Ord, K: Borrow, { - match self.length { - 0 => None, - _ => Some(OccupiedEntry { - handle: self.root.as_mut().first_kv(), + let front = self.root.as_mut().first_leaf_edge(); + if let Ok(kv) = front.right_kv() { + Some(OccupiedEntry { + handle: kv.forget_node_type(), length: &mut self.length, _marker: PhantomData, - }), + }) + } else { + None } } @@ -736,13 +738,15 @@ impl BTreeMap { T: Ord, K: Borrow, { - match self.length { - 0 => None, - _ => Some(OccupiedEntry { - handle: self.root.as_mut().last_kv(), + let back = self.root.as_mut().last_leaf_edge(); + if let Ok(kv) = back.left_kv() { + Some(OccupiedEntry { + handle: kv.forget_node_type(), length: &mut self.length, _marker: PhantomData, - }), + }) + } else { + None } } diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 0d009507fc7aa..0a26d7bf427ab 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -23,6 +23,11 @@ fn test_basic_large() { assert_eq!(map.len(), i + 1); } + assert_eq!(map.first_key_value(), Some((&0, &0))); + assert_eq!(map.last_key_value(), Some((&(size - 1), &(10 * (size - 1))))); + assert_eq!(map.first_entry().unwrap().key(), &0); + assert_eq!(map.last_entry().unwrap().key(), &(size - 1)); + for i in 0..size { assert_eq!(map.get(&i).unwrap(), &(i * 10)); } diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index 265ef758cc5bc..1a2b62d026b2e 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -487,21 +487,26 @@ fn test_first_last() { a.insert(2); assert_eq!(a.first(), Some(&1)); assert_eq!(a.last(), Some(&2)); - a.insert(3); + for i in 3..=12 { + a.insert(i); + } assert_eq!(a.first(), Some(&1)); - assert_eq!(a.last(), Some(&3)); - - assert_eq!(a.len(), 3); + assert_eq!(a.last(), Some(&12)); assert_eq!(a.pop_first(), Some(1)); - assert_eq!(a.len(), 2); - assert_eq!(a.pop_last(), Some(3)); - assert_eq!(a.len(), 1); + assert_eq!(a.pop_last(), Some(12)); assert_eq!(a.pop_first(), Some(2)); - assert_eq!(a.len(), 0); - assert_eq!(a.pop_last(), None); - assert_eq!(a.len(), 0); + assert_eq!(a.pop_last(), Some(11)); + assert_eq!(a.pop_first(), Some(3)); + assert_eq!(a.pop_last(), Some(10)); + assert_eq!(a.pop_first(), Some(4)); + assert_eq!(a.pop_first(), Some(5)); + assert_eq!(a.pop_first(), Some(6)); + assert_eq!(a.pop_first(), Some(7)); + assert_eq!(a.pop_first(), Some(8)); + assert_eq!(a.clone().pop_last(), Some(9)); + assert_eq!(a.pop_first(), Some(9)); assert_eq!(a.pop_first(), None); - assert_eq!(a.len(), 0); + assert_eq!(a.pop_last(), None); } fn rand_data(len: usize) -> Vec { From c0a110f7e6b8f8eab2d5c8c9cfc3e86c37ef2fd8 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 4 Feb 2020 17:08:50 -0500 Subject: [PATCH 0896/1253] use def_path_str for missing_debug_impls message The lint message will now use the full, correct path to the `Debug` trait, even in `no_std`. --- src/librustc_lint/builtin.rs | 11 +++++++---- src/test/ui/missing_debug_impls.rs | 4 ++-- src/test/ui/missing_debug_impls.stderr | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 345665de63c3c..154b1608dcc7f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -567,7 +567,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { declare_lint! { MISSING_DEBUG_IMPLEMENTATIONS, Allow, - "detects missing implementations of fmt::Debug" + "detects missing implementations of Debug" } #[derive(Default)] @@ -611,9 +611,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { cx.span_lint( MISSING_DEBUG_IMPLEMENTATIONS, item.span, - "type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` \ - or a manual implementation", - ) + &format!( + "type does not implement `{}`; consider adding `#[derive(Debug)]` \ + or a manual implementation", + cx.tcx.def_path_str(debug) + ), + ); } } } diff --git a/src/test/ui/missing_debug_impls.rs b/src/test/ui/missing_debug_impls.rs index ff919292ae244..72fcba51588b4 100644 --- a/src/test/ui/missing_debug_impls.rs +++ b/src/test/ui/missing_debug_impls.rs @@ -4,7 +4,7 @@ use std::fmt; -pub enum A {} //~ ERROR type does not implement `fmt::Debug` +pub enum A {} //~ ERROR type does not implement `std::fmt::Debug` #[derive(Debug)] pub enum B {} @@ -17,7 +17,7 @@ impl fmt::Debug for C { } } -pub struct Foo; //~ ERROR type does not implement `fmt::Debug` +pub struct Foo; //~ ERROR type does not implement `std::fmt::Debug` #[derive(Debug)] pub struct Bar; diff --git a/src/test/ui/missing_debug_impls.stderr b/src/test/ui/missing_debug_impls.stderr index 5f8adb791f687..51c65589b0cc0 100644 --- a/src/test/ui/missing_debug_impls.stderr +++ b/src/test/ui/missing_debug_impls.stderr @@ -1,4 +1,4 @@ -error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation +error: type does not implement `std::fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> $DIR/missing_debug_impls.rs:7:1 | LL | pub enum A {} @@ -10,7 +10,7 @@ note: the lint level is defined here LL | #![deny(missing_debug_implementations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation +error: type does not implement `std::fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> $DIR/missing_debug_impls.rs:20:1 | LL | pub struct Foo; From 1fad337f79a6a554ae947def38ec2db0e91d864c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 13 Dec 2019 19:45:04 +0100 Subject: [PATCH 0897/1253] Prefer system MinGW libs when available --- src/librustc_codegen_ssa/back/link.rs | 78 +++++++++++++++++++++++++++ src/librustc_session/session.rs | 5 ++ 2 files changed, 83 insertions(+) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index f56a4170c0a4b..c2daf6590731d 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -968,7 +968,78 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary } } +// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles +// own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64 +// installed in the system. This breaks many cases where Rust is mixed with other languages +// (e.g. *-sys crates). +// We prefer system mingw-w64 libraries if they are available to avoid this issue. +fn get_crt_libs_path(sess: &Session) -> Option { + fn find_exe_in_path

(exe_name: P) -> Option + where + P: AsRef, + { + for dir in env::split_paths(&env::var_os("PATH")?) { + let full_path = dir.join(&exe_name); + if full_path.is_file() { + return Some(fix_windows_verbatim_for_gcc(&full_path)); + } + } + None + } + + fn probe(sess: &Session) -> Option { + if let (linker, LinkerFlavor::Gcc) = linker_and_flavor(&sess) { + let linker_path = if cfg!(windows) && linker.extension().is_none() { + linker.with_extension("exe") + } else { + linker + }; + if let Some(linker_path) = find_exe_in_path(linker_path) { + let mingw_arch = match &sess.target.target.arch { + x if x == "x86" => "i686", + x => x, + }; + let mingw_dir = format!("{}-w64-mingw32", mingw_arch); + // Here we have path/bin/gcc but we need path/ + let mut path = linker_path; + path.pop(); + path.pop(); + // Based on Clang MinGW driver + let probe_path = path.join(&mingw_dir).join("lib"); + if probe_path.exists() { + return Some(probe_path); + }; + let probe_path = path.join(&mingw_dir).join("sys-root/mingw/lib"); + if probe_path.exists() { + return Some(probe_path); + }; + }; + }; + None + } + + let mut system_library_path = sess.system_library_path.borrow_mut(); + match &*system_library_path { + Some(Some(compiler_libs_path)) => Some(compiler_libs_path.clone()), + Some(None) => None, + None => { + let path = probe(sess); + *system_library_path = Some(path.clone()); + path + } + } +} + pub fn get_file_path(sess: &Session, name: &str) -> PathBuf { + // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details + if sess.target.target.llvm_target.contains("windows-gnu") { + if let Some(compiler_libs_path) = get_crt_libs_path(sess) { + let file_path = compiler_libs_path.join(name); + if file_path.exists() { + return file_path; + } + } + } let fs = sess.target_filesearch(PathKind::Native); let file_path = fs.get_lib_path().join(name); if file_path.exists() { @@ -1150,6 +1221,13 @@ fn link_args<'a, B: ArchiveBuilder<'a>>( // target descriptor let t = &sess.target.target; + // prefer system mingw-w64 libs, see get_crt_libs_path comment for more details + if cfg!(windows) && sess.target.target.llvm_target.contains("windows-gnu") { + if let Some(compiler_libs_path) = get_crt_libs_path(sess) { + cmd.include_path(&compiler_libs_path); + } + } + cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index a40d6451b958c..db1e95fe0b68b 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -133,6 +133,10 @@ pub struct Session { /// Mapping from ident span to path span for paths that don't exist as written, but that /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`. pub confused_type_with_std_module: Lock>, + + /// Path for libraries that will take preference over libraries shipped by Rust. + /// Used by windows-gnu targets to priortize system mingw-w64 libraries. + pub system_library_path: OneThread>>>, } pub struct PerfStats { @@ -1069,6 +1073,7 @@ fn build_session_( driver_lint_caps, trait_methods_not_found: Lock::new(Default::default()), confused_type_with_std_module: Lock::new(Default::default()), + system_library_path: OneThread::new(RefCell::new(Default::default())), }; validate_commandline_args_with_session_available(&sess); From c0b7b41cff2b40d430befefc8688fb8ad847bcd4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 29 Jan 2020 01:57:24 +0100 Subject: [PATCH 0898/1253] parse_ty_common: use `enum`s instead of `bool`s. --- src/librustc_parse/parser/diagnostics.rs | 9 ++-- src/librustc_parse/parser/expr.rs | 3 +- src/librustc_parse/parser/item.rs | 7 +-- src/librustc_parse/parser/path.rs | 3 +- src/librustc_parse/parser/ty.rs | 59 ++++++++++++++++-------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index b1cab591fd97c..5f148fa6ba2d3 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,3 +1,4 @@ +use super::ty::AllowPlus; use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType}; use rustc_ast_pretty::pprust; @@ -693,11 +694,11 @@ impl<'a> Parser<'a> { pub(super) fn maybe_report_ambiguous_plus( &mut self, - allow_plus: bool, + allow_plus: AllowPlus, impl_dyn_multi: bool, ty: &Ty, ) { - if !allow_plus && impl_dyn_multi { + if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi { let sum_with_parens = format!("({})", pprust::ty_to_string(&ty)); self.struct_span_err(ty.span, "ambiguous `+` in a type") .span_suggestion( @@ -712,11 +713,11 @@ impl<'a> Parser<'a> { pub(super) fn maybe_recover_from_bad_type_plus( &mut self, - allow_plus: bool, + allow_plus: AllowPlus, ty: &Ty, ) -> PResult<'a, ()> { // Do not add `+` to expected tokens. - if !allow_plus || !self.token.is_like_plus() { + if matches!(allow_plus, AllowPlus::No) || !self.token.is_like_plus() { return Ok(()); } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 0d12f8cf6c039..d98321416957d 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1,4 +1,5 @@ use super::pat::{GateOr, PARAM_EXPECTED}; +use super::ty::{AllowPlus, RecoverQPath}; use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; @@ -1399,7 +1400,7 @@ impl<'a> Parser<'a> { self.expect_or()?; args }; - let output = self.parse_ret_ty(true, true)?; + let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes)?; Ok(P(FnDecl { inputs, output })) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index b7f299e56ae50..87a6aa76f5777 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1,4 +1,5 @@ use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error}; +use super::ty::{AllowPlus, RecoverQPath}; use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; @@ -1839,7 +1840,7 @@ impl<'a> Parser<'a> { fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P, Generics)> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let decl = self.parse_fn_decl(cfg, true)?; + let decl = self.parse_fn_decl(cfg, AllowPlus::Yes)?; generics.where_clause = self.parse_where_clause()?; Ok((ident, decl, generics)) } @@ -1848,11 +1849,11 @@ impl<'a> Parser<'a> { pub(super) fn parse_fn_decl( &mut self, cfg: &ParamCfg, - ret_allow_plus: bool, + ret_allow_plus: AllowPlus, ) -> PResult<'a, P> { Ok(P(FnDecl { inputs: self.parse_fn_params(cfg)?, - output: self.parse_ret_ty(ret_allow_plus, true)?, + output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes)?, })) } diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index a09eb42dcfe6a..cb14ffb4bd028 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -1,3 +1,4 @@ +use super::ty::{AllowPlus, RecoverQPath}; use super::{Parser, TokenType}; use crate::maybe_whole; use rustc_errors::{pluralize, Applicability, PResult}; @@ -224,7 +225,7 @@ impl<'a> Parser<'a> { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; let span = ident.span.to(self.prev_span); - let output = self.parse_ret_ty(false, false)?; + let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No)?; ParenthesizedArgs { inputs, output, span }.into() }; diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index c9c2cbb98ca40..1ed80ed7350a9 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -36,6 +36,23 @@ impl BoundModifiers { } } +#[derive(Copy, Clone)] +pub(super) enum AllowPlus { + Yes, + No, +} + +pub(super) enum RecoverQPath { + Yes, + No, +} + +// Is `...` (`CVarArgs`) legal at this level of type parsing? +enum AllowCVariadic { + Yes, + No, +} + /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, /// `IDENT<::AssocTy>`. /// @@ -48,14 +65,14 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { impl<'a> Parser<'a> { /// Parses a type. pub fn parse_ty(&mut self) -> PResult<'a, P> { - self.parse_ty_common(true, true, false) + self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::No) } /// Parse a type suitable for a function or function pointer parameter. /// The difference from `parse_ty` is that this version allows `...` /// (`CVarArgs`) at the top level of the the type. pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P> { - self.parse_ty_common(true, true, true) + self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::Yes) } /// Parses a type in restricted contexts where `+` is not permitted. @@ -65,18 +82,19 @@ impl<'a> Parser<'a> { /// Example 2: `value1 as TYPE + value2` /// `+` is prohibited to avoid interactions with expression grammar. pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P> { - self.parse_ty_common(false, true, false) + self.parse_ty_common(AllowPlus::No, RecoverQPath::Yes, AllowCVariadic::No) } /// Parses an optional return type `[ -> TY ]` in a function declaration. pub(super) fn parse_ret_ty( &mut self, - allow_plus: bool, - allow_qpath_recovery: bool, + allow_plus: AllowPlus, + recover_qpath: RecoverQPath, ) -> PResult<'a, FunctionRetTy> { Ok(if self.eat(&token::RArrow) { // FIXME(Centril): Can we unconditionally `allow_plus`? - FunctionRetTy::Ty(self.parse_ty_common(allow_plus, allow_qpath_recovery, false)?) + let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; + FunctionRetTy::Ty(ty) } else { FunctionRetTy::Default(self.token.span.shrink_to_lo()) }) @@ -84,11 +102,11 @@ impl<'a> Parser<'a> { fn parse_ty_common( &mut self, - allow_plus: bool, - allow_qpath_recovery: bool, - // Is `...` (`CVarArgs`) legal in the immediate top level call? - allow_c_variadic: bool, + allow_plus: AllowPlus, + recover_qpath: RecoverQPath, + allow_c_variadic: AllowCVariadic, ) -> PResult<'a, P> { + let allow_qpath_recovery = matches!(recover_qpath, RecoverQPath::Yes); maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); maybe_whole!(self, NtTy, |x| x); @@ -124,7 +142,7 @@ impl<'a> Parser<'a> { self.parse_ty_bare_fn(lifetime_defs)? } else { let path = self.parse_path(PathStyle::Type)?; - let parse_plus = allow_plus && self.check_plus(); + let parse_plus = matches!(allow_plus, AllowPlus::Yes) && self.check_plus(); self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)? } } else if self.eat_keyword(kw::Impl) { @@ -144,7 +162,7 @@ impl<'a> Parser<'a> { } else if self.token.is_path_start() { self.parse_path_start_ty(lo, allow_plus)? } else if self.eat(&token::DotDotDot) { - if allow_c_variadic { + if let AllowCVariadic::Yes = allow_c_variadic { TyKind::CVarArgs } else { // FIXME(Centril): Should we just allow `...` syntactically @@ -172,7 +190,7 @@ impl<'a> Parser<'a> { /// Parses either: /// - `(TYPE)`, a parenthesized type. /// - `(TYPE,)`, a tuple with a single field of type TYPE. - fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> { + fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { let mut trailing_plus = false; let (ts, trailing) = self.parse_paren_comma_seq(|p| { let ty = p.parse_ty()?; @@ -182,7 +200,7 @@ impl<'a> Parser<'a> { if ts.len() == 1 && !trailing { let ty = ts.into_iter().nth(0).unwrap().into_inner(); - let maybe_bounds = allow_plus && self.token.is_like_plus(); + let maybe_bounds = matches!(allow_plus, AllowPlus::Yes) && self.token.is_like_plus(); match ty.kind { // `(TY_BOUND_NOPAREN) + BOUND + ...`. TyKind::Path(None, path) if maybe_bounds => { @@ -288,7 +306,8 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); let ext = self.parse_extern()?; self.expect_keyword(kw::Fn)?; - let decl = self.parse_fn_decl(&ParamCfg { is_name_required: |_| false }, false)?; + let cfg = ParamCfg { is_name_required: |_| false }; + let decl = self.parse_fn_decl(&cfg, AllowPlus::No)?; Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl }))) } @@ -326,7 +345,7 @@ impl<'a> Parser<'a> { /// 1. a type macro, `mac!(...)`, /// 2. a bare trait object, `B0 + ... + Bn`, /// 3. or a path, `path::to::MyType`. - fn parse_path_start_ty(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> { + fn parse_path_start_ty(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { // Simple path let path = self.parse_path(PathStyle::Type)?; if self.eat(&token::Not) { @@ -336,7 +355,7 @@ impl<'a> Parser<'a> { args: self.parse_mac_args()?, prior_type_ascription: self.last_type_ascription, })) - } else if allow_plus && self.check_plus() { + } else if matches!(allow_plus, AllowPlus::Yes) && self.check_plus() { // `Trait1 + Trait2 + 'a` self.parse_remaining_bounds(Vec::new(), path, lo, true) } else { @@ -359,7 +378,7 @@ impl<'a> Parser<'a> { &mut self, colon_span: Option, ) -> PResult<'a, GenericBounds> { - self.parse_generic_bounds_common(true, colon_span) + self.parse_generic_bounds_common(AllowPlus::Yes, colon_span) } /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`. @@ -367,7 +386,7 @@ impl<'a> Parser<'a> { /// See `parse_generic_bound` for the `BOUND` grammar. fn parse_generic_bounds_common( &mut self, - allow_plus: bool, + allow_plus: AllowPlus, colon_span: Option, ) -> PResult<'a, GenericBounds> { let mut bounds = Vec::new(); @@ -377,7 +396,7 @@ impl<'a> Parser<'a> { Ok(bound) => bounds.push(bound), Err(neg_sp) => negative_bounds.push(neg_sp), } - if !allow_plus || !self.eat_plus() { + if matches!(allow_plus, AllowPlus::No) || !self.eat_plus() { break; } } From b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 30 Jan 2020 00:18:54 +0100 Subject: [PATCH 0899/1253] parser: merge `fn` grammars wrt. bodies & headers also refactor `FnKind` and `visit_assoc_item` visitors --- src/librustc_ast_lowering/item.rs | 48 ++- src/librustc_ast_lowering/lib.rs | 27 +- src/librustc_ast_passes/ast_validation.rs | 301 +++++++++++------- src/librustc_ast_passes/feature_gate.rs | 69 ++-- src/librustc_ast_passes/node_count.rs | 8 +- src/librustc_ast_pretty/pprust.rs | 64 ++-- .../global_allocator.rs | 2 +- src/librustc_builtin_macros/test_harness.rs | 2 +- src/librustc_expand/base.rs | 6 +- src/librustc_expand/expand.rs | 38 ++- src/librustc_lint/builtin.rs | 46 +-- src/librustc_lint/early.rs | 39 +-- src/librustc_lint/passes.rs | 3 +- src/librustc_parse/parser/diagnostics.rs | 41 --- src/librustc_parse/parser/item.rs | 115 +++---- src/librustc_parse/parser/stmt.rs | 2 +- src/librustc_parse/parser/ty.rs | 16 +- src/librustc_passes/hir_stats.rs | 25 +- src/librustc_resolve/build_reduced_graph.rs | 21 +- src/librustc_resolve/def_collector.rs | 39 +-- src/librustc_resolve/late.rs | 54 ++-- src/librustc_save_analysis/dump_visitor.rs | 9 +- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_save_analysis/sig.rs | 3 +- src/libsyntax/ast.rs | 15 +- src/libsyntax/mut_visit.rs | 7 +- src/libsyntax/visit.rs | 136 ++++---- src/test/ui/extern/extern-ffi-fn-with-body.rs | 2 +- .../ui/extern/extern-ffi-fn-with-body.stderr | 10 +- src/test/ui/issues/issue-39616.rs | 3 +- src/test/ui/issues/issue-39616.stderr | 4 +- src/test/ui/macros/issue-54441.stderr | 4 +- src/test/ui/no-patterns-in-args-2.rs | 4 +- src/test/ui/no-patterns-in-args-2.stderr | 6 +- src/test/ui/no-patterns-in-args-macro.rs | 6 +- src/test/ui/no-patterns-in-args-macro.stderr | 4 +- src/test/ui/parser/duplicate-visibility.rs | 2 +- .../ui/parser/duplicate-visibility.stderr | 4 +- .../parser/fn-body-optional-semantic-fail.rs | 27 ++ .../fn-body-optional-semantic-fail.stderr | 40 +++ .../parser/fn-body-optional-syntactic-pass.rs | 31 ++ src/test/ui/parser/fn-header-semantic-fail.rs | 57 ++++ .../ui/parser/fn-header-semantic-fail.stderr | 136 ++++++++ .../ui/parser/fn-header-syntactic-pass.rs | 55 ++++ src/test/ui/parser/issue-24780.rs | 2 +- src/test/ui/parser/issue-24780.stderr | 4 +- src/test/ui/parser/issue-63135.rs | 2 +- src/test/ui/parser/issue-63135.stderr | 8 +- src/test/ui/parser/missing_right_paren.rs | 2 +- src/test/ui/parser/missing_right_paren.stderr | 8 +- .../ui/parser/no-const-fn-in-extern-block.rs | 4 +- .../parser/no-const-fn-in-extern-block.stderr | 21 +- src/test/ui/parser/not-a-pred.stderr | 4 +- 53 files changed, 961 insertions(+), 629 deletions(-) create mode 100644 src/test/ui/parser/fn-body-optional-semantic-fail.rs create mode 100644 src/test/ui/parser/fn-body-optional-semantic-fail.stderr create mode 100644 src/test/ui/parser/fn-body-optional-syntactic-pass.rs create mode 100644 src/test/ui/parser/fn-header-semantic-fail.rs create mode 100644 src/test/ui/parser/fn-header-semantic-fail.stderr create mode 100644 src/test/ui/parser/fn-header-syntactic-pass.rs diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index e27f2bdb8d25f..dab950e23f618 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -14,7 +14,7 @@ use rustc_target::spec::abi; use syntax::ast::*; use syntax::attr; use syntax::node_id::NodeMap; -use syntax::visit::{self, Visitor}; +use syntax::visit::{self, AssocCtxt, Visitor}; use log::debug; use smallvec::{smallvec, SmallVec}; @@ -81,25 +81,23 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { } } - fn visit_trait_item(&mut self, item: &'a AssocItem) { - self.lctx.with_hir_id_owner(item.id, |lctx| { - let hir_item = lctx.lower_trait_item(item); - let id = hir::TraitItemId { hir_id: hir_item.hir_id }; - lctx.trait_items.insert(id, hir_item); - lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id); + fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { + self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt { + AssocCtxt::Trait => { + let hir_item = lctx.lower_trait_item(item); + let id = hir::TraitItemId { hir_id: hir_item.hir_id }; + lctx.trait_items.insert(id, hir_item); + lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id); + } + AssocCtxt::Impl => { + let hir_item = lctx.lower_impl_item(item); + let id = hir::ImplItemId { hir_id: hir_item.hir_id }; + lctx.impl_items.insert(id, hir_item); + lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id); + } }); - visit::walk_trait_item(self, item); - } - - fn visit_impl_item(&mut self, item: &'a AssocItem) { - self.lctx.with_hir_id_owner(item.id, |lctx| { - let hir_item = lctx.lower_impl_item(item); - let id = hir::ImplItemId { hir_id: hir_item.hir_id }; - lctx.impl_items.insert(id, hir_item); - lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id); - }); - visit::walk_impl_item(self, item); + visit::walk_assoc_item(self, item, ctxt); } } @@ -299,20 +297,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // `impl Future` here because lower_body // only cares about the input argument patterns in the function // declaration (decl), not the return types. + let asyncness = header.asyncness.node; let body_id = - this.lower_maybe_async_body(span, &decl, header.asyncness.node, Some(body)); + this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); let (generics, decl) = this.add_in_band_defs( generics, fn_def_id, AnonymousLifetimeMode::PassThrough, |this, idty| { - this.lower_fn_decl( - &decl, - Some((fn_def_id, idty)), - true, - header.asyncness.node.opt_return_id(), - ) + let ret_id = asyncness.opt_return_id(); + this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id) }, ); let sig = hir::FnSig { decl, header: this.lower_fn_header(header) }; @@ -658,7 +653,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ident: i.ident, attrs: self.lower_attrs(&i.attrs), kind: match i.kind { - ForeignItemKind::Fn(ref fdec, ref generics) => { + ForeignItemKind::Fn(ref sig, ref generics, _) => { + let fdec = &sig.decl; let (generics, (fn_dec, fn_args)) = self.add_in_band_defs( generics, def_id, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index c3e96a31e4001..cd33bf6547be0 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -63,7 +63,7 @@ use syntax::attr; use syntax::node_id::NodeMap; use syntax::token::{self, Nonterminal, Token}; use syntax::tokenstream::{TokenStream, TokenTree}; -use syntax::visit::{self, Visitor}; +use syntax::visit::{self, AssocCtxt, Visitor}; use syntax::walk_list; use log::{debug, trace}; @@ -485,25 +485,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }); } - fn visit_trait_item(&mut self, item: &'tcx AssocItem) { + fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) { self.lctx.allocate_hir_id_counter(item.id); - - match item.kind { - AssocItemKind::Fn(_, None) => { - // Ignore patterns in trait methods without bodies - self.with_hir_id_owner(None, |this| visit::walk_trait_item(this, item)); - } - _ => self.with_hir_id_owner(Some(item.id), |this| { - visit::walk_trait_item(this, item); - }), - } - } - - fn visit_impl_item(&mut self, item: &'tcx AssocItem) { - self.lctx.allocate_hir_id_counter(item.id); - self.with_hir_id_owner(Some(item.id), |this| { - visit::walk_impl_item(this, item); - }); + let owner = match (&item.kind, ctxt) { + // Ignore patterns in trait methods without bodies. + (AssocItemKind::Fn(_, None), AssocCtxt::Trait) => None, + _ => Some(item.id), + }; + self.with_hir_id_owner(owner, |this| visit::walk_assoc_item(this, item, ctxt)); } fn visit_foreign_item(&mut self, i: &'tcx ForeignItem) { diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index cb64e2e95bf7d..53911d147802d 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -8,7 +8,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, Applicability, FatalError}; +use rustc_errors::{error_code, struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_session::lint::LintBuffer; @@ -20,7 +20,7 @@ use std::mem; use syntax::ast::*; use syntax::attr; use syntax::expand::is_proc_macro_attr; -use syntax::visit::{self, Visitor}; +use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use syntax::walk_list; /// Is `self` allowed semantically as the first parameter in an `FnDecl`? @@ -49,6 +49,13 @@ impl BoundContext { struct AstValidator<'a> { session: &'a Session, + + /// The span of the `extern` in an `extern { ... }` block, if any. + extern_mod: Option<&'a Item>, + + /// Are we inside a trait impl? + in_trait_impl: bool, + has_proc_macro_decls: bool, /// Used to ban nested `impl Trait`, e.g., `impl Into`. @@ -389,13 +396,9 @@ impl<'a> AstValidator<'a> { } } - fn check_impl_item_provided(&self, sp: Span, body: &Option, ctx: &str, sugg: &str) { - if body.is_some() { - return; - } - + fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) { self.err_handler() - .struct_span_err(sp, &format!("associated {} in `impl` without body", ctx)) + .struct_span_err(sp, msg) .span_suggestion( self.session.source_map().end_point(sp), &format!("provide a definition for the {}", ctx), @@ -405,6 +408,13 @@ impl<'a> AstValidator<'a> { .emit(); } + fn check_impl_item_provided(&self, sp: Span, body: &Option, ctx: &str, sugg: &str) { + if body.is_none() { + let msg = format!("associated {} in `impl` without body", ctx); + self.error_item_without_body(sp, ctx, &msg, sugg); + } + } + fn check_impl_assoc_type_no_bounds(&self, bounds: &[GenericBound]) { let span = match bounds { [] => return, @@ -416,8 +426,71 @@ impl<'a> AstValidator<'a> { .emit(); } - fn check_c_varadic_type(&self, decl: &FnDecl) { - for Param { ty, span, .. } in &decl.inputs { + /// An `fn` in `extern { ... }` cannot have a body `{ ... }`. + fn check_foreign_fn_bodyless(&self, ident: Ident, body: Option<&Block>) { + let body = match body { + None => return, + Some(body) => body, + }; + self.err_handler() + .struct_span_err(ident.span, "incorrect function inside `extern` block") + .span_label(ident.span, "cannot have a body") + .span_suggestion( + body.span, + "remove the invalid body", + ";".to_string(), + Applicability::MaybeIncorrect, + ) + .help( + "you might have meant to write a function accessible through FFI, \ + which can be done by writing `extern fn` outside of the `extern` block", + ) + .span_label( + self.current_extern_span(), + "`extern` blocks define existing foreign functions and functions \ + inside of them cannot have a body", + ) + .note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html") + .emit(); + } + + fn current_extern_span(&self) -> Span { + self.session.source_map().def_span(self.extern_mod.unwrap().span) + } + + /// An `fn` in `extern { ... }` cannot have qualfiers, e.g. `async fn`. + fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) { + if header.has_qualifiers() { + self.err_handler() + .struct_span_err(ident.span, "functions in `extern` blocks cannot have qualifiers") + .span_label(self.current_extern_span(), "in this `extern` block") + .span_suggestion( + span.until(ident.span.shrink_to_lo()), + "remove the qualifiers", + "fn ".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(); + } + } + + /// Reject C-varadic type unless the function is foreign, + /// or free and `unsafe extern "C"` semantically. + fn check_c_varadic_type(&self, fk: FnKind<'a>) { + match (fk.ctxt(), fk.header()) { + (Some(FnCtxt::Foreign), _) => return, + (Some(FnCtxt::Free), Some(header)) => match header.ext { + Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }) | Extern::Implicit + if header.unsafety == Unsafety::Unsafe => + { + return; + } + _ => {} + }, + _ => {} + }; + + for Param { ty, span, .. } in &fk.decl().inputs { if let TyKind::CVarArgs = ty.kind { self.err_handler() .struct_span_err( @@ -428,6 +501,24 @@ impl<'a> AstValidator<'a> { } } } + + /// We currently do not permit const generics in `const fn`, + /// as this is tantamount to allowing compile-time dependent typing. + /// + /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor. + /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck. + fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) { + if sig.header.constness.node == Constness::Const { + // Look for const generics and error if we find any. + for param in &generics.params { + if let GenericParamKind::Const { .. } = param.kind { + self.err_handler() + .struct_span_err(span, "const parameters are not permitted in `const fn`") + .emit(); + } + } + } + } } enum GenericPosition { @@ -532,9 +623,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.kind { - ExprKind::Closure(_, _, _, fn_decl, _, _) => { - self.check_fn_decl(fn_decl, SelfSemantic::No); - } ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => { struct_span_err!( self.session, @@ -647,8 +735,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { generics: _, of_trait: Some(_), ref self_ty, - ref items, + items: _, } => { + let old_in_trait_impl = mem::replace(&mut self.in_trait_impl, true); + self.invalid_visibility(&item.vis, None); if let TyKind::Err = self_ty.kind { self.err_handler() @@ -665,13 +755,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ) .emit(); } - for impl_item in items { - self.invalid_visibility(&impl_item.vis, None); - if let AssocItemKind::Fn(ref sig, _) = impl_item.kind { - self.check_trait_fn_not_const(sig.header.constness); - self.check_trait_fn_not_async(impl_item.span, sig.header.asyncness.node); - } - } + + visit::walk_item(self, item); + + self.in_trait_impl = old_in_trait_impl; + return; // Avoid visiting again. } ItemKind::Impl { unsafety, @@ -712,40 +800,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .emit(); } } - ItemKind::Fn(ref sig, ref generics, _) => { - self.visit_fn_header(&sig.header); - self.check_fn_decl(&sig.decl, SelfSemantic::No); - // We currently do not permit const generics in `const fn`, as - // this is tantamount to allowing compile-time dependent typing. - if sig.header.constness.node == Constness::Const { - // Look for const generics and error if we find any. - for param in &generics.params { - match param.kind { - GenericParamKind::Const { .. } => { - self.err_handler() - .struct_span_err( - item.span, - "const parameters are not permitted in `const fn`", - ) - .emit(); - } - _ => {} - } - } - } - // Reject C-varadic type unless the function is `unsafe extern "C"` semantically. - match sig.header.ext { - Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }) - | Extern::Implicit - if sig.header.unsafety == Unsafety::Unsafe => {} - _ => self.check_c_varadic_type(&sig.decl), + ItemKind::Fn(ref sig, ref generics, ref body) => { + self.check_const_fn_const_generic(item.span, sig, generics); + + if body.is_none() { + let msg = "free function without a body"; + self.error_item_without_body(item.span, "function", msg, " { }"); } } - ItemKind::ForeignMod(..) => { + ItemKind::ForeignMod(_) => { + let old_item = mem::replace(&mut self.extern_mod, Some(item)); self.invalid_visibility( &item.vis, Some("place qualifiers on individual foreign items instead"), ); + visit::walk_item(self, item); + self.extern_mod = old_item; + return; // Avoid visiting again. } ItemKind::Enum(ref def, _) => { for variant in &def.variants { @@ -796,7 +867,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.with_bound_context(BoundContext::TraitBounds, |this| { walk_list!(this, visit_param_bound, bounds); }); - walk_list!(self, visit_trait_item, trait_items); + walk_list!(self, visit_assoc_item, trait_items, AssocCtxt::Trait); walk_list!(self, visit_attribute, &item.attrs); return; } @@ -820,19 +891,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { - match fi.kind { - ForeignItemKind::Fn(ref decl, _) => { - self.check_fn_decl(decl, SelfSemantic::No); - Self::check_decl_no_pat(decl, |span, _| { - struct_span_err!( - self.session, - span, - E0130, - "patterns aren't allowed in foreign function declarations" - ) - .span_label(span, "pattern not allowed in foreign function") - .emit(); - }); + match &fi.kind { + ForeignItemKind::Fn(sig, _, body) => { + self.check_foreign_fn_bodyless(fi.ident, body.as_deref()); + self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header); } ForeignItemKind::Static(..) | ForeignItemKind::Ty | ForeignItemKind::Macro(..) => {} } @@ -1011,67 +1073,84 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }) } - fn visit_impl_item(&mut self, ii: &'a AssocItem) { - match &ii.kind { - AssocItemKind::Const(_, body) => { - self.check_impl_item_provided(ii.span, body, "constant", " = ;"); - } - AssocItemKind::Fn(_, body) => { - self.check_impl_item_provided(ii.span, body, "function", " { }"); - } - AssocItemKind::TyAlias(bounds, body) => { - self.check_impl_item_provided(ii.span, body, "type", " = ;"); - self.check_impl_assoc_type_no_bounds(bounds); - } - _ => {} + fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { + // Only associated `fn`s can have `self` parameters. + let self_semantic = match fk.ctxt() { + Some(FnCtxt::Assoc(_)) => SelfSemantic::Yes, + _ => SelfSemantic::No, + }; + self.check_fn_decl(fk.decl(), self_semantic); + + self.check_c_varadic_type(fk); + + // Functions without bodies cannot have patterns. + if let FnKind::Fn(ctxt, _, sig, _, None) = fk { + Self::check_decl_no_pat(&sig.decl, |span, mut_ident| { + let (code, msg, label) = match ctxt { + FnCtxt::Foreign => ( + error_code!(E0130), + "patterns aren't allowed in foreign function declarations", + "pattern not allowed in foreign function", + ), + _ => ( + error_code!(E0642), + "patterns aren't allowed in functions without bodies", + "pattern not allowed in function without body", + ), + }; + if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { + self.lint_buffer.buffer_lint(PATTERNS_IN_FNS_WITHOUT_BODY, id, span, msg); + } else { + self.err_handler() + .struct_span_err(span, msg) + .span_label(span, label) + .code(code) + .emit(); + } + }); } - visit::walk_impl_item(self, ii); + + visit::walk_fn(self, fk, span); } - fn visit_trait_item(&mut self, ti: &'a AssocItem) { - self.invalid_visibility(&ti.vis, None); - self.check_defaultness(ti.span, ti.defaultness); - - if let AssocItemKind::Fn(sig, block) = &ti.kind { - self.check_trait_fn_not_async(ti.span, sig.header.asyncness.node); - self.check_trait_fn_not_const(sig.header.constness); - if block.is_none() { - Self::check_decl_no_pat(&sig.decl, |span, mut_ident| { - if mut_ident { - self.lint_buffer.buffer_lint( - PATTERNS_IN_FNS_WITHOUT_BODY, - ti.id, - span, - "patterns aren't allowed in methods without bodies", - ); - } else { - struct_span_err!( - self.session, - span, - E0642, - "patterns aren't allowed in methods without bodies" - ) - .emit(); - } - }); - } + fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { + if ctxt == AssocCtxt::Trait { + self.check_defaultness(item.span, item.defaultness); } - visit::walk_trait_item(self, ti); - } + if ctxt == AssocCtxt::Impl { + match &item.kind { + AssocItemKind::Const(_, body) => { + self.check_impl_item_provided(item.span, body, "constant", " = ;"); + } + AssocItemKind::Fn(_, body) => { + self.check_impl_item_provided(item.span, body, "function", " { }"); + } + AssocItemKind::TyAlias(bounds, body) => { + self.check_impl_item_provided(item.span, body, "type", " = ;"); + self.check_impl_assoc_type_no_bounds(bounds); + } + _ => {} + } + } - fn visit_assoc_item(&mut self, item: &'a AssocItem) { - if let AssocItemKind::Fn(sig, _) = &item.kind { - self.check_fn_decl(&sig.decl, SelfSemantic::Yes); - self.check_c_varadic_type(&sig.decl); + if ctxt == AssocCtxt::Trait || self.in_trait_impl { + self.invalid_visibility(&item.vis, None); + if let AssocItemKind::Fn(sig, _) = &item.kind { + self.check_trait_fn_not_const(sig.header.constness); + self.check_trait_fn_not_async(item.span, sig.header.asyncness.node); + } } - visit::walk_assoc_item(self, item); + + visit::walk_assoc_item(self, item, ctxt); } } pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool { let mut validator = AstValidator { session, + extern_mod: None, + in_trait_impl: false, has_proc_macro_decls: false, outer_impl_trait: None, bound_context: None, diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 3b13ab354fdf9..a10ac94d8942b 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -8,7 +8,7 @@ use rustc_span::Span; use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; use syntax::attr; -use syntax::visit::{self, FnKind, Visitor}; +use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use log::debug; @@ -492,25 +492,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_pat(self, pattern) } - fn visit_fn( - &mut self, - fn_kind: FnKind<'a>, - fn_decl: &'a ast::FnDecl, - span: Span, - _node_id: NodeId, - ) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { if let Some(header) = fn_kind.header() { - // Stability of const fn methods are covered in - // `visit_trait_item` and `visit_impl_item` below; this is - // because default methods don't pass through this point. + // Stability of const fn methods are covered in `visit_assoc_item` below. self.check_extern(header.ext); } - if fn_decl.c_variadic() { + if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() { gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); } - visit::walk_fn(self, fn_kind, fn_decl, span) + visit::walk_fn(self, fn_kind, span) } fn visit_generic_param(&mut self, param: &'a GenericParam) { @@ -539,56 +531,35 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_assoc_ty_constraint(self, constraint) } - fn visit_trait_item(&mut self, ti: &'a ast::AssocItem) { - match ti.kind { - ast::AssocItemKind::Fn(ref sig, ref block) => { - if block.is_none() { - self.check_extern(sig.header.ext); - } - if sig.header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); + fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { + if i.defaultness == ast::Defaultness::Default { + gate_feature_post!(&self, specialization, i.span, "specialization is unstable"); + } + + match i.kind { + ast::AssocItemKind::Fn(ref sig, _) => { + let constness = sig.header.constness.node; + if let (ast::Constness::Const, AssocCtxt::Trait) = (constness, ctxt) { + gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); } } - ast::AssocItemKind::TyAlias(_, ref default) => { - if let Some(_) = default { + ast::AssocItemKind::TyAlias(_, ref ty) => { + if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, associated_type_defaults, - ti.span, + i.span, "associated type defaults are unstable" ); } - } - _ => {} - } - visit::walk_trait_item(self, ti) - } - - fn visit_assoc_item(&mut self, ii: &'a ast::AssocItem) { - if ii.defaultness == ast::Defaultness::Default { - gate_feature_post!(&self, specialization, ii.span, "specialization is unstable"); - } - - match ii.kind { - ast::AssocItemKind::Fn(ref sig, _) => { - if sig.decl.c_variadic() { - gate_feature_post!( - &self, - c_variadic, - ii.span, - "C-variadic functions are unstable" - ); - } - } - ast::AssocItemKind::TyAlias(_, ref ty) => { if let Some(ty) = ty { self.check_impl_trait(ty); } - self.check_gat(&ii.generics, ii.span); + self.check_gat(&i.generics, i.span); } _ => {} } - visit::walk_assoc_item(self, ii) + visit::walk_assoc_item(self, i, ctxt) } fn visit_vis(&mut self, vis: &'a ast::Visibility) { diff --git a/src/librustc_ast_passes/node_count.rs b/src/librustc_ast_passes/node_count.rs index 9fe7238fcfc3e..ed1ccdf6a768a 100644 --- a/src/librustc_ast_passes/node_count.rs +++ b/src/librustc_ast_passes/node_count.rs @@ -67,13 +67,13 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_generics(self, g) } - fn visit_fn(&mut self, fk: FnKind<'_>, fd: &FnDecl, s: Span, _: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'_>, s: Span, _: NodeId) { self.count += 1; - walk_fn(self, fk, fd, s) + walk_fn(self, fk, s) } - fn visit_assoc_item(&mut self, ti: &AssocItem) { + fn visit_assoc_item(&mut self, ti: &AssocItem, ctxt: AssocCtxt) { self.count += 1; - walk_assoc_item(self, ti) + walk_assoc_item(self, ti, ctxt); } fn visit_trait_ref(&mut self, t: &TraitRef) { self.count += 1; diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 3cc67a7c82117..d9077d1606f3a 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1020,18 +1020,8 @@ impl<'a> State<'a> { self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(&item.attrs); match item.kind { - ast::ForeignItemKind::Fn(ref decl, ref generics) => { - self.head(""); - self.print_fn( - decl, - ast::FnHeader::default(), - Some(item.ident), - generics, - &item.vis, - ); - self.end(); // end head-ibox - self.s.word(";"); - self.end(); // end the outer fn box + ast::ForeignItemKind::Fn(ref sig, ref gen, ref body) => { + self.print_fn_full(sig, item.ident, gen, &item.vis, body.as_deref(), &item.attrs); } ast::ForeignItemKind::Static(ref t, m) => { self.head(visibility_qualified(&item.vis, "static")); @@ -1154,11 +1144,8 @@ impl<'a> State<'a> { self.s.word(";"); self.end(); // end the outer cbox } - ast::ItemKind::Fn(ref sig, ref param_names, ref body) => { - self.head(""); - self.print_fn(&sig.decl, sig.header, Some(item.ident), param_names, &item.vis); - self.s.word(" "); - self.print_block_with_attrs(body, &item.attrs); + ast::ItemKind::Fn(ref sig, ref gen, ref body) => { + self.print_fn_full(sig, item.ident, gen, &item.vis, body.as_deref(), &item.attrs); } ast::ItemKind::Mod(ref _mod) => { self.head(visibility_qualified(&item.vis, "mod")); @@ -1483,16 +1470,8 @@ impl<'a> State<'a> { self.print_associated_const(item.ident, ty, expr.as_deref(), &item.vis); } ast::AssocItemKind::Fn(sig, body) => { - if body.is_some() { - self.head(""); - } - self.print_fn(&sig.decl, sig.header, Some(item.ident), &item.generics, &item.vis); - if let Some(body) = body { - self.nbsp(); - self.print_block_with_attrs(body, &item.attrs); - } else { - self.s.word(";"); - } + let body = body.as_deref(); + self.print_fn_full(sig, item.ident, &item.generics, &item.vis, body, &item.attrs); } ast::AssocItemKind::TyAlias(bounds, ty) => { self.print_associated_type(item.ident, bounds, ty.as_deref()); @@ -2412,6 +2391,27 @@ impl<'a> State<'a> { } } + fn print_fn_full( + &mut self, + sig: &ast::FnSig, + name: ast::Ident, + generics: &ast::Generics, + vis: &ast::Visibility, + body: Option<&ast::Block>, + attrs: &[ast::Attribute], + ) { + if body.is_some() { + self.head(""); + } + self.print_fn(&sig.decl, sig.header, Some(name), generics, vis); + if let Some(body) = body { + self.nbsp(); + self.print_block_with_attrs(body, attrs); + } else { + self.s.word(";"); + } + } + crate fn print_fn( &mut self, decl: &ast::FnDecl, @@ -2698,13 +2698,9 @@ impl<'a> State<'a> { where_clause: ast::WhereClause { predicates: Vec::new(), span: rustc_span::DUMMY_SP }, span: rustc_span::DUMMY_SP, }; - self.print_fn( - decl, - ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }, - name, - &generics, - &dummy_spanned(ast::VisibilityKind::Inherited), - ); + let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }; + let vis = dummy_spanned(ast::VisibilityKind::Inherited); + self.print_fn(decl, header, name, &generics, &vis); self.end(); } diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs index 957d34b7d8983..ec0d55b38a73d 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/src/librustc_builtin_macros/global_allocator.rs @@ -66,7 +66,7 @@ impl AllocFnFactory<'_, '_> { let decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)); let header = FnHeader { unsafety: Unsafety::Unsafe, ..FnHeader::default() }; let sig = FnSig { decl, header }; - let kind = ItemKind::Fn(sig, Generics::default(), self.cx.block_expr(output_expr)); + let kind = ItemKind::Fn(sig, Generics::default(), Some(self.cx.block_expr(output_expr))); let item = self.cx.item( self.span, self.cx.ident_of(&self.kind.fn_name(method.name), self.span), diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index 6a73f121c99bf..70f1c0e4e2d7c 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -307,7 +307,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { let decl = ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)); let sig = ast::FnSig { decl, header: ast::FnHeader::default() }; - let main = ast::ItemKind::Fn(sig, ast::Generics::default(), main_body); + let main = ast::ItemKind::Fn(sig, ast::Generics::default(), Some(main_body)); // Honor the reexport_test_harness_main attribute let main_id = match cx.reexport_test_harness_main { diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 536259e054718..e167089b93a35 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -17,7 +17,7 @@ use syntax::mut_visit::{self, MutVisitor}; use syntax::ptr::P; use syntax::token; use syntax::tokenstream::{self, TokenStream}; -use syntax::visit::Visitor; +use syntax::visit::{AssocCtxt, Visitor}; use std::default::Default; use std::iter; @@ -103,8 +103,8 @@ impl Annotatable { pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { match self { Annotatable::Item(item) => visitor.visit_item(item), - Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item), - Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item), + Annotatable::TraitItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Trait), + Annotatable::ImplItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Impl), Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item), Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt), Annotatable::Expr(expr) => visitor.visit_expr(expr), diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index f08bed5731530..eb1f23ee5b36a 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -25,7 +25,7 @@ use syntax::ptr::P; use syntax::token; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::util::map_in_place::MapInPlace; -use syntax::visit::{self, Visitor}; +use syntax::visit::{self, AssocCtxt, Visitor}; use smallvec::{smallvec, SmallVec}; use std::io::ErrorKind; @@ -39,7 +39,7 @@ macro_rules! ast_fragments { $($Kind:ident($AstTy:ty) { $kind_name:expr; $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? - $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)? + $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)? fn $make_ast:ident; })* ) => { @@ -127,7 +127,7 @@ macro_rules! ast_fragments { AstFragment::OptExpr(None) => {} $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)* $($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] { - visitor.$visit_ast_elt(ast_elt); + visitor.$visit_ast_elt(ast_elt, $($args)*); })?)* } } @@ -147,52 +147,58 @@ ast_fragments! { Pat(P) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; } Ty(P) { "type"; one fn visit_ty; fn visit_ty; fn make_ty; } Stmts(SmallVec<[ast::Stmt; 1]>) { - "statement"; many fn flat_map_stmt; fn visit_stmt; fn make_stmts; + "statement"; many fn flat_map_stmt; fn visit_stmt(); fn make_stmts; } Items(SmallVec<[P; 1]>) { - "item"; many fn flat_map_item; fn visit_item; fn make_items; + "item"; many fn flat_map_item; fn visit_item(); fn make_items; } TraitItems(SmallVec<[P; 1]>) { - "trait item"; many fn flat_map_trait_item; fn visit_trait_item; fn make_trait_items; + "trait item"; + many fn flat_map_trait_item; + fn visit_assoc_item(AssocCtxt::Trait); + fn make_trait_items; } ImplItems(SmallVec<[P; 1]>) { - "impl item"; many fn flat_map_impl_item; fn visit_impl_item; fn make_impl_items; + "impl item"; + many fn flat_map_impl_item; + fn visit_assoc_item(AssocCtxt::Impl); + fn make_impl_items; } ForeignItems(SmallVec<[P; 1]>) { "foreign item"; many fn flat_map_foreign_item; - fn visit_foreign_item; + fn visit_foreign_item(); fn make_foreign_items; } Arms(SmallVec<[ast::Arm; 1]>) { - "match arm"; many fn flat_map_arm; fn visit_arm; fn make_arms; + "match arm"; many fn flat_map_arm; fn visit_arm(); fn make_arms; } Fields(SmallVec<[ast::Field; 1]>) { - "field expression"; many fn flat_map_field; fn visit_field; fn make_fields; + "field expression"; many fn flat_map_field; fn visit_field(); fn make_fields; } FieldPats(SmallVec<[ast::FieldPat; 1]>) { "field pattern"; many fn flat_map_field_pattern; - fn visit_field_pattern; + fn visit_field_pattern(); fn make_field_patterns; } GenericParams(SmallVec<[ast::GenericParam; 1]>) { "generic parameter"; many fn flat_map_generic_param; - fn visit_generic_param; + fn visit_generic_param(); fn make_generic_params; } Params(SmallVec<[ast::Param; 1]>) { - "function parameter"; many fn flat_map_param; fn visit_param; fn make_params; + "function parameter"; many fn flat_map_param; fn visit_param(); fn make_params; } StructFields(SmallVec<[ast::StructField; 1]>) { "field"; many fn flat_map_struct_field; - fn visit_struct_field; + fn visit_struct_field(); fn make_struct_fields; } Variants(SmallVec<[ast::Variant; 1]>) { - "variant"; many fn flat_map_variant; fn visit_variant; fn make_variants; + "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants; } } @@ -851,7 +857,7 @@ pub fn parse_ast_fragment<'a>( AstFragmentKind::ForeignItems => { let mut items = SmallVec::new(); while this.token != token::Eof { - items.push(this.parse_foreign_item(DUMMY_SP)?); + items.push(this.parse_foreign_item()?); } AstFragment::ForeignItems(items) } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 345665de63c3c..f024bb0e8b5c8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -43,7 +43,7 @@ use rustc_span::{BytePos, Span}; use syntax::ast::{self, Expr}; use syntax::attr::{self, HasAttrs}; use syntax::tokenstream::{TokenStream, TokenTree}; -use syntax::visit::FnKind; +use syntax::visit::{FnCtxt, FnKind}; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -259,34 +259,22 @@ impl EarlyLintPass for UnsafeCode { } } - fn check_fn( - &mut self, - cx: &EarlyContext<'_>, - fk: FnKind<'_>, - _: &ast::FnDecl, - span: Span, - _: ast::NodeId, - ) { - match fk { - FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => { - self.report_unsafe(cx, span, "declaration of an `unsafe` function") - } - - FnKind::Method(_, sig, ..) => { - if sig.header.unsafety == ast::Unsafety::Unsafe { - self.report_unsafe(cx, span, "implementation of an `unsafe` method") - } - } - - _ => (), - } - } - - fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &ast::AssocItem) { - if let ast::AssocItemKind::Fn(ref sig, None) = item.kind { - if sig.header.unsafety == ast::Unsafety::Unsafe { - self.report_unsafe(cx, item.span, "declaration of an `unsafe` method") - } + fn check_fn(&mut self, cx: &EarlyContext<'_>, fk: FnKind<'_>, span: Span, _: ast::NodeId) { + if let FnKind::Fn( + ctxt, + _, + ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, .. }, + _, + body, + ) = fk + { + let msg = match ctxt { + FnCtxt::Foreign => return, + FnCtxt::Free => "declaration of an `unsafe` function", + FnCtxt::Assoc(_) if body.is_none() => "declaration of an `unsafe` method", + FnCtxt::Assoc(_) => "implementation of an `unsafe` method", + }; + self.report_unsafe(cx, span, msg); } } } diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 490114b2d4d2a..542cbea0c954a 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -116,17 +116,11 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::walk_stmt(self, s); } - fn visit_fn( - &mut self, - fk: ast_visit::FnKind<'a>, - decl: &'a ast::FnDecl, - span: Span, - id: ast::NodeId, - ) { - run_early_pass!(self, check_fn, fk, decl, span, id); + fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) { + run_early_pass!(self, check_fn, fk, span, id); self.check_id(id); - ast_visit::walk_fn(self, fk, decl, span); - run_early_pass!(self, check_fn_post, fk, decl, span, id); + ast_visit::walk_fn(self, fk, span); + run_early_pass!(self, check_fn_post, fk, span, id); } fn visit_variant_data(&mut self, s: &'a ast::VariantData) { @@ -213,19 +207,18 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::walk_poly_trait_ref(self, t, m); } - fn visit_trait_item(&mut self, trait_item: &'a ast::AssocItem) { - self.with_lint_attrs(trait_item.id, &trait_item.attrs, |cx| { - run_early_pass!(cx, check_trait_item, trait_item); - ast_visit::walk_trait_item(cx, trait_item); - run_early_pass!(cx, check_trait_item_post, trait_item); - }); - } - - fn visit_impl_item(&mut self, impl_item: &'a ast::AssocItem) { - self.with_lint_attrs(impl_item.id, &impl_item.attrs, |cx| { - run_early_pass!(cx, check_impl_item, impl_item); - ast_visit::walk_impl_item(cx, impl_item); - run_early_pass!(cx, check_impl_item_post, impl_item); + fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) { + self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt { + ast_visit::AssocCtxt::Trait => { + run_early_pass!(cx, check_trait_item, item); + ast_visit::walk_assoc_item(cx, item, ctxt); + run_early_pass!(cx, check_trait_item_post, item); + } + ast_visit::AssocCtxt::Impl => { + run_early_pass!(cx, check_impl_item, item); + ast_visit::walk_assoc_item(cx, item, ctxt); + run_early_pass!(cx, check_impl_item_post, item); + } }); } diff --git a/src/librustc_lint/passes.rs b/src/librustc_lint/passes.rs index 7e5d670767ad8..36de625cafac2 100644 --- a/src/librustc_lint/passes.rs +++ b/src/librustc_lint/passes.rs @@ -179,10 +179,9 @@ macro_rules! early_lint_methods { fn check_where_predicate(a: &ast::WherePredicate); fn check_poly_trait_ref(a: &ast::PolyTraitRef, b: &ast::TraitBoundModifier); - fn check_fn(a: syntax::visit::FnKind<'_>, b: &ast::FnDecl, c: Span, d_: ast::NodeId); + fn check_fn(a: syntax::visit::FnKind<'_>, c: Span, d_: ast::NodeId); fn check_fn_post( a: syntax::visit::FnKind<'_>, - b: &ast::FnDecl, c: Span, d: ast::NodeId ); diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 5f148fa6ba2d3..7c015c7a1d75d 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -938,47 +938,6 @@ impl<'a> Parser<'a> { self.expect(&token::Semi).map(drop) // Error unconditionally } - pub(super) fn parse_semi_or_incorrect_foreign_fn_body( - &mut self, - ident: &Ident, - extern_sp: Span, - ) -> PResult<'a, ()> { - if self.token != token::Semi { - // This might be an incorrect fn definition (#62109). - let parser_snapshot = self.clone(); - match self.parse_inner_attrs_and_block() { - Ok((_, body)) => { - self.struct_span_err(ident.span, "incorrect `fn` inside `extern` block") - .span_label(ident.span, "can't have a body") - .span_label(body.span, "this body is invalid here") - .span_label( - extern_sp, - "`extern` blocks define existing foreign functions and `fn`s \ - inside of them cannot have a body", - ) - .help( - "you might have meant to write a function accessible through ffi, \ - which can be done by writing `extern fn` outside of the \ - `extern` block", - ) - .note( - "for more information, visit \ - https://doc.rust-lang.org/std/keyword.extern.html", - ) - .emit(); - } - Err(mut err) => { - err.cancel(); - mem::replace(self, parser_snapshot); - self.expect_semi()?; - } - } - } else { - self.bump(); - } - Ok(()) - } - /// Consumes alternative await syntaxes like `await!()`, `await `, /// `await? `, `await()`, and `await { }`. pub(super) fn recover_incorrect_await_syntax( diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 87a6aa76f5777..07d8bae4725bd 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -97,7 +97,6 @@ impl<'a> Parser<'a> { } if self.eat_keyword(kw::Extern) { - let extern_sp = self.prev_span; if self.eat_keyword(kw::Crate) { return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?)); } @@ -115,7 +114,7 @@ impl<'a> Parser<'a> { }; return self.parse_item_fn(lo, vis, attrs, header); } else if self.check(&token::OpenDelim(token::Brace)) { - return Ok(Some(self.parse_item_foreign_mod(lo, abi, vis, attrs, extern_sp)?)); + return Ok(Some(self.parse_item_foreign_mod(lo, abi, vis, attrs)?)); } self.unexpected()?; @@ -1046,7 +1045,6 @@ impl<'a> Parser<'a> { abi: Option, visibility: Visibility, mut attrs: Vec, - extern_sp: Span, ) -> PResult<'a, P> { self.expect(&token::OpenDelim(token::Brace))?; @@ -1054,7 +1052,7 @@ impl<'a> Parser<'a> { let mut foreign_items = vec![]; while !self.eat(&token::CloseDelim(token::Brace)) { - foreign_items.push(self.parse_foreign_item(extern_sp)?); + foreign_items.push(self.parse_foreign_item()?); } let prev_span = self.prev_span; @@ -1064,51 +1062,42 @@ impl<'a> Parser<'a> { } /// Parses a foreign item. - pub fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, P> { + pub fn parse_foreign_item(&mut self) -> PResult<'a, P> { maybe_whole!(self, NtForeignItem, |ni| ni); let attrs = self.parse_outer_attributes()?; let lo = self.token.span; let visibility = self.parse_visibility(FollowedByType::No)?; + // FOREIGN TYPE ITEM + if self.check_keyword(kw::Type) { + return self.parse_item_foreign_type(visibility, lo, attrs); + } + // FOREIGN STATIC ITEM - // Treat `const` as `static` for error recovery, but don't add it to expected tokens. - if self.check_keyword(kw::Static) || self.token.is_keyword(kw::Const) { - if self.token.is_keyword(kw::Const) { - let mut err = - self.struct_span_err(self.token.span, "extern items cannot be `const`"); + if self.is_static_global() { + self.bump(); // `static` + return self.parse_item_foreign_static(visibility, lo, attrs); + } - // The user wrote 'const fn' - if self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe]) { - err.emit(); - // Consume `const` - self.bump(); - // Consume `unsafe` if present, since `extern` blocks - // don't allow it. This will leave behind a plain 'fn' - self.eat_keyword(kw::Unsafe); - // Treat 'const fn` as a plain `fn` for error recovery purposes. - // We've already emitted an error, so compilation is guaranteed - // to fail - return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?); - } - err.span_suggestion( - self.token.span, + // Treat `const` as `static` for error recovery, but don't add it to expected tokens. + if self.is_kw_followed_by_ident(kw::Const) { + self.bump(); // `const` + self.struct_span_err(self.prev_span, "extern items cannot be `const`") + .span_suggestion( + self.prev_span, "try using a static value", "static".to_owned(), Applicability::MachineApplicable, - ); - err.emit(); - } - self.bump(); // `static` or `const` - return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?); + ) + .emit(); + return self.parse_item_foreign_static(visibility, lo, attrs); } + // FOREIGN FUNCTION ITEM - if self.check_keyword(kw::Fn) { - return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?); - } - // FOREIGN TYPE ITEM - if self.check_keyword(kw::Type) { - return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?); + const MAY_INTRODUCE_FN: &[Symbol] = &[kw::Const, kw::Async, kw::Unsafe, kw::Extern, kw::Fn]; + if MAY_INTRODUCE_FN.iter().any(|&kw| self.check_keyword(kw)) { + return self.parse_item_foreign_fn(visibility, lo, attrs); } match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? { @@ -1727,14 +1716,14 @@ impl<'a> Parser<'a> { &mut self, lo: Span, vis: Visibility, - attrs: Vec, + mut attrs: Vec, header: FnHeader, ) -> PResult<'a, Option>> { let cfg = ParamCfg { is_name_required: |_| true }; let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + let body = self.parse_fn_body(&mut false, &mut attrs)?; let kind = ItemKind::Fn(FnSig { decl, header }, generics, body); - self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) + self.mk_item_with_info(attrs, lo, vis, (ident, kind, None)) } /// Parses a function declaration from a foreign module. @@ -1742,15 +1731,14 @@ impl<'a> Parser<'a> { &mut self, vis: ast::Visibility, lo: Span, - attrs: Vec, - extern_sp: Span, + mut attrs: Vec, ) -> PResult<'a, P> { let cfg = ParamCfg { is_name_required: |_| true }; - self.expect_keyword(kw::Fn)?; + let header = self.parse_fn_front_matter()?; let (ident, decl, generics) = self.parse_fn_sig(&cfg)?; - let span = lo.to(self.token.span); - self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; - let kind = ForeignItemKind::Fn(decl, generics); + let body = self.parse_fn_body(&mut false, &mut attrs)?; + let kind = ForeignItemKind::Fn(FnSig { header, decl }, generics, body); + let span = lo.to(self.prev_span); Ok(P(ast::ForeignItem { ident, attrs, kind, id: DUMMY_NODE_ID, span, vis, tokens: None })) } @@ -1761,45 +1749,40 @@ impl<'a> Parser<'a> { is_name_required: fn(&token::Token) -> bool, ) -> PResult<'a, (Ident, AssocItemKind, Generics)> { let header = self.parse_fn_front_matter()?; - let (ident, decl, generics) = self.parse_fn_sig(&ParamCfg { is_name_required })?; - let sig = FnSig { header, decl }; - let body = self.parse_assoc_fn_body(at_end, attrs)?; - Ok((ident, AssocItemKind::Fn(sig, body), generics)) + let (ident, decl, generics) = self.parse_fn_sig(&&ParamCfg { is_name_required })?; + let body = self.parse_fn_body(at_end, attrs)?; + Ok((ident, AssocItemKind::Fn(FnSig { header, decl }, body), generics)) } - /// Parse the "body" of a method in an associated item definition. + /// Parse the "body" of a function. /// This can either be `;` when there's no body, - /// or e.g. a block when the method is a provided one. - fn parse_assoc_fn_body( + /// or e.g. a block when the function is a provided one. + fn parse_fn_body( &mut self, at_end: &mut bool, attrs: &mut Vec, ) -> PResult<'a, Option>> { - Ok(match self.token.kind { + let (inner_attrs, body) = match self.token.kind { token::Semi => { - debug!("parse_assoc_fn_body(): parsing required method"); self.bump(); - *at_end = true; - None + (Vec::new(), None) } token::OpenDelim(token::Brace) => { - debug!("parse_assoc_fn_body(): parsing provided method"); - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) + let (attrs, body) = self.parse_inner_attrs_and_block()?; + (attrs, Some(body)) } token::Interpolated(ref nt) => match **nt { token::NtBlock(..) => { - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) + let (attrs, body) = self.parse_inner_attrs_and_block()?; + (attrs, Some(body)) } _ => return self.expected_semi_or_open_brace(), }, _ => return self.expected_semi_or_open_brace(), - }) + }; + attrs.extend(inner_attrs); + *at_end = true; + Ok(body) } /// Parses all the "front matter" for a `fn` declaration, up to diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index ae8f1e4db1b38..f3a69729399c1 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -199,7 +199,7 @@ impl<'a> Parser<'a> { } } - fn is_kw_followed_by_ident(&self, kw: Symbol) -> bool { + pub(super) fn is_kw_followed_by_ident(&self, kw: Symbol) -> bool { self.token.is_keyword(kw) && self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()) } diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 1ed80ed7350a9..990661bf6b5b9 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -36,18 +36,20 @@ impl BoundModifiers { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub(super) enum AllowPlus { Yes, No, } +#[derive(PartialEq)] pub(super) enum RecoverQPath { Yes, No, } // Is `...` (`CVarArgs`) legal at this level of type parsing? +#[derive(PartialEq)] enum AllowCVariadic { Yes, No, @@ -106,7 +108,7 @@ impl<'a> Parser<'a> { recover_qpath: RecoverQPath, allow_c_variadic: AllowCVariadic, ) -> PResult<'a, P> { - let allow_qpath_recovery = matches!(recover_qpath, RecoverQPath::Yes); + let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); maybe_whole!(self, NtTy, |x| x); @@ -142,7 +144,7 @@ impl<'a> Parser<'a> { self.parse_ty_bare_fn(lifetime_defs)? } else { let path = self.parse_path(PathStyle::Type)?; - let parse_plus = matches!(allow_plus, AllowPlus::Yes) && self.check_plus(); + let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)? } } else if self.eat_keyword(kw::Impl) { @@ -162,7 +164,7 @@ impl<'a> Parser<'a> { } else if self.token.is_path_start() { self.parse_path_start_ty(lo, allow_plus)? } else if self.eat(&token::DotDotDot) { - if let AllowCVariadic::Yes = allow_c_variadic { + if allow_c_variadic == AllowCVariadic::Yes { TyKind::CVarArgs } else { // FIXME(Centril): Should we just allow `...` syntactically @@ -200,7 +202,7 @@ impl<'a> Parser<'a> { if ts.len() == 1 && !trailing { let ty = ts.into_iter().nth(0).unwrap().into_inner(); - let maybe_bounds = matches!(allow_plus, AllowPlus::Yes) && self.token.is_like_plus(); + let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus(); match ty.kind { // `(TY_BOUND_NOPAREN) + BOUND + ...`. TyKind::Path(None, path) if maybe_bounds => { @@ -355,7 +357,7 @@ impl<'a> Parser<'a> { args: self.parse_mac_args()?, prior_type_ascription: self.last_type_ascription, })) - } else if matches!(allow_plus, AllowPlus::Yes) && self.check_plus() { + } else if allow_plus == AllowPlus::Yes && self.check_plus() { // `Trait1 + Trait2 + 'a` self.parse_remaining_bounds(Vec::new(), path, lo, true) } else { @@ -396,7 +398,7 @@ impl<'a> Parser<'a> { Ok(bound) => bounds.push(bound), Err(neg_sp) => negative_bounds.push(neg_sp), } - if matches!(allow_plus, AllowPlus::No) || !self.eat_plus() { + if allow_plus == AllowPlus::No || !self.eat_plus() { break; } } diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index b6ca2b3a595db..c6c201fa38ec1 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -302,19 +302,18 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_ty(self, t) } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, fd: &'v ast::FnDecl, s: Span, _: NodeId) { - self.record("FnDecl", Id::None, fd); - ast_visit::walk_fn(self, fk, fd, s) - } - - fn visit_trait_item(&mut self, ti: &'v ast::AssocItem) { - self.record("TraitItem", Id::None, ti); - ast_visit::walk_trait_item(self, ti) - } - - fn visit_impl_item(&mut self, ii: &'v ast::AssocItem) { - self.record("ImplItem", Id::None, ii); - ast_visit::walk_impl_item(self, ii) + fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, s: Span, _: NodeId) { + self.record("FnDecl", Id::None, fk.decl()); + ast_visit::walk_fn(self, fk, s) + } + + fn visit_assoc_item(&mut self, item: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) { + let label = match ctxt { + ast_visit::AssocCtxt::Trait => "TraitItem", + ast_visit::AssocCtxt::Impl => "ImplItem", + }; + self.record(label, Id::None, item); + ast_visit::walk_assoc_item(self, item, ctxt); } fn visit_param_bound(&mut self, bounds: &'v ast::GenericBound) { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c77b588d7fbc3..d6ea737385cdd 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -36,7 +36,7 @@ use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, Nod use syntax::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use syntax::ast::{Ident, Name}; use syntax::token::{self, Token}; -use syntax::visit::{self, Visitor}; +use syntax::visit::{self, AssocCtxt, Visitor}; use log::debug; use std::cell::Cell; @@ -1234,7 +1234,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { self.parent_scope.legacy = orig_current_legacy_scope; } - fn visit_trait_item(&mut self, item: &'b AssocItem) { + fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) { let parent = self.parent_scope.module; if let AssocItemKind::Macro(_) = item.kind { @@ -1242,6 +1242,12 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { return; } + if let AssocCtxt::Impl = ctxt { + self.resolve_visibility(&item.vis); + visit::walk_assoc_item(self, item, ctxt); + return; + } + // Add the item to the trait info. let item_def_id = self.r.definitions.local_def_id(item.id); let (res, ns) = match item.kind { @@ -1260,16 +1266,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let expansion = self.parent_scope.expansion; self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion)); - visit::walk_trait_item(self, item); - } - - fn visit_impl_item(&mut self, item: &'b ast::AssocItem) { - if let ast::AssocItemKind::Macro(..) = item.kind { - self.visit_invoc(item.id); - } else { - self.resolve_visibility(&item.vis); - visit::walk_impl_item(self, item); - } + visit::walk_assoc_item(self, item, ctxt); } fn visit_token(&mut self, t: Token) { diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 696ba0e994c7d..3a26197c1607a 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -125,7 +125,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { &sig.header, generics, &sig.decl, - Some(body), + body.as_deref(), ); } ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { @@ -213,39 +213,26 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { visit::walk_generic_param(self, param); } - fn visit_trait_item(&mut self, ti: &'a AssocItem) { - let def_data = match ti.kind { - AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(ti.ident.name), - AssocItemKind::TyAlias(..) => DefPathData::TypeNs(ti.ident.name), - AssocItemKind::Macro(..) => return self.visit_macro_invoc(ti.id), - }; - - let def = self.create_def(ti.id, def_data, ti.span); - self.with_parent(def, |this| visit::walk_trait_item(this, ti)); - } - - fn visit_impl_item(&mut self, ii: &'a AssocItem) { - let def_data = match ii.kind { - AssocItemKind::Fn(FnSig { ref header, ref decl }, ref body) - if header.asyncness.node.is_async() => - { + fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { + let def_data = match &i.kind { + AssocItemKind::Fn(FnSig { header, decl }, body) if header.asyncness.node.is_async() => { return self.visit_async_fn( - ii.id, - ii.ident.name, - ii.span, + i.id, + i.ident.name, + i.span, header, - &ii.generics, + &i.generics, decl, body.as_deref(), ); } - AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name), - AssocItemKind::TyAlias(..) => DefPathData::TypeNs(ii.ident.name), - AssocItemKind::Macro(..) => return self.visit_macro_invoc(ii.id), + AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name), + AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), + AssocItemKind::Macro(..) => return self.visit_macro_invoc(i.id), }; - let def = self.create_def(ii.id, def_data, ii.span); - self.with_parent(def, |this| visit::walk_impl_item(this, ii)); + let def = self.create_def(i.id, def_data, i.span); + self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); } fn visit_pat(&mut self, pat: &'a Pat) { diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index f1622af130e77..01a0e568137b2 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -24,7 +24,7 @@ use smallvec::{smallvec, SmallVec}; use syntax::ast::*; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; -use syntax::visit::{self, FnKind, Visitor}; +use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use syntax::{unwrap_or, walk_list}; use log::debug; @@ -437,7 +437,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { match foreign_item.kind { - ForeignItemKind::Fn(_, ref generics) => { + ForeignItemKind::Fn(_, ref generics, _) => { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { visit::walk_foreign_item(this, foreign_item); }); @@ -452,13 +452,15 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } } } - fn visit_fn(&mut self, fn_kind: FnKind<'ast>, declaration: &'ast FnDecl, sp: Span, _: NodeId) { - let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp)); - debug!("(resolving function) entering function"); + fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) { let rib_kind = match fn_kind { - FnKind::ItemFn(..) => FnItemRibKind, - FnKind::Method(..) | FnKind::Closure(_) => NormalRibKind, + FnKind::Fn(FnCtxt::Foreign, ..) => return visit::walk_fn(self, fn_kind, sp), + FnKind::Fn(FnCtxt::Free, ..) => FnItemRibKind, + FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind, }; + let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp)); + debug!("(resolving function) entering function"); + let declaration = fn_kind.decl(); // Create a value rib for the function. self.with_rib(ValueNS, rib_kind, |this| { @@ -471,8 +473,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { // Resolve the function body, potentially inside the body of an async closure match fn_kind { - FnKind::ItemFn(.., body) | FnKind::Method(.., body) => this.visit_block(body), - FnKind::Closure(body) => this.visit_expr(body), + FnKind::Fn(.., body) => walk_list!(this, visit_block, body), + FnKind::Closure(_, body) => this.visit_expr(body), }; debug!("(resolving function) leaving function"); @@ -843,12 +845,16 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }); } } - AssocItemKind::Fn(_, _) => { - visit::walk_trait_item(this, trait_item) - } - AssocItemKind::TyAlias(..) => { - visit::walk_trait_item(this, trait_item) - } + AssocItemKind::Fn(_, _) => visit::walk_assoc_item( + this, + trait_item, + AssocCtxt::Trait, + ), + AssocItemKind::TyAlias(..) => visit::walk_assoc_item( + this, + trait_item, + AssocCtxt::Trait, + ), AssocItemKind::Macro(_) => { panic!("unexpanded macro in resolve!") } @@ -1128,7 +1134,11 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ); this.with_constant_rib(|this| { - visit::walk_impl_item(this, impl_item) + visit::walk_assoc_item( + this, + impl_item, + AssocCtxt::Impl, + ) }); } AssocItemKind::Fn(..) => { @@ -1139,7 +1149,11 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { impl_item.span, |n, s| MethodNotMemberOfTrait(n, s)); - visit::walk_impl_item(this, impl_item); + visit::walk_assoc_item( + this, + impl_item, + AssocCtxt::Impl, + ) } AssocItemKind::TyAlias(_, _) => { // If this is a trait impl, ensure the type @@ -1149,7 +1163,11 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { impl_item.span, |n, s| TypeNotMemberOfTrait(n, s)); - visit::walk_impl_item(this, impl_item); + visit::walk_assoc_item( + this, + impl_item, + AssocCtxt::Impl, + ) } AssocItemKind::Macro(_) => panic!("unexpanded macro in resolve!"), diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3f436a1e27c2c..5ce81c104e17c 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -358,7 +358,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { decl: &'l ast::FnDecl, header: &'l ast::FnHeader, ty_params: &'l ast::Generics, - body: &'l ast::Block, + body: Option<&'l ast::Block>, ) { let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.nest_tables(item.id, |v| { @@ -392,7 +392,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } } - v.visit_block(&body); + walk_list!(v, visit_block, body); }); } @@ -1291,7 +1291,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { } } Fn(ref sig, ref ty_params, ref body) => { - self.process_fn(item, &sig.decl, &sig.header, ty_params, &body) + self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref()) } Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr), Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr), @@ -1515,7 +1515,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { let access = access_from!(self.save_ctxt, item, hir_id); match item.kind { - ast::ForeignItemKind::Fn(ref decl, ref generics) => { + ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { + let decl = &sig.decl; if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(fn_data, DefData, item.span); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 89054441fa3bf..e32f47443667b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -133,7 +133,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)) ); match item.kind { - ast::ForeignItemKind::Fn(ref decl, ref generics) => { + ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { @@ -142,7 +142,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, - value: make_signature(decl, generics), + value: make_signature(&sig.decl, generics), parent: None, children: vec![], decl_id: None, diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index dbf29b6531d2a..6401cabdcd5c1 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -723,7 +723,8 @@ impl Sig for ast::ForeignItem { fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let id = Some(self.id); match self.kind { - ast::ForeignItemKind::Fn(ref decl, ref generics) => { + ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { + let decl = &sig.decl; let mut text = String::new(); text.push_str("fn "); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5a8c9f76ea943..b22406124e098 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2533,6 +2533,17 @@ pub struct FnHeader { pub ext: Extern, } +impl FnHeader { + /// Does this function header have any qualifiers or is it empty? + pub fn has_qualifiers(&self) -> bool { + let Self { unsafety, asyncness, constness, ext } = self; + matches!(unsafety, Unsafety::Unsafe) + || asyncness.node.is_async() + || matches!(constness.node, Constness::Const) + || !matches!(ext, Extern::None) + } +} + impl Default for FnHeader { fn default() -> FnHeader { FnHeader { @@ -2565,7 +2576,7 @@ pub enum ItemKind { /// A function declaration (`fn`). /// /// E.g., `fn foo(bar: usize) -> usize { .. }`. - Fn(FnSig, Generics, P), + Fn(FnSig, Generics, Option>), /// A module declaration (`mod`). /// /// E.g., `mod foo;` or `mod foo { .. }`. @@ -2667,7 +2678,7 @@ pub type ForeignItem = Item; #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum ForeignItemKind { /// A foreign function. - Fn(P, Generics), + Fn(FnSig, Generics, Option>), /// A foreign static item (`static ext: u8`). Static(P, Mutability), /// A foreign type. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 3bcdf8fe286e4..8517f223f92e3 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -901,7 +901,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { ItemKind::Fn(sig, generics, body) => { visit_fn_sig(sig, vis); vis.visit_generics(generics); - vis.visit_block(body); + visit_opt(body, |body| vis.visit_block(body)); } ItemKind::Mod(m) => vis.visit_mod(m), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), @@ -1044,9 +1044,10 @@ pub fn noop_flat_map_foreign_item( visitor.visit_ident(ident); visit_attrs(attrs, visitor); match kind { - ForeignItemKind::Fn(fdec, generics) => { - visitor.visit_fn_decl(fdec); + ForeignItemKind::Fn(sig, generics, body) => { + visit_fn_sig(sig, visitor); visitor.visit_generics(generics); + visit_opt(body, |body| visitor.visit_block(body)); } ForeignItemKind::Static(t, _m) => visitor.visit_ty(t), ForeignItemKind::Ty => {} diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 946a0d29cd399..73e731397c329 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -19,24 +19,47 @@ use crate::tokenstream::{TokenStream, TokenTree}; use rustc_span::Span; +#[derive(Copy, Clone, PartialEq)] +pub enum AssocCtxt { + Trait, + Impl, +} + +#[derive(Copy, Clone, PartialEq)] +pub enum FnCtxt { + Free, + Foreign, + Assoc(AssocCtxt), +} + #[derive(Copy, Clone)] pub enum FnKind<'a> { - /// E.g., `fn foo()` or `extern "Abi" fn foo()`. - ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block), - - /// E.g., `fn foo(&self)`. - Method(Ident, &'a FnSig, &'a Visibility, &'a Block), + /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. + Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, Option<&'a Block>), /// E.g., `|x, y| body`. - Closure(&'a Expr), + Closure(&'a FnDecl, &'a Expr), } impl<'a> FnKind<'a> { pub fn header(&self) -> Option<&'a FnHeader> { match *self { - FnKind::ItemFn(_, header, _, _) => Some(header), - FnKind::Method(_, sig, _, _) => Some(&sig.header), - FnKind::Closure(_) => None, + FnKind::Fn(_, _, sig, _, _) => Some(&sig.header), + FnKind::Closure(_, _) => None, + } + } + + pub fn decl(&self) -> &'a FnDecl { + match self { + FnKind::Fn(_, _, sig, _, _) => &sig.decl, + FnKind::Closure(decl, _) => decl, + } + } + + pub fn ctxt(&self) -> Option { + match self { + FnKind::Fn(ctxt, ..) => Some(*ctxt), + FnKind::Closure(..) => None, } } } @@ -106,17 +129,11 @@ pub trait Visitor<'ast>: Sized { fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, s: Span, _: NodeId) { - walk_fn(self, fk, fd, s) - } - fn visit_trait_item(&mut self, i: &'ast AssocItem) { - walk_trait_item(self, i) + fn visit_fn(&mut self, fk: FnKind<'ast>, s: Span, _: NodeId) { + walk_fn(self, fk, s) } - fn visit_impl_item(&mut self, i: &'ast AssocItem) { - walk_impl_item(self, i) - } - fn visit_assoc_item(&mut self, i: &'ast AssocItem) { - walk_assoc_item(self, i) + fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) { + walk_assoc_item(self, i, ctxt) } fn visit_trait_ref(&mut self, t: &'ast TraitRef) { walk_trait_ref(self, t) @@ -287,13 +304,8 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { } ItemKind::Fn(ref sig, ref generics, ref body) => { visitor.visit_generics(generics); - visitor.visit_fn_header(&sig.header); - visitor.visit_fn( - FnKind::ItemFn(item.ident, &sig.header, &item.vis, body), - &sig.decl, - item.span, - item.id, - ) + let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id) } ItemKind::Mod(ref module) => visitor.visit_mod(module, item.span, &item.attrs, item.id), ItemKind::ForeignMod(ref foreign_module) => { @@ -321,17 +333,17 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); walk_list!(visitor, visit_trait_ref, of_trait); visitor.visit_ty(self_ty); - walk_list!(visitor, visit_impl_item, items); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { visitor.visit_generics(generics); visitor.visit_variant_data(struct_definition); } - ItemKind::Trait(.., ref generics, ref bounds, ref methods) => { + ItemKind::Trait(.., ref generics, ref bounds, ref items) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); - walk_list!(visitor, visit_trait_item, methods); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); } ItemKind::TraitAlias(ref generics, ref bounds) => { visitor.visit_generics(generics); @@ -512,21 +524,22 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { } } -pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a ForeignItem) { - visitor.visit_vis(&foreign_item.vis); - visitor.visit_ident(foreign_item.ident); +pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) { + visitor.visit_vis(&item.vis); + visitor.visit_ident(item.ident); - match foreign_item.kind { - ForeignItemKind::Fn(ref function_declaration, ref generics) => { - walk_fn_decl(visitor, function_declaration); - visitor.visit_generics(generics) + match item.kind { + ForeignItemKind::Fn(ref sig, ref generics, ref body) => { + visitor.visit_generics(generics); + let kind = FnKind::Fn(FnCtxt::Foreign, item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id); } ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), ForeignItemKind::Ty => (), ForeignItemKind::Macro(ref mac) => visitor.visit_mac(mac), } - walk_list!(visitor, visit_attribute, &foreign_item.attrs); + walk_list!(visitor, visit_attribute, &item.attrs); } pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) { @@ -594,37 +607,21 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: & visitor.visit_fn_ret_ty(&function_declaration.output); } -pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl, _span: Span) -where - V: Visitor<'a>, -{ +pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) { match kind { - FnKind::ItemFn(_, header, _, body) => { - visitor.visit_fn_header(header); - walk_fn_decl(visitor, declaration); - visitor.visit_block(body); - } - FnKind::Method(_, sig, _, body) => { + FnKind::Fn(_, _, sig, _, body) => { visitor.visit_fn_header(&sig.header); - walk_fn_decl(visitor, declaration); - visitor.visit_block(body); + walk_fn_decl(visitor, &sig.decl); + walk_list!(visitor, visit_block, body); } - FnKind::Closure(body) => { - walk_fn_decl(visitor, declaration); + FnKind::Closure(decl, body) => { + walk_fn_decl(visitor, decl); visitor.visit_expr(body); } } } -pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { - visitor.visit_assoc_item(item); -} - -pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { - visitor.visit_assoc_item(item); -} - -pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { +pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); walk_list!(visitor, visit_attribute, &item.attrs); @@ -634,17 +631,9 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(ref sig, None) => { - visitor.visit_fn_header(&sig.header); - walk_fn_decl(visitor, &sig.decl); - } - AssocItemKind::Fn(ref sig, Some(ref body)) => { - visitor.visit_fn( - FnKind::Method(item.ident, sig, &item.vis, body), - &sig.decl, - item.span, - item.id, - ); + AssocItemKind::Fn(ref sig, ref body) => { + let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id); } AssocItemKind::TyAlias(ref bounds, ref ty) => { walk_list!(visitor, visit_param_bound, bounds); @@ -765,8 +754,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(_, _, _, ref function_declaration, ref body, _decl_span) => visitor - .visit_fn(FnKind::Closure(body), function_declaration, expression.span, expression.id), + ExprKind::Closure(_, _, _, ref decl, ref body, _decl_span) => { + visitor.visit_fn(FnKind::Closure(decl, body), expression.span, expression.id) + } ExprKind::Block(ref block, ref opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); diff --git a/src/test/ui/extern/extern-ffi-fn-with-body.rs b/src/test/ui/extern/extern-ffi-fn-with-body.rs index 4cf563514ea60..ef234e8afd8ca 100644 --- a/src/test/ui/extern/extern-ffi-fn-with-body.rs +++ b/src/test/ui/extern/extern-ffi-fn-with-body.rs @@ -1,5 +1,5 @@ extern "C" { - fn foo() -> i32 { //~ ERROR incorrect `fn` inside `extern` block + fn foo() -> i32 { //~ ERROR incorrect function inside `extern` block return 0; } } diff --git a/src/test/ui/extern/extern-ffi-fn-with-body.stderr b/src/test/ui/extern/extern-ffi-fn-with-body.stderr index 4ac3ce1f93eab..079c9cecd8ed4 100644 --- a/src/test/ui/extern/extern-ffi-fn-with-body.stderr +++ b/src/test/ui/extern/extern-ffi-fn-with-body.stderr @@ -1,17 +1,17 @@ -error: incorrect `fn` inside `extern` block +error: incorrect function inside `extern` block --> $DIR/extern-ffi-fn-with-body.rs:2:8 | LL | extern "C" { - | ------ `extern` blocks define existing foreign functions and `fn`s inside of them cannot have a body + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body LL | fn foo() -> i32 { | ________^^^__________- | | | - | | can't have a body + | | cannot have a body LL | | return 0; LL | | } - | |_____- this body is invalid here + | |_____- help: remove the invalid body: `;` | - = help: you might have meant to write a function accessible through ffi, which can be done by writing `extern fn` outside of the `extern` block + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html error: aborting due to previous error diff --git a/src/test/ui/issues/issue-39616.rs b/src/test/ui/issues/issue-39616.rs index 3d8e28e5c2f52..428856a36b425 100644 --- a/src/test/ui/issues/issue-39616.rs +++ b/src/test/ui/issues/issue-39616.rs @@ -1,5 +1,4 @@ fn foo(a: [0; 1]) {} //~ ERROR expected type, found `0` -//~| ERROR expected one of `)`, `,`, `->`, `where`, or `{`, found `]` -// FIXME(jseyfried): avoid emitting the second error (preexisting) +//~| ERROR expected `;` or `{`, found `]` fn main() {} diff --git a/src/test/ui/issues/issue-39616.stderr b/src/test/ui/issues/issue-39616.stderr index 74e94eda51faa..ced582746617b 100644 --- a/src/test/ui/issues/issue-39616.stderr +++ b/src/test/ui/issues/issue-39616.stderr @@ -4,11 +4,11 @@ error: expected type, found `0` LL | fn foo(a: [0; 1]) {} | ^ expected type -error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]` +error: expected `;` or `{`, found `]` --> $DIR/issue-39616.rs:1:16 | LL | fn foo(a: [0; 1]) {} - | ^ expected one of `)`, `,`, `->`, `where`, or `{` + | ^ expected `;` or `{` error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr index 1139ef06a1263..92d1afe1b645a 100644 --- a/src/test/ui/macros/issue-54441.stderr +++ b/src/test/ui/macros/issue-54441.stderr @@ -1,8 +1,8 @@ -error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found keyword `let` +error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `static`, `type`, or `unsafe`, found keyword `let` --> $DIR/issue-54441.rs:3:9 | LL | let - | ^^^ expected one of `crate`, `fn`, `pub`, `static`, or `type` + | ^^^ expected one of 9 possible tokens ... LL | m!(); | ----- in this macro invocation diff --git a/src/test/ui/no-patterns-in-args-2.rs b/src/test/ui/no-patterns-in-args-2.rs index ccf57478b4850..85b7fc5cdba49 100644 --- a/src/test/ui/no-patterns-in-args-2.rs +++ b/src/test/ui/no-patterns-in-args-2.rs @@ -1,9 +1,9 @@ #![deny(patterns_in_fns_without_body)] trait Tr { - fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in methods without bodies + fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in functions without bodies //~^ WARN was previously accepted - fn f2(&arg: u8); //~ ERROR patterns aren't allowed in methods without bodies + fn f2(&arg: u8); //~ ERROR patterns aren't allowed in functions without bodies fn g1(arg: u8); // OK fn g2(_: u8); // OK #[allow(anonymous_parameters)] diff --git a/src/test/ui/no-patterns-in-args-2.stderr b/src/test/ui/no-patterns-in-args-2.stderr index 905a89af4e587..21f4439d89009 100644 --- a/src/test/ui/no-patterns-in-args-2.stderr +++ b/src/test/ui/no-patterns-in-args-2.stderr @@ -1,10 +1,10 @@ -error[E0642]: patterns aren't allowed in methods without bodies +error[E0642]: patterns aren't allowed in functions without bodies --> $DIR/no-patterns-in-args-2.rs:6:11 | LL | fn f2(&arg: u8); - | ^^^^ + | ^^^^ pattern not allowed in function without body -error: patterns aren't allowed in methods without bodies +error: patterns aren't allowed in functions without bodies --> $DIR/no-patterns-in-args-2.rs:4:11 | LL | fn f1(mut arg: u8); diff --git a/src/test/ui/no-patterns-in-args-macro.rs b/src/test/ui/no-patterns-in-args-macro.rs index 59cb99453987c..b5109f9c28696 100644 --- a/src/test/ui/no-patterns-in-args-macro.rs +++ b/src/test/ui/no-patterns-in-args-macro.rs @@ -6,10 +6,10 @@ macro_rules! m { type A = fn($pat: u8); - extern { + extern "C" { fn foreign_fn($pat: u8); } - } + }; } mod good_pat { @@ -20,7 +20,7 @@ mod bad_pat { m!((bad, pat)); //~^ ERROR patterns aren't allowed in function pointer types //~| ERROR patterns aren't allowed in foreign function declarations - //~| ERROR patterns aren't allowed in methods without bodies + //~| ERROR patterns aren't allowed in functions without bodies } fn main() {} diff --git a/src/test/ui/no-patterns-in-args-macro.stderr b/src/test/ui/no-patterns-in-args-macro.stderr index f21df68d5a2cc..0016c7953f344 100644 --- a/src/test/ui/no-patterns-in-args-macro.stderr +++ b/src/test/ui/no-patterns-in-args-macro.stderr @@ -1,8 +1,8 @@ -error[E0642]: patterns aren't allowed in methods without bodies +error[E0642]: patterns aren't allowed in functions without bodies --> $DIR/no-patterns-in-args-macro.rs:20:8 | LL | m!((bad, pat)); - | ^^^^^^^^^^ + | ^^^^^^^^^^ pattern not allowed in function without body error[E0561]: patterns aren't allowed in function pointer types --> $DIR/no-patterns-in-args-macro.rs:20:8 diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index bb17e97e950c6..a8f0b7d61b985 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -1,4 +1,4 @@ -// error-pattern:expected one of `(`, `fn`, `static`, or `type` +// error-pattern: expected one of `(`, `async`, `const`, `extern`, `fn` extern { pub pub fn foo(); } diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 313e88e812bb5..cba4058e48255 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,8 +1,8 @@ -error: expected one of `(`, `fn`, `static`, or `type`, found keyword `pub` +error: expected one of `(`, `async`, `const`, `extern`, `fn`, `static`, `type`, or `unsafe`, found keyword `pub` --> $DIR/duplicate-visibility.rs:3:9 | LL | pub pub fn foo(); - | ^^^ expected one of `(`, `fn`, `static`, or `type` + | ^^^ expected one of 8 possible tokens error: aborting due to previous error diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.rs b/src/test/ui/parser/fn-body-optional-semantic-fail.rs new file mode 100644 index 0000000000000..38def05e8f2b3 --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-semantic-fail.rs @@ -0,0 +1,27 @@ +// Tests the different rules for `fn` forms requiring the presence or lack of a body. + +fn main() { + fn f1(); //~ ERROR free function without a body + fn f2() {} // OK. + + trait X { + fn f1(); // OK. + fn f2() {} // OK. + } + + struct Y; + impl X for Y { + fn f1(); //~ ERROR associated function in `impl` without body + fn f2() {} // OK. + } + + impl Y { + fn f3(); //~ ERROR associated function in `impl` without body + fn f4() {} // OK. + } + + extern { + fn f5(); // OK. + fn f6() {} //~ ERROR incorrect function inside `extern` block + } +} diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.stderr b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr new file mode 100644 index 0000000000000..23ce98fb5d787 --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr @@ -0,0 +1,40 @@ +error: free function without a body + --> $DIR/fn-body-optional-semantic-fail.rs:4:5 + | +LL | fn f1(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ }` + +error: associated function in `impl` without body + --> $DIR/fn-body-optional-semantic-fail.rs:14:9 + | +LL | fn f1(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ }` + +error: associated function in `impl` without body + --> $DIR/fn-body-optional-semantic-fail.rs:19:9 + | +LL | fn f3(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ }` + +error: incorrect function inside `extern` block + --> $DIR/fn-body-optional-semantic-fail.rs:25:12 + | +LL | extern { + | ------ `extern` blocks define existing foreign functions and functions inside of them cannot have a body +LL | fn f5(); // OK. +LL | fn f6() {} + | ^^ -- help: remove the invalid body: `;` + | | + | cannot have a body + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/fn-body-optional-syntactic-pass.rs b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs new file mode 100644 index 0000000000000..e7991c73b4b77 --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs @@ -0,0 +1,31 @@ +// Ensures that all `fn` forms having or lacking a body are syntactically valid. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + fn f(); + fn f() {} + + trait X { + fn f(); + fn f() {} + } + + impl X for Y { + fn f(); + fn f() {} + } + + impl Y { + fn f(); + fn f() {} + } + + extern { + fn f(); + fn f() {} + } +} diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs new file mode 100644 index 0000000000000..c2b7e69c80d8e --- /dev/null +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -0,0 +1,57 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// edition:2018 + +#![feature(const_extern_fn)] +#![feature(const_fn)] + +fn main() { + async fn ff1() {} // OK. + unsafe fn ff2() {} // OK. + const fn ff3() {} // OK. + extern "C" fn ff4() {} // OK. + const /* async */ unsafe extern "C" fn ff5() {} // OK. + //^ FIXME(Centril): `async` should be legal syntactically, ensure it's illegal semantically. + + trait X { + async fn ft1(); //~ ERROR trait fns cannot be declared `async` + unsafe fn ft2(); // OK. + const fn ft3(); //~ ERROR trait fns cannot be declared const + extern "C" fn ft4(); // OK. + /* const */ async unsafe extern "C" fn ft5(); + //~^ ERROR trait fns cannot be declared `async` + //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically. + } + + struct Y; + impl X for Y { + async fn ft1() {} //~ ERROR trait fns cannot be declared `async` + //~^ ERROR method `ft1` has an incompatible type for trait + unsafe fn ft2() {} // OK. + const fn ft3() {} //~ ERROR trait fns cannot be declared const + extern "C" fn ft4() {} + /* const */ async unsafe extern "C" fn ft5() {} + //~^ ERROR trait fns cannot be declared `async` + //~| ERROR method `ft5` has an incompatible type for trait + //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically. + } + + impl Y { + async fn fi1() {} // OK. + unsafe fn fi2() {} // OK. + const fn fi3() {} // OK. + extern "C" fn fi4() {} // OK. + /* const */ async unsafe extern "C" fn fi5() {} // OK. + //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically. + } + + extern { + async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers + unsafe fn fe2(); //~ ERROR functions in `extern` blocks cannot have qualifiers + const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers + extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers + /* const */ async unsafe extern "C" fn fe5(); + //~^ ERROR functions in `extern` blocks cannot have qualifiers + //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically. + } +} diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr new file mode 100644 index 0000000000000..41d2d9b7faaf1 --- /dev/null +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -0,0 +1,136 @@ +error[E0706]: trait fns cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:17:9 + | +LL | async fn ft1(); + | ^^^^^^^^^^^^^^^ + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0379]: trait fns cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:19:9 + | +LL | const fn ft3(); + | ^^^^^ trait fns cannot be const + +error[E0706]: trait fns cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:21:21 + | +LL | /* const */ async unsafe extern "C" fn ft5(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0706]: trait fns cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:28:9 + | +LL | async fn ft1() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0379]: trait fns cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:31:9 + | +LL | const fn ft3() {} + | ^^^^^ trait fns cannot be const + +error[E0706]: trait fns cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:33:21 + | +LL | /* const */ async unsafe extern "C" fn ft5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:49:18 + | +LL | extern { + | ------ in this `extern` block +LL | async fn fe1(); + | ---------^^^ + | | + | help: remove the qualifiers: `fn` + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:50:19 + | +LL | extern { + | ------ in this `extern` block +LL | async fn fe1(); +LL | unsafe fn fe2(); + | ----------^^^ + | | + | help: remove the qualifiers: `fn` + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:51:18 + | +LL | extern { + | ------ in this `extern` block +... +LL | const fn fe3(); + | ---------^^^ + | | + | help: remove the qualifiers: `fn` + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:52:23 + | +LL | extern { + | ------ in this `extern` block +... +LL | extern "C" fn fe4(); + | --------------^^^ + | | + | help: remove the qualifiers: `fn` + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:53:48 + | +LL | extern { + | ------ in this `extern` block +... +LL | /* const */ async unsafe extern "C" fn fe5(); + | ---------------------------^^^ + | | + | help: remove the qualifiers: `fn` + +error[E0053]: method `ft1` has an incompatible type for trait + --> $DIR/fn-header-semantic-fail.rs:28:24 + | +LL | async fn ft1(); + | - type in trait +... +LL | async fn ft1() {} + | ^ + | | + | the `Output` of this `async fn`'s found opaque type + | expected `()`, found opaque type + | + = note: expected fn pointer `fn()` + found fn pointer `fn() -> impl std::future::Future` + +error[E0053]: method `ft5` has an incompatible type for trait + --> $DIR/fn-header-semantic-fail.rs:33:54 + | +LL | /* const */ async unsafe extern "C" fn ft5(); + | - type in trait +... +LL | /* const */ async unsafe extern "C" fn ft5() {} + | ^ + | | + | the `Output` of this `async fn`'s found opaque type + | expected `()`, found opaque type + | + = note: expected fn pointer `unsafe extern "C" fn()` + found fn pointer `unsafe extern "C" fn() -> impl std::future::Future` + +error: aborting due to 13 previous errors + +Some errors have detailed explanations: E0053, E0379, E0706. +For more information about an error, try `rustc --explain E0053`. diff --git a/src/test/ui/parser/fn-header-syntactic-pass.rs b/src/test/ui/parser/fn-header-syntactic-pass.rs new file mode 100644 index 0000000000000..145a208cb249d --- /dev/null +++ b/src/test/ui/parser/fn-header-syntactic-pass.rs @@ -0,0 +1,55 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// check-pass +// edition:2018 + +#![feature(const_extern_fn)] +//^ FIXME(Centril): move check to ast_validation. + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const /* async */ unsafe extern "C" fn f(); + //^ FIXME(Centril): `async` should be legal syntactically. + + trait X { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + /* const */ async unsafe extern "C" fn f(); + //^ FIXME(Centril): `const` should be legal syntactically. + } + + impl X for Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + /* const */ async unsafe extern "C" fn f(); + //^ FIXME(Centril): `const` should be legal syntactically. + } + + impl Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + /* const */ async unsafe extern "C" fn f(); + //^ FIXME(Centril): `const` should be legal syntactically. + } + + extern { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + /* const */ async unsafe extern "C" fn f(); + //^ FIXME(Centril): `const` should be legal syntactically. + } +} diff --git a/src/test/ui/parser/issue-24780.rs b/src/test/ui/parser/issue-24780.rs index 799cdd8022257..8b46aa2bf22a1 100644 --- a/src/test/ui/parser/issue-24780.rs +++ b/src/test/ui/parser/issue-24780.rs @@ -3,6 +3,6 @@ // expected one of ..., `>`, ... found `>` fn foo() -> Vec> { - //~^ ERROR expected one of `!`, `+`, `::`, `where`, or `{`, found `>` + //~^ ERROR expected `;` or `{`, found `>` Vec::new() } diff --git a/src/test/ui/parser/issue-24780.stderr b/src/test/ui/parser/issue-24780.stderr index d9470191b25a4..d65a5f448739a 100644 --- a/src/test/ui/parser/issue-24780.stderr +++ b/src/test/ui/parser/issue-24780.stderr @@ -1,8 +1,8 @@ -error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>` +error: expected `;` or `{`, found `>` --> $DIR/issue-24780.rs:5:23 | LL | fn foo() -> Vec> { - | ^ expected one of `!`, `+`, `::`, `where`, or `{` + | ^ expected `;` or `{` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-63135.rs b/src/test/ui/parser/issue-63135.rs index d5f5f1469f35a..7d46b8904f033 100644 --- a/src/test/ui/parser/issue-63135.rs +++ b/src/test/ui/parser/issue-63135.rs @@ -1,3 +1,3 @@ -// error-pattern: aborting due to 6 previous errors +// error-pattern: aborting due to 7 previous errors fn i(n{...,f # diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr index 462fdf11f40a9..04afae93be0e5 100644 --- a/src/test/ui/parser/issue-63135.stderr +++ b/src/test/ui/parser/issue-63135.stderr @@ -43,5 +43,11 @@ error: expected one of `:` or `|`, found `)` LL | fn i(n{...,f # | ^ expected one of `:` or `|` -error: aborting due to 6 previous errors +error: expected `;` or `{`, found `` + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | ^ expected `;` or `{` + +error: aborting due to 7 previous errors diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs index c35236ce7934e..810dee9571d81 100644 --- a/src/test/ui/parser/missing_right_paren.rs +++ b/src/test/ui/parser/missing_right_paren.rs @@ -1,3 +1,3 @@ // ignore-tidy-trailing-newlines -// error-pattern: aborting due to 3 previous errors +// error-pattern: aborting due to 4 previous errors fn main((ؼ \ No newline at end of file diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr index d67e7c88912a5..c1ceb81a07c47 100644 --- a/src/test/ui/parser/missing_right_paren.stderr +++ b/src/test/ui/parser/missing_right_paren.stderr @@ -22,5 +22,11 @@ error: expected one of `:` or `|`, found `)` LL | fn main((ؼ | ^ expected one of `:` or `|` -error: aborting due to 3 previous errors +error: expected `;` or `{`, found `` + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | ^ expected `;` or `{` + +error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.rs b/src/test/ui/parser/no-const-fn-in-extern-block.rs index 29f26389ded18..4cae703a16395 100644 --- a/src/test/ui/parser/no-const-fn-in-extern-block.rs +++ b/src/test/ui/parser/no-const-fn-in-extern-block.rs @@ -1,8 +1,8 @@ extern { const fn foo(); - //~^ ERROR extern items cannot be `const` + //~^ ERROR functions in `extern` blocks cannot have qualifiers const unsafe fn bar(); - //~^ ERROR extern items cannot be `const` + //~^ ERROR functions in `extern` blocks cannot have qualifiers } fn main() {} diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.stderr b/src/test/ui/parser/no-const-fn-in-extern-block.stderr index 5b4663a702f06..de653987e406d 100644 --- a/src/test/ui/parser/no-const-fn-in-extern-block.stderr +++ b/src/test/ui/parser/no-const-fn-in-extern-block.stderr @@ -1,14 +1,23 @@ -error: extern items cannot be `const` - --> $DIR/no-const-fn-in-extern-block.rs:2:5 +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/no-const-fn-in-extern-block.rs:2:14 | +LL | extern { + | ------ in this `extern` block LL | const fn foo(); - | ^^^^^ + | ---------^^^ + | | + | help: remove the qualifiers: `fn` -error: extern items cannot be `const` - --> $DIR/no-const-fn-in-extern-block.rs:4:5 +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/no-const-fn-in-extern-block.rs:4:21 | +LL | extern { + | ------ in this `extern` block +... LL | const unsafe fn bar(); - | ^^^^^ + | ----------------^^^ + | | + | help: remove the qualifiers: `fn` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr index 90246b92bf0fa..dce54655fa027 100644 --- a/src/test/ui/parser/not-a-pred.stderr +++ b/src/test/ui/parser/not-a-pred.stderr @@ -1,8 +1,8 @@ -error: expected one of `->`, `where`, or `{`, found `:` +error: expected `;` or `{`, found `:` --> $DIR/not-a-pred.rs:3:26 | LL | fn f(a: isize, b: isize) : lt(a, b) { } - | ^ expected one of `->`, `where`, or `{` + | ^ expected `;` or `{` error: aborting due to previous error From 4fc4b951f1da755298aea69f10a4951745ee8501 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 5 Feb 2020 01:43:03 +0100 Subject: [PATCH 0900/1253] Make associated item lookup a query --- src/librustc/query/mod.rs | 5 +++++ src/librustc/ty/mod.rs | 31 ++++++++++--------------------- src/librustc_ty/ty.rs | 9 +++++++++ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 37d5e23535b81..228271e0c4c3a 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -310,6 +310,11 @@ rustc_queries! { /// Maps from a trait item to the trait item "descriptor". query associated_item(_: DefId) -> ty::AssocItem {} + /// Collects the associated items defined on a trait or impl. + query associated_items(key: DefId) -> ty::AssocItemsIterator<'tcx> { + desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) } + } + query impl_trait_ref(_: DefId) -> Option> {} query impl_polarity(_: DefId) -> ty::ImplPolarity {} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f417b907a3811..028a88a6c82b3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2741,19 +2741,6 @@ impl<'tcx> TyCtxt<'tcx> { variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id)) } - pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> { - // Ideally, we would use `-> impl Iterator` here, but it falls - // afoul of the conservative "capture [restrictions]" we put - // in place, so we use a hand-written iterator. - // - // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 - AssocItemsIterator { - tcx: self, - def_ids: self.associated_item_def_ids(def_id), - next_index: 0, - } - } - /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated #[marker] and prevents item overrides. pub fn impls_are_allowed_to_overlap( @@ -2993,20 +2980,22 @@ impl<'tcx> TyCtxt<'tcx> { } } -#[derive(Clone)] +#[derive(Copy, Clone, HashStable)] pub struct AssocItemsIterator<'tcx> { - tcx: TyCtxt<'tcx>, - def_ids: &'tcx [DefId], - next_index: usize, + pub items: &'tcx [AssocItem], } -impl Iterator for AssocItemsIterator<'_> { +impl<'tcx> Iterator for AssocItemsIterator<'tcx> { type Item = AssocItem; + #[inline] fn next(&mut self) -> Option { - let def_id = self.def_ids.get(self.next_index)?; - self.next_index += 1; - Some(self.tcx.associated_item(*def_id)) + if let Some((first, rest)) = self.items.split_first() { + self.items = rest; + Some(*first) + } else { + None + } } } diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 8f882be1a090e..e2a9b821b4a0a 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -206,6 +206,14 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { } } +fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AssocItemsIterator<'tcx> { + ty::AssocItemsIterator { + items: tcx.arena.alloc_from_iter( + tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)), + ), + } +} + fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { tcx.hir().span_if_local(def_id).unwrap() } @@ -356,6 +364,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { asyncness, associated_item, associated_item_def_ids, + associated_items, adt_sized_constraint, def_span, param_env, From 67c29ed8fc8d2aa6e6b86cb02f4596c5d222b704 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Feb 2020 02:04:14 +0100 Subject: [PATCH 0901/1253] lowering: add recursion_limit = 256 --- src/librustc_ast_lowering/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index cd33bf6547be0..5816a64fca52c 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -32,6 +32,7 @@ #![feature(array_value_iter)] #![feature(crate_visibility_modifier)] +#![recursion_limit = "256"] use rustc::arena::Arena; use rustc::dep_graph::DepGraph; From 319dd6f139377259ceca7db35069b382446ee3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 19:01:31 -0800 Subject: [PATCH 0902/1253] When suggesting associated fn with type parameters, include in the structured suggestion --- src/librustc_typeck/check/mod.rs | 85 ++++++++++++++++++- ...sing-assoc-fn-applicable-suggestions.fixed | 21 +++++ ...missing-assoc-fn-applicable-suggestions.rs | 18 ++++ ...ing-assoc-fn-applicable-suggestions.stderr | 16 ++++ src/test/ui/suggestions/missing-assoc-fn.rs | 22 +++++ .../ui/suggestions/missing-assoc-fn.stderr | 36 ++++++++ 6 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed create mode 100644 src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs create mode 100644 src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr create mode 100644 src/test/ui/suggestions/missing-assoc-fn.rs create mode 100644 src/test/ui/suggestions/missing-assoc-fn.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d0275429747b6..678f837db96fd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2157,8 +2157,77 @@ fn missing_items_err( err.emit(); } +/// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions. +fn bounds_from_generic_predicates( + tcx: TyCtxt<'_>, + predicates: ty::GenericPredicates<'_>, +) -> (String, String) { + let mut types: FxHashMap, Vec> = FxHashMap::default(); + let mut projections = vec![]; + for (predicate, _) in predicates.predicates { + debug!("predicate {:?}", predicate); + match predicate { + ty::Predicate::Trait(trait_predicate, _) => { + let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default(); + let def_id = trait_predicate.skip_binder().def_id(); + if Some(def_id) != tcx.lang_items().sized_trait() { + // Type params are `Sized` by default, do not add that restriction to the list + // if it is a positive requirement. + entry.push(trait_predicate.skip_binder().def_id()); + } + } + ty::Predicate::Projection(projection_pred) => { + projections.push(projection_pred); + } + _ => {} + } + } + let generics = if types.is_empty() { + "".to_string() + } else { + format!( + "<{}>", + types + .keys() + .filter_map(|t| match t.kind { + ty::Param(_) => Some(t.to_string()), + // Avoid suggesting the following: + // fn foo::Bar>(_: T) where T: Trait, ::Bar: Other {} + _ => None, + }) + .collect::>() + .join(", ") + ) + }; + let mut where_clauses = vec![]; + for (ty, bounds) in types { + for bound in &bounds { + where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound))); + } + } + for projection in &projections { + let p = projection.skip_binder(); + // FIXME: this is not currently supported syntax, we should be looking at the `types` and + // insert the associated types where they correspond, but for now lets be "lazy" and + // propose this instead of the following valid resugaring: + // `T: Trait, Trait::Assoc = K` → `T: Trait` + where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty)); + } + let where_clauses = if where_clauses.is_empty() { + String::new() + } else { + format!(" where {}", where_clauses.join(", ")) + }; + (generics, where_clauses) +} + /// Return placeholder code for the given function. -fn fn_sig_suggestion(sig: &ty::FnSig<'_>, ident: Ident) -> String { +fn fn_sig_suggestion( + tcx: TyCtxt<'_>, + sig: &ty::FnSig<'_>, + ident: Ident, + predicates: ty::GenericPredicates<'_>, +) -> String { let args = sig .inputs() .iter() @@ -2188,12 +2257,17 @@ fn fn_sig_suggestion(sig: &ty::FnSig<'_>, ident: Ident) -> String { let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() }; let unsafety = sig.unsafety.prefix_str(); + let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates); + // FIXME: this is not entirely correct, as the lifetimes from borrowed params will // not be present in the `fn` definition, not will we account for renamed // lifetimes between the `impl` and the `trait`, but this should be good enough to // fill in a significant portion of the missing code, and other subsequent // suggestions can help the user fix the code. - format!("{}fn {}({}){} {{ unimplemented!() }}", unsafety, ident, args, output) + format!( + "{}fn {}{}({}){}{} {{ unimplemented!() }}", + unsafety, ident, generics, args, output, where_clauses + ) } /// Return placeholder code for the given associated item. @@ -2206,7 +2280,12 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { // late-bound regions, and we don't want method signatures to show up // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound // regions just fine, showing `fn(&MyType)`. - fn_sig_suggestion(tcx.fn_sig(assoc.def_id).skip_binder(), assoc.ident) + fn_sig_suggestion( + tcx, + tcx.fn_sig(assoc.def_id).skip_binder(), + assoc.ident, + tcx.predicates_of(assoc.def_id), + ) } ty::AssocKind::Type => format!("type {} = Type;", assoc.ident), // FIXME(type_alias_impl_trait): we should print bounds here too. diff --git a/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed new file mode 100644 index 0000000000000..00a712e5722a7 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed @@ -0,0 +1,21 @@ +// run-rustfix +trait TraitB { + type Item; +} + +trait TraitA { + type Type; + fn bar(_: T) -> Self; + fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; +} + +struct S; +struct Type; + +impl TraitA<()> for S { //~ ERROR not all trait items implemented +fn baz(_: T) -> Self where T: TraitB, ::Item: std::marker::Copy { unimplemented!() } +fn bar(_: T) -> Self { unimplemented!() } +type Type = Type; +} + +fn main() {} diff --git a/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs new file mode 100644 index 0000000000000..c80ede1b2be23 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs @@ -0,0 +1,18 @@ +// run-rustfix +trait TraitB { + type Item; +} + +trait TraitA { + type Type; + fn bar(_: T) -> Self; + fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; +} + +struct S; +struct Type; + +impl TraitA<()> for S { //~ ERROR not all trait items implemented +} + +fn main() {} diff --git a/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr new file mode 100644 index 0000000000000..ee29a56f3f8c5 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr @@ -0,0 +1,16 @@ +error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz` + --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1 + | +LL | type Type; + | ---------- `Type` from trait +LL | fn bar(_: T) -> Self; + | ------------------------ `bar` from trait +LL | fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; + | ------------------------------------------------------------------- `baz` from trait +... +LL | impl TraitA<()> for S { + | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/suggestions/missing-assoc-fn.rs b/src/test/ui/suggestions/missing-assoc-fn.rs new file mode 100644 index 0000000000000..9af8e5a939d65 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-fn.rs @@ -0,0 +1,22 @@ +trait TraitB { + type Item; +} + +trait TraitA { + fn foo>(_: T) -> Self; + fn bar(_: T) -> Self; + fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; + fn bat>(_: T) -> Self; //~ ERROR associated type bounds are unstable +} + +struct S; + +impl TraitA<()> for S { //~ ERROR not all trait items implemented +} + +use std::iter::FromIterator; +struct X; +impl FromIterator<()> for X { //~ ERROR not all trait items implemented +} + +fn main() {} diff --git a/src/test/ui/suggestions/missing-assoc-fn.stderr b/src/test/ui/suggestions/missing-assoc-fn.stderr new file mode 100644 index 0000000000000..bed8bffe38d73 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-fn.stderr @@ -0,0 +1,36 @@ +error[E0658]: associated type bounds are unstable + --> $DIR/missing-assoc-fn.rs:9:22 + | +LL | fn bat>(_: T) -> Self; + | ^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + +error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `baz`, `bat` + --> $DIR/missing-assoc-fn.rs:14:1 + | +LL | fn foo>(_: T) -> Self; + | ------------------------------------------ `foo` from trait +LL | fn bar(_: T) -> Self; + | ------------------------ `bar` from trait +LL | fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; + | ------------------------------------------------------------------- `baz` from trait +LL | fn bat>(_: T) -> Self; + | -------------------------------------------- `bat` from trait +... +LL | impl TraitA<()> for S { + | ^^^^^^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `baz`, `bat` in implementation + +error[E0046]: not all trait items implemented, missing: `from_iter` + --> $DIR/missing-assoc-fn.rs:19:1 + | +LL | impl FromIterator<()> for X { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation + | + = help: implement the missing item: `fn from_iter(_: T) -> Self where T: std::iter::IntoIterator, std::iter::IntoIterator::Item = A { unimplemented!() }` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0046, E0658. +For more information about an error, try `rustc --explain E0046`. From 01dd376dedc7fe1389138565fe8a7a0cdb332f47 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Feb 2020 02:57:30 +0100 Subject: [PATCH 0903/1253] `#![recursion_limit = "X"]`: note current crate name. --- src/librustc/traits/error_reporting/suggestions.rs | 4 ++-- src/librustc_expand/expand.rs | 4 ++-- src/librustc_typeck/check/autoderef.rs | 4 ++-- src/test/ui/did_you_mean/recursion_limit.stderr | 2 +- src/test/ui/did_you_mean/recursion_limit_deref.stderr | 2 +- src/test/ui/did_you_mean/recursion_limit_macro.stderr | 2 +- src/test/ui/error-codes/E0055.stderr | 2 +- src/test/ui/error-codes/E0275.stderr | 2 +- src/test/ui/infinite/infinite-autoderef.stderr | 6 +++--- src/test/ui/infinite/infinite-macro-expansion.stderr | 2 +- src/test/ui/issues/issue-16098.stderr | 2 +- src/test/ui/issues/issue-18400.stderr | 2 +- src/test/ui/issues/issue-20413.stderr | 4 ++-- src/test/ui/issues/issue-23122-2.stderr | 4 ++-- src/test/ui/issues/issue-38940.stderr | 2 +- src/test/ui/macros/trace_faulty_macros.stderr | 2 +- 16 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c1facd34dfee5..b2973c642a21e 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -1646,8 +1646,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let current_limit = self.tcx.sess.recursion_limit.get(); let suggested_limit = current_limit * 2; err.help(&format!( - "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", - suggested_limit + "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)", + suggested_limit, self.tcx.crate_name, )); } } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index f08bed5731530..20b9172642475 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -599,8 +599,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { &format!("recursion limit reached while expanding `{}`", expn_data.kind.descr()), ); err.help(&format!( - "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", - suggested_limit + "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)", + suggested_limit, self.cx.ecfg.crate_name, )); err.emit(); self.cx.trace_macros_diag(); diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index e4dec97183c7d..d436733d19a36 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -250,8 +250,8 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa ) .span_label(span, "deref recursion limit reached") .help(&format!( - "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", - suggested_limit + "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)", + suggested_limit, tcx.crate_name, )) .emit(); } diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index b05b92bf1e94b..fc14b7fa5b75c 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -7,7 +7,7 @@ LL | fn is_send() { } LL | is_send::(); | ^^^^^^^^^^^^ | - = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit`) = note: required because it appears within the type `I` = note: required because it appears within the type `H` = note: required because it appears within the type `G` diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index fdbb5af9b3243..e8d11530b08aa 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr @@ -4,7 +4,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `I` LL | let x: &Bottom = &t; | ^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit_deref`) error[E0308]: mismatched types --> $DIR/recursion_limit_deref.rs:50:22 diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index 1cc59051605cd..18d321c24d80c 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -7,7 +7,7 @@ LL | ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); | -------------------------------------------------- in this macro invocation | - = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit_macro`) error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr index d06566ffbe9a9..01411e585abdd 100644 --- a/src/test/ui/error-codes/E0055.stderr +++ b/src/test/ui/error-codes/E0055.stderr @@ -4,7 +4,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` LL | ref_foo.foo(); | ^^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="10"]` attribute to your crate + = help: consider adding a `#![recursion_limit="10"]` attribute to your crate (`E0055`) error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index 1d087a465942e..c551a00096e23 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -7,7 +7,7 @@ LL | trait Foo {} LL | impl Foo for T where Bar: Foo {} | ^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`E0275`) = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index 8c59fbd530129..e7d90f00d24de 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr @@ -13,7 +13,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` LL | Foo.foo; | ^^^^^^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`infinite_autoderef`) error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:25:9 @@ -21,7 +21,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` LL | Foo.foo; | ^^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`infinite_autoderef`) error[E0609]: no field `foo` on type `Foo` --> $DIR/infinite-autoderef.rs:25:9 @@ -35,7 +35,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` LL | Foo.bar(); | ^^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`infinite_autoderef`) error[E0599]: no method named `bar` found for struct `Foo` in the current scope --> $DIR/infinite-autoderef.rs:26:9 diff --git a/src/test/ui/infinite/infinite-macro-expansion.stderr b/src/test/ui/infinite/infinite-macro-expansion.stderr index 159312e5c1b53..ff67eea568866 100644 --- a/src/test/ui/infinite/infinite-macro-expansion.stderr +++ b/src/test/ui/infinite/infinite-macro-expansion.stderr @@ -7,7 +7,7 @@ LL | () => (recursive!()) LL | recursive!() | ------------ in this macro invocation | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`infinite_macro_expansion`) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16098.stderr b/src/test/ui/issues/issue-16098.stderr index 2b9657d46283b..a34039a6eec7d 100644 --- a/src/test/ui/issues/issue-16098.stderr +++ b/src/test/ui/issues/issue-16098.stderr @@ -7,7 +7,7 @@ LL | $n + prob1!($n - 1); LL | println!("Problem 1: {}", prob1!(1000)); | ------------ in this macro invocation | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_16098`) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18400.stderr b/src/test/ui/issues/issue-18400.stderr index 85cfa5663f13c..57067ad51759a 100644 --- a/src/test/ui/issues/issue-18400.stderr +++ b/src/test/ui/issues/issue-18400.stderr @@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `_: std::marker::Sized` LL | 0.contains(bits); | ^^^^^^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_18400`) = note: required because of the requirements on the impl of `Set<&[_]>` for `{integer}` = note: required because of the requirements on the impl of `Set<&[&[_]]>` for `{integer}` = note: required because of the requirements on the impl of `Set<&[&[&[_]]]>` for `{integer}` diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index e765144ff0b48..84e64ff74ae96 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -15,7 +15,7 @@ LL | trait Foo { LL | impl Foo for T where NoData: Foo { | ^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_20413`) = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` @@ -153,7 +153,7 @@ LL | trait Foo { LL | impl Foo for T where NoData: Foo { | ^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_20413`) = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index d2c1421e29e0e..7625e30498ac3 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<< LL | impl Next for GetNext { | ^^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_23122_2`) = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: std::marker::Sized` @@ -13,7 +13,7 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<< LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider adding a `#![recursion_limit="256"]` attribute to your crate + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_23122_2`) = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr index f60387f841aed..36117278fd814 100644 --- a/src/test/ui/issues/issue-38940.stderr +++ b/src/test/ui/issues/issue-38940.stderr @@ -4,7 +4,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `I` LL | let x: &Bottom = &t; | ^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`issue_38940`) error[E0308]: mismatched types --> $DIR/issue-38940.rs:43:22 diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 4e86daffb61ba..021c51fd726d3 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -29,7 +29,7 @@ LL | my_recursive_macro!(); LL | my_recursive_macro!(); | ---------------------- in this macro invocation | - = help: consider adding a `#![recursion_limit="8"]` attribute to your crate + = help: consider adding a `#![recursion_limit="8"]` attribute to your crate (`trace_faulty_macros`) note: trace_macro --> $DIR/trace_faulty_macros.rs:34:5 From ce6cd6709f94a7eb68b4944c054117c285a4b258 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Feb 2020 03:58:41 +0100 Subject: [PATCH 0904/1253] or_patterns: add regression test for 68785 --- .../issue-68785-irrefutable-param-with-at.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs diff --git a/src/test/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs b/src/test/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs new file mode 100644 index 0000000000000..1a65a1e544b9e --- /dev/null +++ b/src/test/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(or_patterns)] + +enum MyEnum { + FirstCase(u8), + OtherCase(u16), +} + +fn my_fn(x @ (MyEnum::FirstCase(_) | MyEnum::OtherCase(_)): MyEnum) {} + +fn main() { + my_fn(MyEnum::FirstCase(0)); +} From 9ac68e128b112e312cfde264d04b9d374a4402d0 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Tue, 4 Feb 2020 23:04:29 -0500 Subject: [PATCH 0905/1253] stop using BytePos for computing spans in librustc_parse/parser/mod.rs --- src/librustc_parse/parser/mod.rs | 39 +++++++++++++++----------- src/test/ui/parser/issue-68730.stderr | Bin 957 -> 956 bytes 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 8c1839da1cb8f..825607a234859 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -21,7 +21,7 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; +use rustc_span::{FileName, Span, DUMMY_SP}; use syntax::ast::{self, AttrStyle, AttrVec, CrateSugar, Extern, Ident, Unsafety, DUMMY_NODE_ID}; use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; use syntax::ptr::P; @@ -615,8 +615,8 @@ impl<'a> Parser<'a> { true } token::BinOpEq(token::Plus) => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - self.bump_with(token::Eq, span); + let start_point = self.sess.source_map().start_point(self.token.span); + self.bump_with(token::Eq, self.token.span.with_lo(start_point.hi())); true } _ => false, @@ -633,8 +633,9 @@ impl<'a> Parser<'a> { Ok(()) } token::AndAnd => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - Ok(self.bump_with(token::BinOp(token::And), span)) + let start_point = self.sess.source_map().start_point(self.token.span); + Ok(self + .bump_with(token::BinOp(token::And), self.token.span.with_lo(start_point.hi()))) } _ => self.unexpected(), } @@ -650,8 +651,9 @@ impl<'a> Parser<'a> { Ok(()) } token::OrOr => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - Ok(self.bump_with(token::BinOp(token::Or), span)) + let start_point = self.sess.source_map().start_point(self.token.span); + Ok(self + .bump_with(token::BinOp(token::Or), self.token.span.with_lo(start_point.hi()))) } _ => self.unexpected(), } @@ -671,13 +673,16 @@ impl<'a> Parser<'a> { true } token::BinOp(token::Shl) => { - let span = self.sess.source_map().next_point(self.token.span); - self.bump_with(token::Lt, span); + let start_point = self.sess.source_map().start_point(self.token.span); + self.bump_with(token::Lt, self.token.span.with_lo(start_point.hi())); true } token::LArrow => { - let span = self.sess.source_map().next_point(self.token.span); - self.bump_with(token::BinOp(token::Minus), span); + let start_point = self.sess.source_map().start_point(self.token.span); + self.bump_with( + token::BinOp(token::Minus), + self.token.span.with_lo(start_point.hi()), + ); true } _ => false, @@ -707,16 +712,16 @@ impl<'a> Parser<'a> { Some(()) } token::BinOp(token::Shr) => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - Some(self.bump_with(token::Gt, span)) + let start_point = self.sess.source_map().start_point(self.token.span); + Some(self.bump_with(token::Gt, self.token.span.with_lo(start_point.hi()))) } token::BinOpEq(token::Shr) => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - Some(self.bump_with(token::Ge, span)) + let start_point = self.sess.source_map().start_point(self.token.span); + Some(self.bump_with(token::Ge, self.token.span.with_lo(start_point.hi()))) } token::Ge => { - let span = self.token.span.with_lo(self.token.span.lo() + BytePos(1)); - Some(self.bump_with(token::Eq, span)) + let start_point = self.sess.source_map().start_point(self.token.span); + Some(self.bump_with(token::Eq, self.token.span.with_lo(start_point.hi()))) } _ => None, }; diff --git a/src/test/ui/parser/issue-68730.stderr b/src/test/ui/parser/issue-68730.stderr index 5f9ed56e2d7e9fe3fb822cc5a40648bf6b146dd6..090b41d839f82b68c11fe38111b9fda254aa39b0 100644 GIT binary patch delta 15 WcmdnXzK4B-3G-w@Cbh}Y%t-(!wFHg; delta 16 XcmdnPzL$N22{WVN#1+bu! Date: Tue, 4 Feb 2020 11:46:03 -0800 Subject: [PATCH 0906/1253] Use consistent feature naming --- src/libcore/lib.rs | 8 ++-- src/libcore/num/mod.rs | 90 +++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index b5baa42fdb3fc..1fd70e1a1b049 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -72,10 +72,10 @@ #![feature(concat_idents)] #![feature(const_alloc_layout)] #![feature(const_if_match)] -#![feature(const_int_checked)] -#![feature(const_int_euclidean)] -#![feature(const_int_overflowing)] -#![feature(const_int_saturating)] +#![feature(const_checked_int_methods)] +#![feature(const_euclidean_int_methods)] +#![feature(const_overflowing_int_methods)] +#![feature(const_saturating_int_methods)] #![feature(const_int_unchecked_arith)] #![feature(const_panic)] #![feature(const_fn_union)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 38989004f9147..ed37b48b3e855 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -701,7 +701,7 @@ assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -726,7 +726,7 @@ assert_eq!((", stringify!($SelfT), "::min_value() + 2).checked_sub(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -751,7 +751,7 @@ assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -777,7 +777,7 @@ assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -806,7 +806,7 @@ assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None); assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -836,7 +836,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -866,7 +866,7 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -894,7 +894,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[inline] pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); @@ -916,7 +916,7 @@ assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -940,7 +940,7 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -966,7 +966,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);", $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[inline] pub const fn checked_abs(self) -> Option { if self.is_negative() { @@ -1091,7 +1091,7 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] - #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] + #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")] #[inline] pub const fn saturating_neg(self) -> Self { intrinsics::saturating_sub(0, self) @@ -1118,7 +1118,7 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] - #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] + #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")] #[inline] pub const fn saturating_abs(self) -> Self { if self.is_negative() { @@ -1146,7 +1146,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($Self $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] + #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1284,7 +1284,7 @@ assert_eq!((-128i8).wrapping_div(-1), -128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] + #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1314,7 +1314,7 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); assert_eq!((-128i8).wrapping_div_euclid(-1), -128); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1345,7 +1345,7 @@ assert_eq!((-128i8).wrapping_rem(-1), 0);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] + #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1374,7 +1374,7 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); assert_eq!((-128i8).wrapping_rem_euclid(-1), 0); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1654,7 +1654,7 @@ $EndFeature, " ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] + #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { @@ -1689,7 +1689,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { @@ -1724,7 +1724,7 @@ $EndFeature, " ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] + #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { @@ -1758,7 +1758,7 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2004,7 +2004,7 @@ assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2 assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2 ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2044,7 +2044,7 @@ assert_eq!(a.rem_euclid(-b), 3); assert_eq!((-a).rem_euclid(-b), 1); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2872,7 +2872,7 @@ Basic usage: assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2895,7 +2895,7 @@ Basic usage: assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2918,7 +2918,7 @@ Basic usage: assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2941,7 +2941,7 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2968,7 +2968,7 @@ assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64)); assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2995,7 +2995,7 @@ Basic usage: assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3023,7 +3023,7 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1)); assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3051,7 +3051,7 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[inline] pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); @@ -3072,7 +3072,7 @@ Basic usage: assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3095,7 +3095,7 @@ Basic usage: assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_checked", issue = "53718")] + #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3205,7 +3205,7 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se "::MAX);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_saturating", issue = "53718")] + #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3328,7 +3328,7 @@ Basic usage: ", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] + #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3355,7 +3355,7 @@ Basic usage: assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3380,7 +3380,7 @@ Basic usage: ", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping", issue = "53718")] + #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3408,7 +3408,7 @@ Basic usage: assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3657,7 +3657,7 @@ Basic usage ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] + #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { @@ -3689,7 +3689,7 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false)); ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { @@ -3718,7 +3718,7 @@ Basic usage ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_int_overflowing", issue = "53718")] + #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { @@ -3750,7 +3750,7 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); ```"), #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { @@ -3944,7 +3944,7 @@ Basic usage: assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3974,7 +3974,7 @@ Basic usage: assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type ```"), #[stable(feature = "euclidean_division", since = "1.38.0")] - #[rustc_const_unstable(feature = "const_int_euclidean", issue = "53718")] + #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From 040d9873aa6ca1ce458e98fec403cee8ec4f7ae8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 4 Feb 2020 11:46:13 -0800 Subject: [PATCH 0907/1253] Fix test --- src/test/ui/consts/const-int-arithmetic.rs | 284 +++++++++------------ 1 file changed, 124 insertions(+), 160 deletions(-) diff --git a/src/test/ui/consts/const-int-arithmetic.rs b/src/test/ui/consts/const-int-arithmetic.rs index 703f21a3f2952..cfa2873c68bad 100644 --- a/src/test/ui/consts/const-int-arithmetic.rs +++ b/src/test/ui/consts/const-int-arithmetic.rs @@ -1,166 +1,130 @@ // run-pass -#![feature(const_int_checked)] -#![feature(const_int_euclidean)] -#![feature(const_int_overflowing)] -#![feature(const_int_saturating)] -#![feature(const_int_wrapping)] - -macro_rules! assert_same_const { - ($(const $ident:ident: $ty:ty = $exp:expr;)+) => { - $(const $ident: $ty = $exp;)+ - - pub fn main() { - $(assert_eq!($exp, $ident);)+ +#![feature(saturating_neg)] +#![feature(const_checked_int_methods)] +#![feature(const_euclidean_int_methods)] +#![feature(const_overflowing_int_methods)] +#![feature(const_saturating_int_methods)] +#![feature(const_wrapping_int_methods)] + +use std::i8; + +macro_rules! suite { + ($( + $fn:ident -> $ty:ty { $( $label:ident : $expr:expr, $result:expr; )* } + )*) => { $( + fn $fn() { + $( + const $label: $ty = $expr; + assert_eq!($label, $result); + )* } - } + )* } } -assert_same_const! { - // `const_int_checked` - const CHECKED_ADD_I32_A: Option = 5i32.checked_add(2); - const CHECKED_ADD_I8_A: Option = 127i8.checked_add(2); - const CHECKED_ADD_U8_A: Option = 255u8.checked_add(2); - - const CHECKED_SUB_I32_A: Option = 5i32.checked_sub(2); - const CHECKED_SUB_I8_A: Option = (-127 as i8).checked_sub(2); - const CHECKED_SUB_U8_A: Option = 1u8.checked_sub(2); - - const CHECKED_MUL_I32_A: Option = 5i32.checked_mul(7777); - const CHECKED_MUL_I8_A: Option = (-127 as i8).checked_mul(-99); - const CHECKED_MUL_U8_A: Option = 1u8.checked_mul(3); - - const CHECKED_DIV_I32_A: Option = 5i32.checked_div(7777); - const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div(-99); - const CHECKED_DIV_U8_A: Option = 1u8.checked_div(3); - - const CHECKED_REM_I32_A: Option = 5i32.checked_rem(7777); - const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem(-99); - const CHECKED_REM_U8_A: Option = 1u8.checked_rem(3); - const CHECKED_REM_U8_B: Option = 1u8.checked_rem(0); - - const CHECKED_NEG_I32_A: Option = 5i32.checked_neg(); - const CHECKED_NEG_I8_A: Option = (-127 as i8).checked_neg(); - const CHECKED_NEG_U8_A: Option = 1u8.checked_neg(); - const CHECKED_NEG_U8_B: Option = u8::min_value().checked_neg(); - - const CHECKED_SHL_I32_A: Option = 5i32.checked_shl(77777); - const CHECKED_SHL_I8_A: Option = (-127 as i8).checked_shl(2); - const CHECKED_SHL_U8_A: Option = 1u8.checked_shl(8); - const CHECKED_SHL_U8_B: Option = 1u8.checked_shl(0); - - const CHECKED_SHR_I32_A: Option = 5i32.checked_shr(77777); - const CHECKED_SHR_I8_A: Option = (-127 as i8).checked_shr(2); - const CHECKED_SHR_U8_A: Option = 1u8.checked_shr(8); - const CHECKED_SHR_U8_B: Option = 1u8.checked_shr(0); - - const CHECKED_ABS_I32_A: Option = 5i32.checked_abs(); - const CHECKED_ABS_I8_A: Option = (-127 as i8).checked_abs(); - const CHECKED_ABS_I8_B: Option = 1i8.checked_abs(); - const CHECKED_ABS_I8_C: Option = i8::min_value().checked_abs(); - - // `const_int_overflowing` - const DIV_A: (i8, bool) = 8i8.overflowing_div(2); - const DIV_B: (i8, bool) = 8i8.overflowing_div(3); - const DIV_C: (i8, bool) = i8::min_value().overflowing_div(-1i8); - const DIV_D: (u8, bool) = 8u8.overflowing_div(2); - const DIV_E: (u8, bool) = 8u8.overflowing_div(3); - - const REM_A: (i8, bool) = 8i8.overflowing_rem(2); - const REM_B: (i8, bool) = 8i8.overflowing_rem(3); - const REM_C: (i8, bool) = i8::min_value().overflowing_rem(-1i8); - const REM_D: (u8, bool) = 8u8.overflowing_rem(2); - const REM_E: (u8, bool) = 8u8.overflowing_rem(3); - - // `const_int_saturating` - const ADD_INT_U32_NO: u32 = (42 as u32).saturating_add(2); - const ADD_INT_U32: u32 = u32::max_value().saturating_add(1); - const ADD_INT_U128: u128 = u128::max_value().saturating_add(1); - const ADD_INT_I128: i128 = i128::max_value().saturating_add(1); - const ADD_INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); - - const SUB_INT_U32_NO: u32 = (42 as u32).saturating_sub(2); - const SUB_INT_U32: u32 = (1 as u32).saturating_sub(2); - const SUB_INT_I32_NO: i32 = (-42 as i32).saturating_sub(2); - const SUB_INT_I32_NEG: i32 = i32::min_value().saturating_sub(1); - const SUB_INT_I32_POS: i32 = i32::max_value().saturating_sub(-1); - const SUB_INT_U128: u128 = (0 as u128).saturating_sub(1); - const SUB_INT_I128_NEG: i128 = i128::min_value().saturating_sub(1); - const SUB_INT_I128_POS: i128 = i128::max_value().saturating_sub(-1); - - const MUL_INT_U32_NO: u32 = (42 as u32).saturating_mul(2); - const MUL_INT_U32: u32 = (1 as u32).saturating_mul(2); - const MUL_INT_I32_NO: i32 = (-42 as i32).saturating_mul(2); - const MUL_INT_I32_NEG: i32 = i32::min_value().saturating_mul(1); - const MUL_INT_I32_POS: i32 = i32::max_value().saturating_mul(2); - const MUL_INT_U128: u128 = (0 as u128).saturating_mul(1); - const MUL_INT_I128_NEG: i128 = i128::min_value().saturating_mul(2); - const MUL_INT_I128_POS: i128 = i128::max_value().saturating_mul(2); - - const NEG_INT_I8: i8 = (-42i8).saturating_neg(); - const NEG_INT_I8_B: i8 = i8::min_value().saturating_neg(); - const NEG_INT_I32: i32 = i32::min_value().saturating_neg(); - const NEG_INT_I32_B: i32 = i32::max_value().saturating_neg(); - const NEG_INT_I128: i128 = i128::min_value().saturating_neg(); - const NEG_INT_I128_B: i128 = i128::max_value().saturating_neg(); - - const ABS_INT_I8_A: i8 = 4i8.saturating_abs(); - const ABS_INT_I8_B: i8 = -4i8.saturating_abs(); - const ABS_INT_I8_C: i8 = i8::min_value().saturating_abs(); - const ABS_INT_I32_A: i32 = 4i32.saturating_abs(); - const ABS_INT_I32_B: i32 = -4i32.saturating_abs(); - const ABS_INT_I32_C: i32 = i32::min_value().saturating_abs(); - const ABS_INT_I128_A: i128 = 4i128.saturating_abs(); - const ABS_INT_I128_B: i128 = -4i128.saturating_abs(); - const ABS_INT_I128_C: i128 = i128::min_value().saturating_abs(); - - // `const_int_euclidean` - const CHECKED_DIV_I32_A: Option = 5i32.checked_div_euclid(7777); - const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div_euclid(-99); - const CHECKED_DIV_I8_B: Option = (-127 as i8).checked_div_euclid(1); - const CHECKED_DIV_I8_C: Option = i8::min_value().checked_div_euclid(-1); - const CHECKED_DIV_U8_A: Option = 1u8.checked_div_euclid(3); - - const CHECKED_REM_I32_A: Option = 5i32.checked_rem_euclid(7777); - const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem_euclid(-99); - const CHECKED_REM_I8_B: Option = (-127 as i8).checked_rem_euclid(0); - const CHECKED_REM_I8_C: Option = i8::min_value().checked_rem_euclid(-1); - const CHECKED_REM_U8_A: Option = 1u8.checked_rem_euclid(3); - - const WRAPPING_DIV_I32_A: i32 = 5i32.wrapping_div_euclid(7777); - const WRAPPING_DIV_I8_A: i8 = (-127 as i8).wrapping_div_euclid(-99); - const WRAPPING_DIV_I8_B: i8 = (-127 as i8).wrapping_div_euclid(1); - const WRAPPING_DIV_I8_C: i8 = i8::min_value().wrapping_div_euclid(-1); - const WRAPPING_DIV_U8_A: u8 = 1u8.wrapping_div_euclid(3); - - const WRAPPING_REM_I32_A: i32 = 5i32.wrapping_rem_euclid(7777); - const WRAPPING_REM_I8_A: i8 = (-127 as i8).wrapping_rem_euclid(-99); - const WRAPPING_REM_I8_B: i8 = (-127 as i8).wrapping_rem_euclid(1); - const WRAPPING_REM_I8_C: i8 = i8::min_value().wrapping_rem_euclid(-1); - const WRAPPING_REM_U8_A: u8 = 1u8.wrapping_rem_euclid(3); - - const OVERFLOWING_DIV_I32_A: (i32, bool) = 5i32.overflowing_div_euclid(7777); - const OVERFLOWING_DIV_I8_A: (i8, bool) = (-127 as i8).overflowing_div_euclid(-99); - const OVERFLOWING_DIV_I8_B: (i8, bool) = (-127 as i8).overflowing_div_euclid(1); - const OVERFLOWING_DIV_I8_C: (i8, bool) = i8::min_value().overflowing_div_euclid(-1); - const OVERFLOWING_DIV_U8_A: (u8, bool) = 1u8.overflowing_div_euclid(3); - - const OVERFLOWING_REM_I32_A: (i32, bool) = 5i32.overflowing_rem_euclid(7777); - const OVERFLOWING_REM_I8_A: (i8, bool) = (-127 as i8).overflowing_rem_euclid(-99); - const OVERFLOWING_REM_I8_B: (i8, bool) = (-127 as i8).overflowing_rem_euclid(1); - const OVERFLOWING_REM_I8_C: (i8, bool) = i8::min_value().overflowing_rem_euclid(-1); - const OVERFLOWING_REM_U8_A: (u8, bool) = 1u8.overflowing_rem_euclid(3); - - // `const_int_wrapping` - const DIV_A: i8 = 8i8.wrapping_div(2); - const DIV_B: i8 = 8i8.wrapping_div(3); - const DIV_C: i8 = i8::min_value().wrapping_div(-1i8); - const DIV_D: u8 = 8u8.wrapping_div(2); - const DIV_E: u8 = 8u8.wrapping_div(3); - - const REM_A: i8 = 8i8.wrapping_rem(2); - const REM_B: i8 = 8i8.wrapping_rem(3); - const REM_C: i8 = i8::min_value().wrapping_rem(-1i8); - const REM_D: u8 = 8u8.wrapping_rem(2); - const REM_E: u8 = 8u8.wrapping_rem(3); +suite!( + checked -> Option { + // `const_checked_int_methods` + C1: 5i8.checked_add(2), Some(7); + C2: 127i8.checked_add(2), None; + + C3: 5i8.checked_sub(2), Some(3); + C4: (-127i8).checked_sub(2), None; + + C5: 1i8.checked_mul(3), Some(3); + C6: 5i8.checked_mul(122), None; + C7: (-127i8).checked_mul(-99), None; + + C8: (i8::min_value() + 1).checked_div(-1), Some(127); + C9: i8::min_value().checked_div(-1), None; + C10: 1i8.checked_div(0), None; + + C11: 5i8.checked_rem(2), Some(1); + C12: 5i8.checked_rem(0), None; + C13: i8::MIN.checked_rem(-1), None; + + C14: 5i8.checked_neg(), Some(-5); + C15: i8::MIN.checked_neg(), None; + + C16: 0x1i8.checked_shl(4), Some(0x10); + C17: 0x1i8.checked_shl(129), None; + + C18: 0x10i8.checked_shr(4), Some(0x1); + C19: 0x10i8.checked_shr(128), None; + + + C20: (-5i8).checked_abs(), Some(5); + C21: i8::MIN.checked_abs(), None; + + // `const_euclidean_int_methods` + C22: (i8::min_value() + 1).checked_div_euclid(-1), Some(127); + C23: i8::min_value().checked_div_euclid(-1), None; + C24: (1i8).checked_div_euclid(0), None; + + C25: 5i8.checked_rem_euclid(2), Some(1); + C26: 5i8.checked_rem_euclid(0), None; + C27: i8::MIN.checked_rem_euclid(-1), None; + } + + saturating_and_wrapping -> i8 { + // `const_saturating_int_methods` + C28: 100i8.saturating_add(1), 101; + C29: i8::max_value().saturating_add(100), i8::max_value(); + C30: i8::min_value().saturating_add(-1), i8::min_value(); + + C31: 100i8.saturating_sub(127), -27; + C32: i8::min_value().saturating_sub(100), i8::min_value(); + C33: i8::max_value().saturating_sub(-1), i8::max_value(); + + C34: 10i8.saturating_mul(12), 120; + C35: i8::MAX.saturating_mul(10), i8::MAX; + C36: i8::MIN.saturating_mul(10), i8::MIN; + + C37: 100i8.saturating_neg(), -100; + C38: (-100i8).saturating_neg(), 100; + C39: i8::min_value().saturating_neg(), i8::max_value(); + C40: i8::max_value().saturating_neg(), i8::min_value() + 1; + + C57: 100i8.saturating_abs(), 100; + C58: (-100i8).saturating_abs(), 100; + C59: i8::min_value().saturating_abs(), i8::max_value(); + C60: (i8::min_value() + 1).saturating_abs(), i8::max_value(); + + // `const_wrapping_int_methods` + C41: 100i8.wrapping_div(10), 10; + C42: (-128i8).wrapping_div(-1), -128; + + C43: 100i8.wrapping_rem(10), 0; + C44: (-128i8).wrapping_rem(-1), 0; + + // `const_euclidean_int_methods` + C45: 100i8.wrapping_div_euclid(10), 10; + C46: (-128i8).wrapping_div_euclid(-1), -128; + + C47: 100i8.wrapping_rem_euclid(10), 0; + C48: (-128i8).wrapping_rem_euclid(-1), 0; + } + + overflowing -> (i8, bool) { + // `const_overflowing_int_methods` + C49: 5i8.overflowing_div(2), (2, false); + C50: i8::MIN.overflowing_div(-1), (i8::MIN, true); + + C51: 5i8.overflowing_rem(2), (1, false); + C52: i8::MIN.overflowing_rem(-1), (0, true); + + // `const_euclidean_int_methods` + C53: 5i8.overflowing_div_euclid(2), (2, false); + C54: i8::MIN.overflowing_div_euclid(-1), (i8::MIN, true); + + C55: 5i8.overflowing_rem_euclid(2), (1, false); + C56: i8::MIN.overflowing_rem_euclid(-1), (0, true); + + } +); + +fn main() { + checked(); + saturating_and_wrapping(); + overflowing(); } From 78f8ad36409754319011514ca6febc8599abd429 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 4 Feb 2020 17:09:22 -0800 Subject: [PATCH 0908/1253] Implement remaining `unchecked` arithmetic intrinsics --- src/librustc_mir/interpret/intrinsics.rs | 19 +++++++++++++++++-- src/librustc_span/symbol.rs | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index cd6d94357e414..f85da760ada6d 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -218,19 +218,34 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; self.write_scalar(val, dest)?; } - sym::unchecked_shl | sym::unchecked_shr => { + sym::unchecked_shl + | sym::unchecked_shr + | sym::unchecked_add + | sym::unchecked_sub + | sym::unchecked_mul + | sym::unchecked_div + | sym::unchecked_rem => { let l = self.read_immediate(args[0])?; let r = self.read_immediate(args[1])?; let bin_op = match intrinsic_name { sym::unchecked_shl => BinOp::Shl, sym::unchecked_shr => BinOp::Shr, + sym::unchecked_add => BinOp::Add, + sym::unchecked_sub => BinOp::Sub, + sym::unchecked_mul => BinOp::Mul, + sym::unchecked_div => BinOp::Div, + sym::unchecked_rem => BinOp::Rem, _ => bug!("Already checked for int ops"), }; let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?; if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = self.force_bits(r.to_scalar()?, layout.size)?; - throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name); + if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name { + throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name); + } else { + throw_ub_format!("Overflow executing `{}`", intrinsic_name); + } } self.write_scalar(val, dest)?; } diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index e4f8b5a014389..c060e8948e3ed 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -755,8 +755,13 @@ symbols! { u64, u8, unboxed_closures, + unchecked_add, + unchecked_div, + unchecked_mul, + unchecked_rem, unchecked_shl, unchecked_shr, + unchecked_sub, underscore_const_names, underscore_imports, underscore_lifetimes, From 9713b5696b215b49a927ba55a5c5681a8f220e47 Mon Sep 17 00:00:00 2001 From: king6cong Date: Wed, 5 Feb 2020 12:56:24 +0800 Subject: [PATCH 0909/1253] doc fix on doc attribute --- src/doc/rustdoc/src/the-doc-attribute.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index 80ac405eb2f2a..ef143c8727ee9 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -39,7 +39,7 @@ crate level, and ones that are useful at the item level. ## At the crate level -These options control how the docs look at a macro level. +These options control how the docs look at a crate level. ### `html_favicon_url` From df7d9f383848dcb31a2f94bb1df5270ea21aff4b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 5 Feb 2020 15:34:33 +0900 Subject: [PATCH 0910/1253] Fix issue number of `capacity` method --- src/libstd/io/buffered.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 6739d4498a6be..8862226adbbd3 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -198,7 +198,7 @@ impl BufReader { /// Ok(()) /// } /// ``` - #[unstable(feature = "buffered_io_capacity", issue = "68558")] + #[unstable(feature = "buffered_io_capacity", issue = "68833")] pub fn capacity(&self) -> usize { self.buf.len() } @@ -616,7 +616,7 @@ impl BufWriter { /// // Calculate how many bytes can be written without flushing /// let without_flush = capacity - buf_writer.buffer().len(); /// ``` - #[unstable(feature = "buffered_io_capacity", issue = "68558")] + #[unstable(feature = "buffered_io_capacity", issue = "68833")] pub fn capacity(&self) -> usize { self.buf.capacity() } From 369f3601592f38b0689bb58b38094edd3164c9d9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 08:51:01 +0100 Subject: [PATCH 0911/1253] Move rustc::traits datatypes to module traits::types. --- src/librustc/traits/auto_trait.rs | 1 + src/librustc/traits/mod.rs | 685 +---------------------------- src/librustc/traits/types/mod.rs | 686 ++++++++++++++++++++++++++++++ 3 files changed, 691 insertions(+), 681 deletions(-) create mode 100644 src/librustc/traits/types/mod.rs diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index fdb6432f7c9e1..d775393a808f7 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -9,6 +9,7 @@ use crate::ty::fold::TypeFolder; use crate::ty::{Region, RegionVid}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use syntax::ast; use std::collections::hash_map::Entry; use std::collections::VecDeque; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b1b3d44044ebc..0eed762c000bc 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -19,31 +19,25 @@ mod select; mod specialize; mod structural_impls; mod structural_match; +mod types; mod util; pub mod wf; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, SuppressRegionErrors}; use crate::middle::region; -use crate::mir::interpret::ErrorHandled; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::TypeFoldable; use crate::ty::subst::{InternalSubsts, SubstsRef}; -use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness}; +use crate::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, WithConstness}; use crate::util::common::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; use rustc_span::{Span, DUMMY_SP}; -use syntax::ast; use std::fmt::Debug; -use std::rc::Rc; pub use self::FulfillmentErrorCode::*; -pub use self::ObligationCauseCode::*; -pub use self::SelectionError::*; -pub use self::Vtable::*; pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls}; pub use self::coherence::{OrphanCheckErr, OverlapResult}; @@ -81,10 +75,7 @@ pub use self::chalk_fulfill::{ CanonicalGoal as ChalkCanonicalGoal, FulfillmentContext as ChalkFulfillmentContext, }; -pub use self::FulfillmentErrorCode::*; -pub use self::ObligationCauseCode::*; -pub use self::SelectionError::*; -pub use self::Vtable::*; +pub use self::types::*; /// Whether to enable bug compatibility with issue #43355. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -138,392 +129,12 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; #[cfg(target_arch = "x86_64")] static_assert_size!(PredicateObligation<'_>, 112); -/// The reason why we incurred this obligation; used for error reporting. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct ObligationCause<'tcx> { - pub span: Span, - - /// The ID of the fn body that triggered this obligation. This is - /// used for region obligations to determine the precise - /// environment in which the region obligation should be evaluated - /// (in particular, closures can add new assumptions). See the - /// field `region_obligations` of the `FulfillmentContext` for more - /// information. - pub body_id: hir::HirId, - - pub code: ObligationCauseCode<'tcx>, -} - -impl ObligationCause<'_> { - pub fn span(&self, tcx: TyCtxt<'_>) -> Span { - match self.code { - ObligationCauseCode::CompareImplMethodObligation { .. } - | ObligationCauseCode::MainFunctionType - | ObligationCauseCode::StartFunctionType => tcx.sess.source_map().def_span(self.span), - ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - arm_span, - .. - }) => arm_span, - _ => self.span, - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum ObligationCauseCode<'tcx> { - /// Not well classified or should be obvious from the span. - MiscObligation, - - /// A slice or array is WF only if `T: Sized`. - SliceOrArrayElem, - - /// A tuple is WF only if its middle elements are `Sized`. - TupleElem, - - /// This is the trait reference from the given projection. - ProjectionWf(ty::ProjectionTy<'tcx>), - - /// In an impl of trait `X` for type `Y`, type `Y` must - /// also implement all supertraits of `X`. - ItemObligation(DefId), - - /// Like `ItemObligation`, but with extra detail on the source of the obligation. - BindingObligation(DefId, Span), - - /// A type like `&'a T` is WF only if `T: 'a`. - ReferenceOutlivesReferent(Ty<'tcx>), - - /// A type like `Box + 'b>` is WF only if `'b: 'a`. - ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>), - - /// Obligation incurred due to an object cast. - ObjectCastObligation(/* Object type */ Ty<'tcx>), - - /// Obligation incurred due to a coercion. - Coercion { - source: Ty<'tcx>, - target: Ty<'tcx>, - }, - - /// Various cases where expressions must be `Sized` / `Copy` / etc. - /// `L = X` implies that `L` is `Sized`. - AssignmentLhsSized, - /// `(x1, .., xn)` must be `Sized`. - TupleInitializerSized, - /// `S { ... }` must be `Sized`. - StructInitializerSized, - /// Type of each variable must be `Sized`. - VariableType(hir::HirId), - /// Argument type must be `Sized`. - SizedArgumentType, - /// Return type must be `Sized`. - SizedReturnType, - /// Yield type must be `Sized`. - SizedYieldType, - /// `[T, ..n]` implies that `T` must be `Copy`. - /// If `true`, suggest `const_in_array_repeat_expressions` feature flag. - RepeatVec(bool), - - /// Types of fields (other than the last, except for packed structs) in a struct must be sized. - FieldSized { - adt_kind: AdtKind, - last: bool, - }, - - /// Constant expressions must be sized. - ConstSized, - - /// `static` items must have `Sync` type. - SharedStatic, - - BuiltinDerivedObligation(DerivedObligationCause<'tcx>), - - ImplDerivedObligation(DerivedObligationCause<'tcx>), - - /// Error derived when matching traits/impls; see ObligationCause for more details - CompareImplMethodObligation { - item_name: ast::Name, - impl_item_def_id: DefId, - trait_item_def_id: DefId, - }, - - /// Error derived when matching traits/impls; see ObligationCause for more details - CompareImplTypeObligation { - item_name: ast::Name, - impl_item_def_id: DefId, - trait_item_def_id: DefId, - }, - - /// Checking that this expression can be assigned where it needs to be - // FIXME(eddyb) #11161 is the original Expr required? - ExprAssignable, - - /// Computing common supertype in the arms of a match expression - MatchExpressionArm(Box>), - - /// Type error arising from type checking a pattern against an expected type. - Pattern { - /// The span of the scrutinee or type expression which caused the `root_ty` type. - span: Option, - /// The root expected type induced by a scrutinee or type expression. - root_ty: Ty<'tcx>, - /// Whether the `Span` came from an expression or a type expression. - origin_expr: bool, - }, - - /// Constants in patterns must have `Structural` type. - ConstPatternStructural, - - /// Computing common supertype in an if expression - IfExpression(Box), - - /// Computing common supertype of an if expression with no else counter-part - IfExpressionWithNoElse, - - /// `main` has wrong type - MainFunctionType, - - /// `start` has wrong type - StartFunctionType, - - /// Intrinsic has wrong type - IntrinsicType, - - /// Method receiver - MethodReceiver, - - /// `return` with no expression - ReturnNoExpression, - - /// `return` with an expression - ReturnValue(hir::HirId), - - /// Return type of this function - ReturnType, - - /// Block implicit return - BlockTailExpression(hir::HirId), - - /// #[feature(trivial_bounds)] is not enabled - TrivialBound, - - AssocTypeBound(Box), -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct AssocTypeBoundData { - pub impl_span: Option, - pub original: Span, - pub bounds: Vec, -} - -// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(target_arch = "x86_64")] -static_assert_size!(ObligationCauseCode<'_>, 32); - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct MatchExpressionArmCause<'tcx> { - pub arm_span: Span, - pub source: hir::MatchSource, - pub prior_arms: Vec, - pub last_ty: Ty<'tcx>, - pub scrut_hir_id: hir::HirId, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct IfExpressionCause { - pub then: Span, - pub outer: Option, - pub semicolon: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct DerivedObligationCause<'tcx> { - /// The trait reference of the parent obligation that led to the - /// current obligation. Note that only trait obligations lead to - /// derived obligations, so we just store the trait reference here - /// directly. - parent_trait_ref: ty::PolyTraitRef<'tcx>, - - /// The parent trait had this cause. - parent_code: Rc>, -} - pub type Obligations<'tcx, O> = Vec>; pub type PredicateObligations<'tcx> = Vec>; pub type TraitObligations<'tcx> = Vec>; -/// The following types: -/// * `WhereClause`, -/// * `WellFormed`, -/// * `FromEnv`, -/// * `DomainGoal`, -/// * `Goal`, -/// * `Clause`, -/// * `Environment`, -/// * `InEnvironment`, -/// are used for representing the trait system in the form of -/// logic programming clauses. They are part of the interface -/// for the chalk SLG solver. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] -pub enum WhereClause<'tcx> { - Implemented(ty::TraitPredicate<'tcx>), - ProjectionEq(ty::ProjectionPredicate<'tcx>), - RegionOutlives(ty::RegionOutlivesPredicate<'tcx>), - TypeOutlives(ty::TypeOutlivesPredicate<'tcx>), -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] -pub enum WellFormed<'tcx> { - Trait(ty::TraitPredicate<'tcx>), - Ty(Ty<'tcx>), -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] -pub enum FromEnv<'tcx> { - Trait(ty::TraitPredicate<'tcx>), - Ty(Ty<'tcx>), -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] -pub enum DomainGoal<'tcx> { - Holds(WhereClause<'tcx>), - WellFormed(WellFormed<'tcx>), - FromEnv(FromEnv<'tcx>), - Normalize(ty::ProjectionPredicate<'tcx>), -} - -pub type PolyDomainGoal<'tcx> = ty::Binder>; - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)] -pub enum QuantifierKind { - Universal, - Existential, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] -pub enum GoalKind<'tcx> { - Implies(Clauses<'tcx>, Goal<'tcx>), - And(Goal<'tcx>, Goal<'tcx>), - Not(Goal<'tcx>), - DomainGoal(DomainGoal<'tcx>), - Quantified(QuantifierKind, ty::Binder>), - Subtype(Ty<'tcx>, Ty<'tcx>), - CannotProve, -} - -pub type Goal<'tcx> = &'tcx GoalKind<'tcx>; - -pub type Goals<'tcx> = &'tcx List>; - -impl<'tcx> DomainGoal<'tcx> { - pub fn into_goal(self) -> GoalKind<'tcx> { - GoalKind::DomainGoal(self) - } - - pub fn into_program_clause(self) -> ProgramClause<'tcx> { - ProgramClause { - goal: self, - hypotheses: ty::List::empty(), - category: ProgramClauseCategory::Other, - } - } -} - -impl<'tcx> GoalKind<'tcx> { - pub fn from_poly_domain_goal( - domain_goal: PolyDomainGoal<'tcx>, - tcx: TyCtxt<'tcx>, - ) -> GoalKind<'tcx> { - match domain_goal.no_bound_vars() { - Some(p) => p.into_goal(), - None => GoalKind::Quantified( - QuantifierKind::Universal, - domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())), - ), - } - } -} - -/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary -/// Harrop Formulas". -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] -pub enum Clause<'tcx> { - Implies(ProgramClause<'tcx>), - ForAll(ty::Binder>), -} - -impl Clause<'tcx> { - pub fn category(self) -> ProgramClauseCategory { - match self { - Clause::Implies(clause) => clause.category, - Clause::ForAll(clause) => clause.skip_binder().category, - } - } -} - -/// Multiple clauses. -pub type Clauses<'tcx> = &'tcx List>; - -/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying -/// that the domain goal `D` is true if `G1...Gn` are provable. This -/// is equivalent to the implication `G1..Gn => D`; we usually write -/// it with the reverse implication operator `:-` to emphasize the way -/// that programs are actually solved (via backchaining, which starts -/// with the goal to solve and proceeds from there). -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] -pub struct ProgramClause<'tcx> { - /// This goal will be considered true ... - pub goal: DomainGoal<'tcx>, - - /// ... if we can prove these hypotheses (there may be no hypotheses at all): - pub hypotheses: Goals<'tcx>, - - /// Useful for filtering clauses. - pub category: ProgramClauseCategory, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)] -pub enum ProgramClauseCategory { - ImpliedBound, - WellFormed, - Other, -} - -/// A set of clauses that we assume to be true. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] -pub struct Environment<'tcx> { - pub clauses: Clauses<'tcx>, -} - -impl Environment<'tcx> { - pub fn with(self, goal: G) -> InEnvironment<'tcx, G> { - InEnvironment { environment: self, goal } - } -} - -/// Something (usually a goal), along with an environment. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] -pub struct InEnvironment<'tcx, G> { - pub environment: Environment<'tcx>, - pub goal: G, -} - pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>; -#[derive(Clone, Debug, TypeFoldable)] -pub enum SelectionError<'tcx> { - Unimplemented, - OutputTypeParameterMismatch( - ty::PolyTraitRef<'tcx>, - ty::PolyTraitRef<'tcx>, - ty::error::TypeError<'tcx>, - ), - TraitNotObjectSafe(DefId), - ConstEvalFailure(ErrorHandled), - Overflow, -} - pub struct FulfillmentError<'tcx> { pub obligation: PredicateObligation<'tcx>, pub code: FulfillmentErrorCode<'tcx>, @@ -541,164 +152,6 @@ pub enum FulfillmentErrorCode<'tcx> { CodeAmbiguity, } -/// When performing resolution, it is typically the case that there -/// can be one of three outcomes: -/// -/// - `Ok(Some(r))`: success occurred with result `r` -/// - `Ok(None)`: could not definitely determine anything, usually due -/// to inconclusive type inference. -/// - `Err(e)`: error `e` occurred -pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; - -/// Given the successful resolution of an obligation, the `Vtable` -/// indicates where the vtable comes from. Note that while we call this -/// a "vtable", it does not necessarily indicate dynamic dispatch at -/// runtime. `Vtable` instances just tell the compiler where to find -/// methods, but in generic code those methods are typically statically -/// dispatched -- only when an object is constructed is a `Vtable` -/// instance reified into an actual vtable. -/// -/// For example, the vtable may be tied to a specific impl (case A), -/// or it may be relative to some bound that is in scope (case B). -/// -/// ``` -/// impl Clone for Option { ... } // Impl_1 -/// impl Clone for Box { ... } // Impl_2 -/// impl Clone for int { ... } // Impl_3 -/// -/// fn foo(concrete: Option>, -/// param: T, -/// mixed: Option) { -/// -/// // Case A: Vtable points at a specific impl. Only possible when -/// // type is concretely known. If the impl itself has bounded -/// // type parameters, Vtable will carry resolutions for those as well: -/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])]) -/// -/// // Case B: Vtable must be provided by caller. This applies when -/// // type is a type parameter. -/// param.clone(); // VtableParam -/// -/// // Case C: A mix of cases A and B. -/// mixed.clone(); // Vtable(Impl_1, [VtableParam]) -/// } -/// ``` -/// -/// ### The type parameter `N` -/// -/// See explanation on `VtableImplData`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub enum Vtable<'tcx, N> { - /// Vtable identifying a particular impl. - VtableImpl(VtableImplData<'tcx, N>), - - /// Vtable for auto trait implementations. - /// This carries the information and nested obligations with regards - /// to an auto implementation for a trait `Trait`. The nested obligations - /// ensure the trait implementation holds for all the constituent types. - VtableAutoImpl(VtableAutoImplData), - - /// Successful resolution to an obligation provided by the caller - /// for some type parameter. The `Vec` represents the - /// obligations incurred from normalizing the where-clause (if - /// any). - VtableParam(Vec), - - /// Virtual calls through an object. - VtableObject(VtableObjectData<'tcx, N>), - - /// Successful resolution for a builtin trait. - VtableBuiltin(VtableBuiltinData), - - /// Vtable automatically generated for a closure. The `DefId` is the ID - /// of the closure expression. This is a `VtableImpl` in spirit, but the - /// impl is generated by the compiler and does not appear in the source. - VtableClosure(VtableClosureData<'tcx, N>), - - /// Same as above, but for a function pointer type with the given signature. - VtableFnPointer(VtableFnPointerData<'tcx, N>), - - /// Vtable automatically generated for a generator. - VtableGenerator(VtableGeneratorData<'tcx, N>), - - /// Vtable for a trait alias. - VtableTraitAlias(VtableTraitAliasData<'tcx, N>), -} - -/// Identifies a particular impl in the source, along with a set of -/// substitutions from the impl's type/lifetime parameters. The -/// `nested` vector corresponds to the nested obligations attached to -/// the impl's type parameters. -/// -/// The type parameter `N` indicates the type used for "nested -/// obligations" that are required by the impl. During type-check, this -/// is `Obligation`, as one might expect. During codegen, however, this -/// is `()`, because codegen only requires a shallow resolution of an -/// impl, and nested obligations are satisfied later. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableImplData<'tcx, N> { - pub impl_def_id: DefId, - pub substs: SubstsRef<'tcx>, - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableGeneratorData<'tcx, N> { - pub generator_def_id: DefId, - pub substs: SubstsRef<'tcx>, - /// Nested obligations. This can be non-empty if the generator - /// signature contains associated types. - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableClosureData<'tcx, N> { - pub closure_def_id: DefId, - pub substs: SubstsRef<'tcx>, - /// Nested obligations. This can be non-empty if the closure - /// signature contains associated types. - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableAutoImplData { - pub trait_def_id: DefId, - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableBuiltinData { - pub nested: Vec, -} - -/// A vtable for some object-safe trait `Foo` automatically derived -/// for the object type `Foo`. -#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableObjectData<'tcx, N> { - /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`. - pub upcast_trait_ref: ty::PolyTraitRef<'tcx>, - - /// The vtable is formed by concatenating together the method lists of - /// the base object trait and all supertraits; this is the start of - /// `upcast_trait_ref`'s methods in that vtable. - pub vtable_base: usize, - - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableFnPointerData<'tcx, N> { - pub fn_ty: Ty<'tcx>, - pub nested: Vec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] -pub struct VtableTraitAliasData<'tcx, N> { - pub alias_def_id: DefId, - pub substs: SubstsRef<'tcx>, - pub nested: Vec, -} - /// Creates predicate obligations from the generic bounds. pub fn predicates_for_generics<'tcx>( cause: ObligationCause<'tcx>, @@ -1147,97 +600,6 @@ impl<'tcx, O> Obligation<'tcx, O> { } } -impl<'tcx> ObligationCause<'tcx> { - #[inline] - pub fn new( - span: Span, - body_id: hir::HirId, - code: ObligationCauseCode<'tcx>, - ) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code } - } - - pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code: MiscObligation } - } - - pub fn dummy() -> ObligationCause<'tcx> { - ObligationCause { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation } - } -} - -impl ObligationCauseCode<'_> { - // Return the base obligation, ignoring derived obligations. - pub fn peel_derives(&self) -> &Self { - let mut base_cause = self; - while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause { - base_cause = &cause.parent_code; - } - base_cause - } -} - -impl<'tcx, N> Vtable<'tcx, N> { - pub fn nested_obligations(self) -> Vec { - match self { - VtableImpl(i) => i.nested, - VtableParam(n) => n, - VtableBuiltin(i) => i.nested, - VtableAutoImpl(d) => d.nested, - VtableClosure(c) => c.nested, - VtableGenerator(c) => c.nested, - VtableObject(d) => d.nested, - VtableFnPointer(d) => d.nested, - VtableTraitAlias(d) => d.nested, - } - } - - pub fn map(self, f: F) -> Vtable<'tcx, M> - where - F: FnMut(N) -> M, - { - match self { - VtableImpl(i) => VtableImpl(VtableImplData { - impl_def_id: i.impl_def_id, - substs: i.substs, - nested: i.nested.into_iter().map(f).collect(), - }), - VtableParam(n) => VtableParam(n.into_iter().map(f).collect()), - VtableBuiltin(i) => { - VtableBuiltin(VtableBuiltinData { nested: i.nested.into_iter().map(f).collect() }) - } - VtableObject(o) => VtableObject(VtableObjectData { - upcast_trait_ref: o.upcast_trait_ref, - vtable_base: o.vtable_base, - nested: o.nested.into_iter().map(f).collect(), - }), - VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData { - trait_def_id: d.trait_def_id, - nested: d.nested.into_iter().map(f).collect(), - }), - VtableClosure(c) => VtableClosure(VtableClosureData { - closure_def_id: c.closure_def_id, - substs: c.substs, - nested: c.nested.into_iter().map(f).collect(), - }), - VtableGenerator(c) => VtableGenerator(VtableGeneratorData { - generator_def_id: c.generator_def_id, - substs: c.substs, - nested: c.nested.into_iter().map(f).collect(), - }), - VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData { - fn_ty: p.fn_ty, - nested: p.nested.into_iter().map(f).collect(), - }), - VtableTraitAlias(d) => VtableTraitAlias(VtableTraitAliasData { - alias_def_id: d.alias_def_id, - substs: d.substs, - nested: d.nested.into_iter().map(f).collect(), - }), - } - } -} - impl<'tcx> FulfillmentError<'tcx> { fn new( obligation: PredicateObligation<'tcx>, @@ -1265,42 +627,3 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { ..*providers }; } - -pub trait ExClauseFold<'tcx> -where - Self: chalk_engine::context::Context + Clone, -{ - fn fold_ex_clause_with>( - ex_clause: &chalk_engine::ExClause, - folder: &mut F, - ) -> chalk_engine::ExClause; - - fn visit_ex_clause_with>( - ex_clause: &chalk_engine::ExClause, - visitor: &mut V, - ) -> bool; -} - -pub trait ChalkContextLift<'tcx> -where - Self: chalk_engine::context::Context + Clone, -{ - type LiftedExClause: Debug + 'tcx; - type LiftedDelayedLiteral: Debug + 'tcx; - type LiftedLiteral: Debug + 'tcx; - - fn lift_ex_clause_to_tcx( - ex_clause: &chalk_engine::ExClause, - tcx: TyCtxt<'tcx>, - ) -> Option; - - fn lift_delayed_literal_to_tcx( - ex_clause: &chalk_engine::DelayedLiteral, - tcx: TyCtxt<'tcx>, - ) -> Option; - - fn lift_literal_to_tcx( - ex_clause: &chalk_engine::Literal, - tcx: TyCtxt<'tcx>, - ) -> Option; -} diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs new file mode 100644 index 0000000000000..c4a066d5ec07a --- /dev/null +++ b/src/librustc/traits/types/mod.rs @@ -0,0 +1,686 @@ +//! Trait Resolution. See the [rustc guide] for more information on how this works. +//! +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html + +use crate::mir::interpret::ErrorHandled; +use crate::ty::fold::{TypeFolder, TypeVisitor}; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, AdtKind, List, Ty, TyCtxt}; + +use rustc_hir as hir; +use rustc_hir::def_id::DefId; +use rustc_span::{Span, DUMMY_SP}; +use syntax::ast; + +use std::fmt::Debug; +use std::rc::Rc; + +pub use self::ObligationCauseCode::*; +pub use self::SelectionError::*; +pub use self::Vtable::*; + +/// The reason why we incurred this obligation; used for error reporting. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ObligationCause<'tcx> { + pub span: Span, + + /// The ID of the fn body that triggered this obligation. This is + /// used for region obligations to determine the precise + /// environment in which the region obligation should be evaluated + /// (in particular, closures can add new assumptions). See the + /// field `region_obligations` of the `FulfillmentContext` for more + /// information. + pub body_id: hir::HirId, + + pub code: ObligationCauseCode<'tcx>, +} + +impl<'tcx> ObligationCause<'tcx> { + #[inline] + pub fn new( + span: Span, + body_id: hir::HirId, + code: ObligationCauseCode<'tcx>, + ) -> ObligationCause<'tcx> { + ObligationCause { span, body_id, code } + } + + pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { + ObligationCause { span, body_id, code: MiscObligation } + } + + pub fn dummy() -> ObligationCause<'tcx> { + ObligationCause { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation } + } + + pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span { + match self.code { + ObligationCauseCode::CompareImplMethodObligation { .. } + | ObligationCauseCode::MainFunctionType + | ObligationCauseCode::StartFunctionType => tcx.sess.source_map().def_span(self.span), + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + arm_span, + .. + }) => arm_span, + _ => self.span, + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum ObligationCauseCode<'tcx> { + /// Not well classified or should be obvious from the span. + MiscObligation, + + /// A slice or array is WF only if `T: Sized`. + SliceOrArrayElem, + + /// A tuple is WF only if its middle elements are `Sized`. + TupleElem, + + /// This is the trait reference from the given projection. + ProjectionWf(ty::ProjectionTy<'tcx>), + + /// In an impl of trait `X` for type `Y`, type `Y` must + /// also implement all supertraits of `X`. + ItemObligation(DefId), + + /// Like `ItemObligation`, but with extra detail on the source of the obligation. + BindingObligation(DefId, Span), + + /// A type like `&'a T` is WF only if `T: 'a`. + ReferenceOutlivesReferent(Ty<'tcx>), + + /// A type like `Box + 'b>` is WF only if `'b: 'a`. + ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>), + + /// Obligation incurred due to an object cast. + ObjectCastObligation(/* Object type */ Ty<'tcx>), + + /// Obligation incurred due to a coercion. + Coercion { + source: Ty<'tcx>, + target: Ty<'tcx>, + }, + + /// Various cases where expressions must be `Sized` / `Copy` / etc. + /// `L = X` implies that `L` is `Sized`. + AssignmentLhsSized, + /// `(x1, .., xn)` must be `Sized`. + TupleInitializerSized, + /// `S { ... }` must be `Sized`. + StructInitializerSized, + /// Type of each variable must be `Sized`. + VariableType(hir::HirId), + /// Argument type must be `Sized`. + SizedArgumentType, + /// Return type must be `Sized`. + SizedReturnType, + /// Yield type must be `Sized`. + SizedYieldType, + /// `[T, ..n]` implies that `T` must be `Copy`. + /// If `true`, suggest `const_in_array_repeat_expressions` feature flag. + RepeatVec(bool), + + /// Types of fields (other than the last, except for packed structs) in a struct must be sized. + FieldSized { + adt_kind: AdtKind, + last: bool, + }, + + /// Constant expressions must be sized. + ConstSized, + + /// `static` items must have `Sync` type. + SharedStatic, + + BuiltinDerivedObligation(DerivedObligationCause<'tcx>), + + ImplDerivedObligation(DerivedObligationCause<'tcx>), + + /// Error derived when matching traits/impls; see ObligationCause for more details + CompareImplMethodObligation { + item_name: ast::Name, + impl_item_def_id: DefId, + trait_item_def_id: DefId, + }, + + /// Error derived when matching traits/impls; see ObligationCause for more details + CompareImplTypeObligation { + item_name: ast::Name, + impl_item_def_id: DefId, + trait_item_def_id: DefId, + }, + + /// Checking that this expression can be assigned where it needs to be + // FIXME(eddyb) #11161 is the original Expr required? + ExprAssignable, + + /// Computing common supertype in the arms of a match expression + MatchExpressionArm(Box>), + + /// Type error arising from type checking a pattern against an expected type. + Pattern { + /// The span of the scrutinee or type expression which caused the `root_ty` type. + span: Option, + /// The root expected type induced by a scrutinee or type expression. + root_ty: Ty<'tcx>, + /// Whether the `Span` came from an expression or a type expression. + origin_expr: bool, + }, + + /// Constants in patterns must have `Structural` type. + ConstPatternStructural, + + /// Computing common supertype in an if expression + IfExpression(Box), + + /// Computing common supertype of an if expression with no else counter-part + IfExpressionWithNoElse, + + /// `main` has wrong type + MainFunctionType, + + /// `start` has wrong type + StartFunctionType, + + /// Intrinsic has wrong type + IntrinsicType, + + /// Method receiver + MethodReceiver, + + /// `return` with no expression + ReturnNoExpression, + + /// `return` with an expression + ReturnValue(hir::HirId), + + /// Return type of this function + ReturnType, + + /// Block implicit return + BlockTailExpression(hir::HirId), + + /// #[feature(trivial_bounds)] is not enabled + TrivialBound, + + AssocTypeBound(Box), +} + +impl ObligationCauseCode<'_> { + // Return the base obligation, ignoring derived obligations. + pub fn peel_derives(&self) -> &Self { + let mut base_cause = self; + while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause { + base_cause = &cause.parent_code; + } + base_cause + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct AssocTypeBoundData { + pub impl_span: Option, + pub original: Span, + pub bounds: Vec, +} + +// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert_size!(ObligationCauseCode<'_>, 32); + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct MatchExpressionArmCause<'tcx> { + pub arm_span: Span, + pub source: hir::MatchSource, + pub prior_arms: Vec, + pub last_ty: Ty<'tcx>, + pub scrut_hir_id: hir::HirId, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct IfExpressionCause { + pub then: Span, + pub outer: Option, + pub semicolon: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct DerivedObligationCause<'tcx> { + /// The trait reference of the parent obligation that led to the + /// current obligation. Note that only trait obligations lead to + /// derived obligations, so we just store the trait reference here + /// directly. + pub parent_trait_ref: ty::PolyTraitRef<'tcx>, + + /// The parent trait had this cause. + pub parent_code: Rc>, +} + +/// The following types: +/// * `WhereClause`, +/// * `WellFormed`, +/// * `FromEnv`, +/// * `DomainGoal`, +/// * `Goal`, +/// * `Clause`, +/// * `Environment`, +/// * `InEnvironment`, +/// are used for representing the trait system in the form of +/// logic programming clauses. They are part of the interface +/// for the chalk SLG solver. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] +pub enum WhereClause<'tcx> { + Implemented(ty::TraitPredicate<'tcx>), + ProjectionEq(ty::ProjectionPredicate<'tcx>), + RegionOutlives(ty::RegionOutlivesPredicate<'tcx>), + TypeOutlives(ty::TypeOutlivesPredicate<'tcx>), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] +pub enum WellFormed<'tcx> { + Trait(ty::TraitPredicate<'tcx>), + Ty(Ty<'tcx>), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] +pub enum FromEnv<'tcx> { + Trait(ty::TraitPredicate<'tcx>), + Ty(Ty<'tcx>), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] +pub enum DomainGoal<'tcx> { + Holds(WhereClause<'tcx>), + WellFormed(WellFormed<'tcx>), + FromEnv(FromEnv<'tcx>), + Normalize(ty::ProjectionPredicate<'tcx>), +} + +pub type PolyDomainGoal<'tcx> = ty::Binder>; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)] +pub enum QuantifierKind { + Universal, + Existential, +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] +pub enum GoalKind<'tcx> { + Implies(Clauses<'tcx>, Goal<'tcx>), + And(Goal<'tcx>, Goal<'tcx>), + Not(Goal<'tcx>), + DomainGoal(DomainGoal<'tcx>), + Quantified(QuantifierKind, ty::Binder>), + Subtype(Ty<'tcx>, Ty<'tcx>), + CannotProve, +} + +pub type Goal<'tcx> = &'tcx GoalKind<'tcx>; + +pub type Goals<'tcx> = &'tcx List>; + +impl<'tcx> DomainGoal<'tcx> { + pub fn into_goal(self) -> GoalKind<'tcx> { + GoalKind::DomainGoal(self) + } + + pub fn into_program_clause(self) -> ProgramClause<'tcx> { + ProgramClause { + goal: self, + hypotheses: ty::List::empty(), + category: ProgramClauseCategory::Other, + } + } +} + +impl<'tcx> GoalKind<'tcx> { + pub fn from_poly_domain_goal( + domain_goal: PolyDomainGoal<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> GoalKind<'tcx> { + match domain_goal.no_bound_vars() { + Some(p) => p.into_goal(), + None => GoalKind::Quantified( + QuantifierKind::Universal, + domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())), + ), + } + } +} + +/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary +/// Harrop Formulas". +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub enum Clause<'tcx> { + Implies(ProgramClause<'tcx>), + ForAll(ty::Binder>), +} + +impl Clause<'tcx> { + pub fn category(self) -> ProgramClauseCategory { + match self { + Clause::Implies(clause) => clause.category, + Clause::ForAll(clause) => clause.skip_binder().category, + } + } +} + +/// Multiple clauses. +pub type Clauses<'tcx> = &'tcx List>; + +/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying +/// that the domain goal `D` is true if `G1...Gn` are provable. This +/// is equivalent to the implication `G1..Gn => D`; we usually write +/// it with the reverse implication operator `:-` to emphasize the way +/// that programs are actually solved (via backchaining, which starts +/// with the goal to solve and proceeds from there). +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub struct ProgramClause<'tcx> { + /// This goal will be considered true ... + pub goal: DomainGoal<'tcx>, + + /// ... if we can prove these hypotheses (there may be no hypotheses at all): + pub hypotheses: Goals<'tcx>, + + /// Useful for filtering clauses. + pub category: ProgramClauseCategory, +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)] +pub enum ProgramClauseCategory { + ImpliedBound, + WellFormed, + Other, +} + +/// A set of clauses that we assume to be true. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub struct Environment<'tcx> { + pub clauses: Clauses<'tcx>, +} + +impl Environment<'tcx> { + pub fn with(self, goal: G) -> InEnvironment<'tcx, G> { + InEnvironment { environment: self, goal } + } +} + +/// Something (usually a goal), along with an environment. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub struct InEnvironment<'tcx, G> { + pub environment: Environment<'tcx>, + pub goal: G, +} + +#[derive(Clone, Debug, TypeFoldable)] +pub enum SelectionError<'tcx> { + Unimplemented, + OutputTypeParameterMismatch( + ty::PolyTraitRef<'tcx>, + ty::PolyTraitRef<'tcx>, + ty::error::TypeError<'tcx>, + ), + TraitNotObjectSafe(DefId), + ConstEvalFailure(ErrorHandled), + Overflow, +} + +/// When performing resolution, it is typically the case that there +/// can be one of three outcomes: +/// +/// - `Ok(Some(r))`: success occurred with result `r` +/// - `Ok(None)`: could not definitely determine anything, usually due +/// to inconclusive type inference. +/// - `Err(e)`: error `e` occurred +pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; + +/// Given the successful resolution of an obligation, the `Vtable` +/// indicates where the vtable comes from. Note that while we call this +/// a "vtable", it does not necessarily indicate dynamic dispatch at +/// runtime. `Vtable` instances just tell the compiler where to find +/// methods, but in generic code those methods are typically statically +/// dispatched -- only when an object is constructed is a `Vtable` +/// instance reified into an actual vtable. +/// +/// For example, the vtable may be tied to a specific impl (case A), +/// or it may be relative to some bound that is in scope (case B). +/// +/// ``` +/// impl Clone for Option { ... } // Impl_1 +/// impl Clone for Box { ... } // Impl_2 +/// impl Clone for int { ... } // Impl_3 +/// +/// fn foo(concrete: Option>, +/// param: T, +/// mixed: Option) { +/// +/// // Case A: Vtable points at a specific impl. Only possible when +/// // type is concretely known. If the impl itself has bounded +/// // type parameters, Vtable will carry resolutions for those as well: +/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])]) +/// +/// // Case B: Vtable must be provided by caller. This applies when +/// // type is a type parameter. +/// param.clone(); // VtableParam +/// +/// // Case C: A mix of cases A and B. +/// mixed.clone(); // Vtable(Impl_1, [VtableParam]) +/// } +/// ``` +/// +/// ### The type parameter `N` +/// +/// See explanation on `VtableImplData`. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub enum Vtable<'tcx, N> { + /// Vtable identifying a particular impl. + VtableImpl(VtableImplData<'tcx, N>), + + /// Vtable for auto trait implementations. + /// This carries the information and nested obligations with regards + /// to an auto implementation for a trait `Trait`. The nested obligations + /// ensure the trait implementation holds for all the constituent types. + VtableAutoImpl(VtableAutoImplData), + + /// Successful resolution to an obligation provided by the caller + /// for some type parameter. The `Vec` represents the + /// obligations incurred from normalizing the where-clause (if + /// any). + VtableParam(Vec), + + /// Virtual calls through an object. + VtableObject(VtableObjectData<'tcx, N>), + + /// Successful resolution for a builtin trait. + VtableBuiltin(VtableBuiltinData), + + /// Vtable automatically generated for a closure. The `DefId` is the ID + /// of the closure expression. This is a `VtableImpl` in spirit, but the + /// impl is generated by the compiler and does not appear in the source. + VtableClosure(VtableClosureData<'tcx, N>), + + /// Same as above, but for a function pointer type with the given signature. + VtableFnPointer(VtableFnPointerData<'tcx, N>), + + /// Vtable automatically generated for a generator. + VtableGenerator(VtableGeneratorData<'tcx, N>), + + /// Vtable for a trait alias. + VtableTraitAlias(VtableTraitAliasData<'tcx, N>), +} + +impl<'tcx, N> Vtable<'tcx, N> { + pub fn nested_obligations(self) -> Vec { + match self { + VtableImpl(i) => i.nested, + VtableParam(n) => n, + VtableBuiltin(i) => i.nested, + VtableAutoImpl(d) => d.nested, + VtableClosure(c) => c.nested, + VtableGenerator(c) => c.nested, + VtableObject(d) => d.nested, + VtableFnPointer(d) => d.nested, + VtableTraitAlias(d) => d.nested, + } + } + + pub fn map(self, f: F) -> Vtable<'tcx, M> + where + F: FnMut(N) -> M, + { + match self { + VtableImpl(i) => VtableImpl(VtableImplData { + impl_def_id: i.impl_def_id, + substs: i.substs, + nested: i.nested.into_iter().map(f).collect(), + }), + VtableParam(n) => VtableParam(n.into_iter().map(f).collect()), + VtableBuiltin(i) => { + VtableBuiltin(VtableBuiltinData { nested: i.nested.into_iter().map(f).collect() }) + } + VtableObject(o) => VtableObject(VtableObjectData { + upcast_trait_ref: o.upcast_trait_ref, + vtable_base: o.vtable_base, + nested: o.nested.into_iter().map(f).collect(), + }), + VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData { + trait_def_id: d.trait_def_id, + nested: d.nested.into_iter().map(f).collect(), + }), + VtableClosure(c) => VtableClosure(VtableClosureData { + closure_def_id: c.closure_def_id, + substs: c.substs, + nested: c.nested.into_iter().map(f).collect(), + }), + VtableGenerator(c) => VtableGenerator(VtableGeneratorData { + generator_def_id: c.generator_def_id, + substs: c.substs, + nested: c.nested.into_iter().map(f).collect(), + }), + VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData { + fn_ty: p.fn_ty, + nested: p.nested.into_iter().map(f).collect(), + }), + VtableTraitAlias(d) => VtableTraitAlias(VtableTraitAliasData { + alias_def_id: d.alias_def_id, + substs: d.substs, + nested: d.nested.into_iter().map(f).collect(), + }), + } + } +} + +/// Identifies a particular impl in the source, along with a set of +/// substitutions from the impl's type/lifetime parameters. The +/// `nested` vector corresponds to the nested obligations attached to +/// the impl's type parameters. +/// +/// The type parameter `N` indicates the type used for "nested +/// obligations" that are required by the impl. During type-check, this +/// is `Obligation`, as one might expect. During codegen, however, this +/// is `()`, because codegen only requires a shallow resolution of an +/// impl, and nested obligations are satisfied later. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableImplData<'tcx, N> { + pub impl_def_id: DefId, + pub substs: SubstsRef<'tcx>, + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableGeneratorData<'tcx, N> { + pub generator_def_id: DefId, + pub substs: SubstsRef<'tcx>, + /// Nested obligations. This can be non-empty if the generator + /// signature contains associated types. + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableClosureData<'tcx, N> { + pub closure_def_id: DefId, + pub substs: SubstsRef<'tcx>, + /// Nested obligations. This can be non-empty if the closure + /// signature contains associated types. + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableAutoImplData { + pub trait_def_id: DefId, + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableBuiltinData { + pub nested: Vec, +} + +/// A vtable for some object-safe trait `Foo` automatically derived +/// for the object type `Foo`. +#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableObjectData<'tcx, N> { + /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`. + pub upcast_trait_ref: ty::PolyTraitRef<'tcx>, + + /// The vtable is formed by concatenating together the method lists of + /// the base object trait and all supertraits; this is the start of + /// `upcast_trait_ref`'s methods in that vtable. + pub vtable_base: usize, + + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableFnPointerData<'tcx, N> { + pub fn_ty: Ty<'tcx>, + pub nested: Vec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +pub struct VtableTraitAliasData<'tcx, N> { + pub alias_def_id: DefId, + pub substs: SubstsRef<'tcx>, + pub nested: Vec, +} + +pub trait ExClauseFold<'tcx> +where + Self: chalk_engine::context::Context + Clone, +{ + fn fold_ex_clause_with>( + ex_clause: &chalk_engine::ExClause, + folder: &mut F, + ) -> chalk_engine::ExClause; + + fn visit_ex_clause_with>( + ex_clause: &chalk_engine::ExClause, + visitor: &mut V, + ) -> bool; +} + +pub trait ChalkContextLift<'tcx> +where + Self: chalk_engine::context::Context + Clone, +{ + type LiftedExClause: Debug + 'tcx; + type LiftedDelayedLiteral: Debug + 'tcx; + type LiftedLiteral: Debug + 'tcx; + + fn lift_ex_clause_to_tcx( + ex_clause: &chalk_engine::ExClause, + tcx: TyCtxt<'tcx>, + ) -> Option; + + fn lift_delayed_literal_to_tcx( + ex_clause: &chalk_engine::DelayedLiteral, + tcx: TyCtxt<'tcx>, + ) -> Option; + + fn lift_literal_to_tcx( + ex_clause: &chalk_engine::Literal, + tcx: TyCtxt<'tcx>, + ) -> Option; +} From a2cd0715fd3b3121512887e2a1e84e26cd6706f4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 08:54:46 +0100 Subject: [PATCH 0912/1253] Move traits::Reveal to traits::types. --- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/project.rs | 43 +------------------------------- src/librustc/traits/types/mod.rs | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 0eed762c000bc..53ebc3176aa23 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -51,7 +51,7 @@ pub use self::object_safety::ObjectSafetyViolation; pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote}; pub use self::project::MismatchedProjectionTypes; pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type}; -pub use self::project::{Normalized, ProjectionCache, ProjectionCacheSnapshot, Reveal}; +pub use self::project::{Normalized, ProjectionCache, ProjectionCacheSnapshot}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::find_associated_item; diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 3085837335abe..fffcf66075f93 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -19,52 +19,11 @@ use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use syntax::ast::Ident; -/// Depending on the stage of compilation, we want projection to be -/// more or less conservative. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] -pub enum Reveal { - /// At type-checking time, we refuse to project any associated - /// type that is marked `default`. Non-`default` ("final") types - /// are always projected. This is necessary in general for - /// soundness of specialization. However, we *could* allow - /// projections in fully-monomorphic cases. We choose not to, - /// because we prefer for `default type` to force the type - /// definition to be treated abstractly by any consumers of the - /// impl. Concretely, that means that the following example will - /// fail to compile: - /// - /// ``` - /// trait Assoc { - /// type Output; - /// } - /// - /// impl Assoc for T { - /// default type Output = bool; - /// } - /// - /// fn main() { - /// let <() as Assoc>::Output = true; - /// } - UserFacing, - - /// At codegen time, all monomorphic projections will succeed. - /// Also, `impl Trait` is normalized to the concrete type, - /// which has to be already collected by type-checking. - /// - /// NOTE: as `impl Trait`'s concrete type should *never* - /// be observable directly by the user, `Reveal::All` - /// should not be used by checks which may expose - /// type equality or type contents to the user. - /// There are some exceptions, e.g., around OIBITS and - /// transmute-checking, which expose some details, but - /// not the whole concrete type of the `impl Trait`. - All, -} +pub use rustc::traits::Reveal; pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>; diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs index c4a066d5ec07a..a9db2a7725460 100644 --- a/src/librustc/traits/types/mod.rs +++ b/src/librustc/traits/types/mod.rs @@ -19,6 +19,49 @@ pub use self::ObligationCauseCode::*; pub use self::SelectionError::*; pub use self::Vtable::*; +/// Depending on the stage of compilation, we want projection to be +/// more or less conservative. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] +pub enum Reveal { + /// At type-checking time, we refuse to project any associated + /// type that is marked `default`. Non-`default` ("final") types + /// are always projected. This is necessary in general for + /// soundness of specialization. However, we *could* allow + /// projections in fully-monomorphic cases. We choose not to, + /// because we prefer for `default type` to force the type + /// definition to be treated abstractly by any consumers of the + /// impl. Concretely, that means that the following example will + /// fail to compile: + /// + /// ``` + /// trait Assoc { + /// type Output; + /// } + /// + /// impl Assoc for T { + /// default type Output = bool; + /// } + /// + /// fn main() { + /// let <() as Assoc>::Output = true; + /// } + /// ``` + UserFacing, + + /// At codegen time, all monomorphic projections will succeed. + /// Also, `impl Trait` is normalized to the concrete type, + /// which has to be already collected by type-checking. + /// + /// NOTE: as `impl Trait`'s concrete type should *never* + /// be observable directly by the user, `Reveal::All` + /// should not be used by checks which may expose + /// type equality or type contents to the user. + /// There are some exceptions, e.g., around OIBITS and + /// transmute-checking, which expose some details, but + /// not the whole concrete type of the `impl Trait`. + All, +} + /// The reason why we incurred this obligation; used for error reporting. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct ObligationCause<'tcx> { From a77da35ed425b46a8df1df33ffc9563a47bbee6f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 09:01:22 +0100 Subject: [PATCH 0913/1253] Move traits::select datatypes to traits::types. --- src/librustc/traits/mod.rs | 3 +- src/librustc/traits/select.rs | 295 +--------------------------- src/librustc/traits/types/mod.rs | 4 + src/librustc/traits/types/select.rs | 283 ++++++++++++++++++++++++++ 4 files changed, 290 insertions(+), 295 deletions(-) create mode 100644 src/librustc/traits/types/select.rs diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 53ebc3176aa23..e88f4e65c7eb1 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -52,8 +52,7 @@ pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote}; pub use self::project::MismatchedProjectionTypes; pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type}; pub use self::project::{Normalized, ProjectionCache, ProjectionCacheSnapshot}; -pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; -pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; +pub use self::select::{IntercrateAmbiguityCause, SelectionContext}; pub use self::specialize::find_associated_item; pub use self::specialize::specialization_graph::FutureCompatOverlapError; pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ba0a270638cd1..ca4a2aa5935a5 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -41,7 +41,6 @@ use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, Wit use rustc_hir::def_id::DefId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::Lock; use rustc_hir as hir; use rustc_index::bit_set::GrowableBitSet; use rustc_span::symbol::sym; @@ -53,6 +52,8 @@ use std::iter; use std::rc::Rc; use syntax::{ast, attr}; +pub use rustc::traits::types::select::*; + pub struct SelectionContext<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, @@ -181,146 +182,6 @@ struct TraitObligationStack<'prev, 'tcx> { dfn: usize, } -#[derive(Clone, Default)] -pub struct SelectionCache<'tcx> { - hashmap: Lock< - FxHashMap< - ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>, - WithDepNode>>, - >, - >, -} - -/// The selection process begins by considering all impls, where -/// clauses, and so forth that might resolve an obligation. Sometimes -/// we'll be able to say definitively that (e.g.) an impl does not -/// apply to the obligation: perhaps it is defined for `usize` but the -/// obligation is for `int`. In that case, we drop the impl out of the -/// list. But the other cases are considered *candidates*. -/// -/// For selection to succeed, there must be exactly one matching -/// candidate. If the obligation is fully known, this is guaranteed -/// by coherence. However, if the obligation contains type parameters -/// or variables, there may be multiple such impls. -/// -/// It is not a real problem if multiple matching impls exist because -/// of type variables - it just means the obligation isn't sufficiently -/// elaborated. In that case we report an ambiguity, and the caller can -/// try again after more type information has been gathered or report a -/// "type annotations needed" error. -/// -/// However, with type parameters, this can be a real problem - type -/// parameters don't unify with regular types, but they *can* unify -/// with variables from blanket impls, and (unless we know its bounds -/// will always be satisfied) picking the blanket impl will be wrong -/// for at least *some* substitutions. To make this concrete, if we have -/// -/// trait AsDebug { type Out : fmt::Debug; fn debug(self) -> Self::Out; } -/// impl AsDebug for T { -/// type Out = T; -/// fn debug(self) -> fmt::Debug { self } -/// } -/// fn foo(t: T) { println!("{:?}", ::debug(t)); } -/// -/// we can't just use the impl to resolve the `` obligation -/// -- a type from another crate (that doesn't implement `fmt::Debug`) could -/// implement `AsDebug`. -/// -/// Because where-clauses match the type exactly, multiple clauses can -/// only match if there are unresolved variables, and we can mostly just -/// report this ambiguity in that case. This is still a problem - we can't -/// *do anything* with ambiguities that involve only regions. This is issue -/// #21974. -/// -/// If a single where-clause matches and there are no inference -/// variables left, then it definitely matches and we can just select -/// it. -/// -/// In fact, we even select the where-clause when the obligation contains -/// inference variables. The can lead to inference making "leaps of logic", -/// for example in this situation: -/// -/// pub trait Foo { fn foo(&self) -> T; } -/// impl Foo<()> for T { fn foo(&self) { } } -/// impl Foo for bool { fn foo(&self) -> bool { *self } } -/// -/// pub fn foo(t: T) where T: Foo { -/// println!("{:?}", >::foo(&t)); -/// } -/// fn main() { foo(false); } -/// -/// Here the obligation `>` can be matched by both the blanket -/// impl and the where-clause. We select the where-clause and unify `$0=bool`, -/// so the program prints "false". However, if the where-clause is omitted, -/// the blanket impl is selected, we unify `$0=()`, and the program prints -/// "()". -/// -/// Exactly the same issues apply to projection and object candidates, except -/// that we can have both a projection candidate and a where-clause candidate -/// for the same obligation. In that case either would do (except that -/// different "leaps of logic" would occur if inference variables are -/// present), and we just pick the where-clause. This is, for example, -/// required for associated types to work in default impls, as the bounds -/// are visible both as projection bounds and as where-clauses from the -/// parameter environment. -#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable)] -enum SelectionCandidate<'tcx> { - BuiltinCandidate { - /// `false` if there are no *further* obligations. - has_nested: bool, - }, - ParamCandidate(ty::PolyTraitRef<'tcx>), - ImplCandidate(DefId), - AutoImplCandidate(DefId), - - /// This is a trait matching with a projected type as `Self`, and - /// we found an applicable bound in the trait definition. - ProjectionCandidate, - - /// Implementation of a `Fn`-family trait by one of the anonymous types - /// generated for a `||` expression. - ClosureCandidate, - - /// Implementation of a `Generator` trait by one of the anonymous types - /// generated for a generator. - GeneratorCandidate, - - /// Implementation of a `Fn`-family trait by one of the anonymous - /// types generated for a fn pointer type (e.g., `fn(int) -> int`) - FnPointerCandidate, - - TraitAliasCandidate(DefId), - - ObjectCandidate, - - BuiltinObjectCandidate, - - BuiltinUnsizeCandidate, -} - -impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> { - type Lifted = SelectionCandidate<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - Some(match *self { - BuiltinCandidate { has_nested } => BuiltinCandidate { has_nested }, - ImplCandidate(def_id) => ImplCandidate(def_id), - AutoImplCandidate(def_id) => AutoImplCandidate(def_id), - ProjectionCandidate => ProjectionCandidate, - ClosureCandidate => ClosureCandidate, - GeneratorCandidate => GeneratorCandidate, - FnPointerCandidate => FnPointerCandidate, - TraitAliasCandidate(def_id) => TraitAliasCandidate(def_id), - ObjectCandidate => ObjectCandidate, - BuiltinObjectCandidate => BuiltinObjectCandidate, - BuiltinUnsizeCandidate => BuiltinUnsizeCandidate, - - ParamCandidate(ref trait_ref) => { - return tcx.lift(trait_ref).map(ParamCandidate); - } - }) - } -} - struct SelectionCandidateSet<'tcx> { // A list of candidates that definitely apply to the current // obligation (meaning: types unify). @@ -350,134 +211,6 @@ enum BuiltinImplConditions<'tcx> { Ambiguous, } -/// The result of trait evaluation. The order is important -/// here as the evaluation of a list is the maximum of the -/// evaluations. -/// -/// The evaluation results are ordered: -/// - `EvaluatedToOk` implies `EvaluatedToOkModuloRegions` -/// implies `EvaluatedToAmbig` implies `EvaluatedToUnknown` -/// - `EvaluatedToErr` implies `EvaluatedToRecur` -/// - the "union" of evaluation results is equal to their maximum - -/// all the "potential success" candidates can potentially succeed, -/// so they are noops when unioned with a definite error, and within -/// the categories it's easy to see that the unions are correct. -#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)] -pub enum EvaluationResult { - /// Evaluation successful. - EvaluatedToOk, - /// Evaluation successful, but there were unevaluated region obligations. - EvaluatedToOkModuloRegions, - /// Evaluation is known to be ambiguous -- it *might* hold for some - /// assignment of inference variables, but it might not. - /// - /// While this has the same meaning as `EvaluatedToUnknown` -- we can't - /// know whether this obligation holds or not -- it is the result we - /// would get with an empty stack, and therefore is cacheable. - EvaluatedToAmbig, - /// Evaluation failed because of recursion involving inference - /// variables. We are somewhat imprecise there, so we don't actually - /// know the real result. - /// - /// This can't be trivially cached for the same reason as `EvaluatedToRecur`. - EvaluatedToUnknown, - /// Evaluation failed because we encountered an obligation we are already - /// trying to prove on this branch. - /// - /// We know this branch can't be a part of a minimal proof-tree for - /// the "root" of our cycle, because then we could cut out the recursion - /// and maintain a valid proof tree. However, this does not mean - /// that all the obligations on this branch do not hold -- it's possible - /// that we entered this branch "speculatively", and that there - /// might be some other way to prove this obligation that does not - /// go through this cycle -- so we can't cache this as a failure. - /// - /// For example, suppose we have this: - /// - /// ```rust,ignore (pseudo-Rust) - /// pub trait Trait { fn xyz(); } - /// // This impl is "useless", but we can still have - /// // an `impl Trait for SomeUnsizedType` somewhere. - /// impl Trait for T { fn xyz() {} } - /// - /// pub fn foo() { - /// ::xyz(); - /// } - /// ``` - /// - /// When checking `foo`, we have to prove `T: Trait`. This basically - /// translates into this: - /// - /// ```plain,ignore - /// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait - /// ``` - /// - /// When we try to prove it, we first go the first option, which - /// recurses. This shows us that the impl is "useless" -- it won't - /// tell us that `T: Trait` unless it already implemented `Trait` - /// by some other means. However, that does not prevent `T: Trait` - /// does not hold, because of the bound (which can indeed be satisfied - /// by `SomeUnsizedType` from another crate). - // - // FIXME: when an `EvaluatedToRecur` goes past its parent root, we - // ought to convert it to an `EvaluatedToErr`, because we know - // there definitely isn't a proof tree for that obligation. Not - // doing so is still sound -- there isn't any proof tree, so the - // branch still can't be a part of a minimal one -- but does not re-enable caching. - EvaluatedToRecur, - /// Evaluation failed. - EvaluatedToErr, -} - -impl EvaluationResult { - /// Returns `true` if this evaluation result is known to apply, even - /// considering outlives constraints. - pub fn must_apply_considering_regions(self) -> bool { - self == EvaluatedToOk - } - - /// Returns `true` if this evaluation result is known to apply, ignoring - /// outlives constraints. - pub fn must_apply_modulo_regions(self) -> bool { - self <= EvaluatedToOkModuloRegions - } - - pub fn may_apply(self) -> bool { - match self { - EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => { - true - } - - EvaluatedToErr | EvaluatedToRecur => false, - } - } - - fn is_stack_dependent(self) -> bool { - match self { - EvaluatedToUnknown | EvaluatedToRecur => true, - - EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false, - } - } -} - -/// Indicates that trait evaluation caused overflow. -#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)] -pub struct OverflowError; - -impl<'tcx> From for SelectionError<'tcx> { - fn from(OverflowError: OverflowError) -> SelectionError<'tcx> { - SelectionError::Overflow - } -} - -#[derive(Clone, Default)] -pub struct EvaluationCache<'tcx> { - hashmap: Lock< - FxHashMap>, WithDepNode>, - >, -} - impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { @@ -3827,13 +3560,6 @@ impl<'tcx> TraitObligation<'tcx> { } } -impl<'tcx> SelectionCache<'tcx> { - /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` - pub fn clear(&self) { - *self.hashmap.borrow_mut() = Default::default(); - } -} - impl<'tcx> EvaluationCache<'tcx> { /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` pub fn clear(&self) { @@ -4126,20 +3852,3 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> { write!(f, "TraitObligationStack({:?})", self.obligation) } } - -#[derive(Clone, Eq, PartialEq)] -pub struct WithDepNode { - dep_node: DepNodeIndex, - cached_value: T, -} - -impl WithDepNode { - pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { - WithDepNode { dep_node, cached_value } - } - - pub fn get(&self, tcx: TyCtxt<'_>) -> T { - tcx.dep_graph.read_index(self.dep_node); - self.cached_value.clone() - } -} diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs index a9db2a7725460..05fd02d6aa6cf 100644 --- a/src/librustc/traits/types/mod.rs +++ b/src/librustc/traits/types/mod.rs @@ -2,6 +2,8 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html +pub mod select; + use crate::mir::interpret::ErrorHandled; use crate::ty::fold::{TypeFolder, TypeVisitor}; use crate::ty::subst::SubstsRef; @@ -15,6 +17,8 @@ use syntax::ast; use std::fmt::Debug; use std::rc::Rc; +pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; + pub use self::ObligationCauseCode::*; pub use self::SelectionError::*; pub use self::Vtable::*; diff --git a/src/librustc/traits/types/select.rs b/src/librustc/traits/types/select.rs new file mode 100644 index 0000000000000..9e5bd4cbb9a05 --- /dev/null +++ b/src/librustc/traits/types/select.rs @@ -0,0 +1,283 @@ +//! Candidate selection. See the [rustc guide] for more information on how this works. +//! +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection + +use self::EvaluationResult::*; + +use super::{SelectionError, SelectionResult}; + +use crate::dep_graph::DepNodeIndex; +use crate::ty::{self, TyCtxt}; + +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lock; +use rustc_hir::def_id::DefId; + +#[derive(Clone, Default)] +pub struct SelectionCache<'tcx> { + pub hashmap: Lock< + FxHashMap< + ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>, + WithDepNode>>, + >, + >, +} + +impl<'tcx> SelectionCache<'tcx> { + /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` + pub fn clear(&self) { + *self.hashmap.borrow_mut() = Default::default(); + } +} + +/// The selection process begins by considering all impls, where +/// clauses, and so forth that might resolve an obligation. Sometimes +/// we'll be able to say definitively that (e.g.) an impl does not +/// apply to the obligation: perhaps it is defined for `usize` but the +/// obligation is for `int`. In that case, we drop the impl out of the +/// list. But the other cases are considered *candidates*. +/// +/// For selection to succeed, there must be exactly one matching +/// candidate. If the obligation is fully known, this is guaranteed +/// by coherence. However, if the obligation contains type parameters +/// or variables, there may be multiple such impls. +/// +/// It is not a real problem if multiple matching impls exist because +/// of type variables - it just means the obligation isn't sufficiently +/// elaborated. In that case we report an ambiguity, and the caller can +/// try again after more type information has been gathered or report a +/// "type annotations needed" error. +/// +/// However, with type parameters, this can be a real problem - type +/// parameters don't unify with regular types, but they *can* unify +/// with variables from blanket impls, and (unless we know its bounds +/// will always be satisfied) picking the blanket impl will be wrong +/// for at least *some* substitutions. To make this concrete, if we have +/// +/// trait AsDebug { type Out : fmt::Debug; fn debug(self) -> Self::Out; } +/// impl AsDebug for T { +/// type Out = T; +/// fn debug(self) -> fmt::Debug { self } +/// } +/// fn foo(t: T) { println!("{:?}", ::debug(t)); } +/// +/// we can't just use the impl to resolve the `` obligation +/// -- a type from another crate (that doesn't implement `fmt::Debug`) could +/// implement `AsDebug`. +/// +/// Because where-clauses match the type exactly, multiple clauses can +/// only match if there are unresolved variables, and we can mostly just +/// report this ambiguity in that case. This is still a problem - we can't +/// *do anything* with ambiguities that involve only regions. This is issue +/// #21974. +/// +/// If a single where-clause matches and there are no inference +/// variables left, then it definitely matches and we can just select +/// it. +/// +/// In fact, we even select the where-clause when the obligation contains +/// inference variables. The can lead to inference making "leaps of logic", +/// for example in this situation: +/// +/// pub trait Foo { fn foo(&self) -> T; } +/// impl Foo<()> for T { fn foo(&self) { } } +/// impl Foo for bool { fn foo(&self) -> bool { *self } } +/// +/// pub fn foo(t: T) where T: Foo { +/// println!("{:?}", >::foo(&t)); +/// } +/// fn main() { foo(false); } +/// +/// Here the obligation `>` can be matched by both the blanket +/// impl and the where-clause. We select the where-clause and unify `$0=bool`, +/// so the program prints "false". However, if the where-clause is omitted, +/// the blanket impl is selected, we unify `$0=()`, and the program prints +/// "()". +/// +/// Exactly the same issues apply to projection and object candidates, except +/// that we can have both a projection candidate and a where-clause candidate +/// for the same obligation. In that case either would do (except that +/// different "leaps of logic" would occur if inference variables are +/// present), and we just pick the where-clause. This is, for example, +/// required for associated types to work in default impls, as the bounds +/// are visible both as projection bounds and as where-clauses from the +/// parameter environment. +#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable)] +pub enum SelectionCandidate<'tcx> { + BuiltinCandidate { + /// `false` if there are no *further* obligations. + has_nested: bool, + }, + ParamCandidate(ty::PolyTraitRef<'tcx>), + ImplCandidate(DefId), + AutoImplCandidate(DefId), + + /// This is a trait matching with a projected type as `Self`, and + /// we found an applicable bound in the trait definition. + ProjectionCandidate, + + /// Implementation of a `Fn`-family trait by one of the anonymous types + /// generated for a `||` expression. + ClosureCandidate, + + /// Implementation of a `Generator` trait by one of the anonymous types + /// generated for a generator. + GeneratorCandidate, + + /// Implementation of a `Fn`-family trait by one of the anonymous + /// types generated for a fn pointer type (e.g., `fn(int) -> int`) + FnPointerCandidate, + + TraitAliasCandidate(DefId), + + ObjectCandidate, + + BuiltinObjectCandidate, + + BuiltinUnsizeCandidate, +} + +/// The result of trait evaluation. The order is important +/// here as the evaluation of a list is the maximum of the +/// evaluations. +/// +/// The evaluation results are ordered: +/// - `EvaluatedToOk` implies `EvaluatedToOkModuloRegions` +/// implies `EvaluatedToAmbig` implies `EvaluatedToUnknown` +/// - `EvaluatedToErr` implies `EvaluatedToRecur` +/// - the "union" of evaluation results is equal to their maximum - +/// all the "potential success" candidates can potentially succeed, +/// so they are noops when unioned with a definite error, and within +/// the categories it's easy to see that the unions are correct. +#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)] +pub enum EvaluationResult { + /// Evaluation successful. + EvaluatedToOk, + /// Evaluation successful, but there were unevaluated region obligations. + EvaluatedToOkModuloRegions, + /// Evaluation is known to be ambiguous -- it *might* hold for some + /// assignment of inference variables, but it might not. + /// + /// While this has the same meaning as `EvaluatedToUnknown` -- we can't + /// know whether this obligation holds or not -- it is the result we + /// would get with an empty stack, and therefore is cacheable. + EvaluatedToAmbig, + /// Evaluation failed because of recursion involving inference + /// variables. We are somewhat imprecise there, so we don't actually + /// know the real result. + /// + /// This can't be trivially cached for the same reason as `EvaluatedToRecur`. + EvaluatedToUnknown, + /// Evaluation failed because we encountered an obligation we are already + /// trying to prove on this branch. + /// + /// We know this branch can't be a part of a minimal proof-tree for + /// the "root" of our cycle, because then we could cut out the recursion + /// and maintain a valid proof tree. However, this does not mean + /// that all the obligations on this branch do not hold -- it's possible + /// that we entered this branch "speculatively", and that there + /// might be some other way to prove this obligation that does not + /// go through this cycle -- so we can't cache this as a failure. + /// + /// For example, suppose we have this: + /// + /// ```rust,ignore (pseudo-Rust) + /// pub trait Trait { fn xyz(); } + /// // This impl is "useless", but we can still have + /// // an `impl Trait for SomeUnsizedType` somewhere. + /// impl Trait for T { fn xyz() {} } + /// + /// pub fn foo() { + /// ::xyz(); + /// } + /// ``` + /// + /// When checking `foo`, we have to prove `T: Trait`. This basically + /// translates into this: + /// + /// ```plain,ignore + /// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait + /// ``` + /// + /// When we try to prove it, we first go the first option, which + /// recurses. This shows us that the impl is "useless" -- it won't + /// tell us that `T: Trait` unless it already implemented `Trait` + /// by some other means. However, that does not prevent `T: Trait` + /// does not hold, because of the bound (which can indeed be satisfied + /// by `SomeUnsizedType` from another crate). + // + // FIXME: when an `EvaluatedToRecur` goes past its parent root, we + // ought to convert it to an `EvaluatedToErr`, because we know + // there definitely isn't a proof tree for that obligation. Not + // doing so is still sound -- there isn't any proof tree, so the + // branch still can't be a part of a minimal one -- but does not re-enable caching. + EvaluatedToRecur, + /// Evaluation failed. + EvaluatedToErr, +} + +impl EvaluationResult { + /// Returns `true` if this evaluation result is known to apply, even + /// considering outlives constraints. + pub fn must_apply_considering_regions(self) -> bool { + self == EvaluatedToOk + } + + /// Returns `true` if this evaluation result is known to apply, ignoring + /// outlives constraints. + pub fn must_apply_modulo_regions(self) -> bool { + self <= EvaluatedToOkModuloRegions + } + + pub fn may_apply(self) -> bool { + match self { + EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => { + true + } + + EvaluatedToErr | EvaluatedToRecur => false, + } + } + + pub fn is_stack_dependent(self) -> bool { + match self { + EvaluatedToUnknown | EvaluatedToRecur => true, + + EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false, + } + } +} + +/// Indicates that trait evaluation caused overflow. +#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)] +pub struct OverflowError; + +impl<'tcx> From for SelectionError<'tcx> { + fn from(OverflowError: OverflowError) -> SelectionError<'tcx> { + SelectionError::Overflow + } +} + +#[derive(Clone, Default)] +pub struct EvaluationCache<'tcx> { + pub hashmap: Lock< + FxHashMap>, WithDepNode>, + >, +} + +#[derive(Clone, Eq, PartialEq)] +pub struct WithDepNode { + dep_node: DepNodeIndex, + cached_value: T, +} + +impl WithDepNode { + pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { + WithDepNode { dep_node, cached_value } + } + + pub fn get(&self, tcx: TyCtxt<'_>) -> T { + tcx.dep_graph.read_index(self.dep_node); + self.cached_value.clone() + } +} From 4e42f388c375b0d6eb25af087cb2a66069419529 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 09:04:50 +0100 Subject: [PATCH 0914/1253] Move traits::query datatypes to traits::types. --- src/librustc/traits/query/dropck_outlives.rs | 79 +---- src/librustc/traits/query/method_autoderef.rs | 34 +- src/librustc/traits/query/mod.rs | 37 +- src/librustc/traits/query/normalize.rs | 9 +- src/librustc/traits/query/outlives_bounds.rs | 38 +- .../traits/query/type_op/ascribe_user_type.rs | 17 +- src/librustc/traits/query/type_op/eq.rs | 14 +- src/librustc/traits/query/type_op/mod.rs | 2 + .../traits/query/type_op/normalize.rs | 14 +- .../traits/query/type_op/prove_predicate.rs | 11 +- src/librustc/traits/query/type_op/subtype.rs | 14 +- src/librustc/traits/types/mod.rs | 1 + src/librustc/traits/types/query.rs | 332 ++++++++++++++++++ 13 files changed, 353 insertions(+), 249 deletions(-) create mode 100644 src/librustc/traits/types/query.rs diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 2e5ef5adcd30e..a1d7a2836e42d 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -1,10 +1,11 @@ use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferOk; -use crate::ty::subst::GenericArg; -use crate::ty::{self, Ty, TyCtxt}; -use rustc_span::source_map::Span; -use std::iter::FromIterator; + +use rustc::ty::subst::GenericArg; +use rustc::ty::{self, Ty, TyCtxt}; + +pub use rustc::traits::query::{DropckOutlivesResult, DtorckConstraint}; impl<'cx, 'tcx> At<'cx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -65,76 +66,6 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } } -#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] -pub struct DropckOutlivesResult<'tcx> { - pub kinds: Vec>, - pub overflows: Vec>, -} - -impl<'tcx> DropckOutlivesResult<'tcx> { - pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) { - if let Some(overflow_ty) = self.overflows.iter().next() { - rustc_errors::struct_span_err!( - tcx.sess, - span, - E0320, - "overflow while adding drop-check rules for {}", - ty, - ) - .note(&format!("overflowed on {}", overflow_ty)) - .emit(); - } - } - - pub fn into_kinds_reporting_overflows( - self, - tcx: TyCtxt<'tcx>, - span: Span, - ty: Ty<'tcx>, - ) -> Vec> { - self.report_overflows(tcx, span, ty); - let DropckOutlivesResult { kinds, overflows: _ } = self; - kinds - } -} - -/// A set of constraints that need to be satisfied in order for -/// a type to be valid for destruction. -#[derive(Clone, Debug, HashStable)] -pub struct DtorckConstraint<'tcx> { - /// Types that are required to be alive in order for this - /// type to be valid for destruction. - pub outlives: Vec>, - - /// Types that could not be resolved: projections and params. - pub dtorck_types: Vec>, - - /// If, during the computation of the dtorck constraint, we - /// overflow, that gets recorded here. The caller is expected to - /// report an error. - pub overflows: Vec>, -} - -impl<'tcx> DtorckConstraint<'tcx> { - pub fn empty() -> DtorckConstraint<'tcx> { - DtorckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } - } -} - -impl<'tcx> FromIterator> for DtorckConstraint<'tcx> { - fn from_iter>>(iter: I) -> Self { - let mut result = Self::empty(); - - for DtorckConstraint { outlives, dtorck_types, overflows } in iter { - result.outlives.extend(outlives); - result.dtorck_types.extend(dtorck_types); - result.overflows.extend(overflows); - } - - result - } -} - /// This returns true if the type `ty` is "trivial" for /// dropck-outlives -- that is, if it doesn't require any types to /// outlive. This is similar but not *quite* the same as the diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs index 4ef775750ec37..80748c5ef388e 100644 --- a/src/librustc/traits/query/method_autoderef.rs +++ b/src/librustc/traits/query/method_autoderef.rs @@ -1,33 +1 @@ -use crate::infer::canonical::{Canonical, QueryResponse}; -use crate::ty::Ty; -use rustc_data_structures::sync::Lrc; - -#[derive(Debug, HashStable)] -pub struct CandidateStep<'tcx> { - pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, - pub autoderefs: usize, - /// `true` if the type results from a dereference of a raw pointer. - /// when assembling candidates, we include these steps, but not when - /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods - /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then - /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't. - pub from_unsafe_deref: bool, - pub unsize: bool, -} - -#[derive(Clone, Debug, HashStable)] -pub struct MethodAutoderefStepsResult<'tcx> { - /// The valid autoderef steps that could be find. - pub steps: Lrc>>, - /// If Some(T), a type autoderef reported an error on. - pub opt_bad_ty: Option>>, - /// If `true`, `steps` has been truncated due to reaching the - /// recursion limit. - pub reached_recursion_limit: bool, -} - -#[derive(Debug, HashStable)] -pub struct MethodAutoderefBadTy<'tcx> { - pub reached_raw_pointer: bool, - pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, -} +pub use rustc::traits::query::{CandidateStep, MethodAutoderefBadTy, MethodAutoderefStepsResult}; diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 440268aab8fb3..20a873dc4c6b6 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -5,10 +5,6 @@ //! The providers for the queries defined here can be found in //! `librustc_traits`. -use crate::infer::canonical::Canonical; -use crate::ty::error::TypeError; -use crate::ty::{self, Ty}; - pub mod dropck_outlives; pub mod evaluate_obligation; pub mod method_autoderef; @@ -16,35 +12,4 @@ pub mod normalize; pub mod outlives_bounds; pub mod type_op; -pub type CanonicalProjectionGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>; - -pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; - -pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; - -pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ascribe_user_type::AscribeUserType<'tcx>>>; - -pub type CanonicalTypeOpEqGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::eq::Eq<'tcx>>>; - -pub type CanonicalTypeOpSubtypeGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::subtype::Subtype<'tcx>>>; - -pub type CanonicalTypeOpProvePredicateGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>; - -pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize>>; - -#[derive(Clone, Debug, HashStable)] -pub struct NoSolution; - -pub type Fallible = Result; - -impl<'tcx> From> for NoSolution { - fn from(_: TypeError<'tcx>) -> NoSolution { - NoSolution - } -} +pub use rustc::traits::types::query::*; diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 20d7b5563774e..737b4fc6bb9dc 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -13,6 +13,8 @@ use crate::ty::{self, Ty, TyCtxt}; use super::NoSolution; +pub use rustc::traits::query::NormalizationResult; + impl<'cx, 'tcx> At<'cx, 'tcx> { /// Normalize `value` in the context of the inference context, /// yielding a resulting type, or an error if `value` cannot be @@ -59,13 +61,6 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } } -/// Result from the `normalize_projection_ty` query. -#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] -pub struct NormalizationResult<'tcx> { - /// Result of normalization. - pub normalized_ty: Ty<'tcx>, -} - struct QueryNormalizer<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, cause: &'cx ObligationCause<'tcx>, diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index 07e57e847b13d..594faffa5f3aa 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -6,43 +6,7 @@ use crate::ty::{self, Ty}; use rustc_hir as hir; use rustc_span::source_map::Span; -use crate::ich::StableHashingContext; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use std::mem; - -/// Outlives bounds are relationships between generic parameters, -/// whether they both be regions (`'a: 'b`) or whether types are -/// involved (`T: 'a`). These relationships can be extracted from the -/// full set of predicates we understand or also from types (in which -/// case they are called implied bounds). They are fed to the -/// `OutlivesEnv` which in turn is supplied to the region checker and -/// other parts of the inference system. -#[derive(Clone, Debug, TypeFoldable, Lift)] -pub enum OutlivesBound<'tcx> { - RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), - RegionSubParam(ty::Region<'tcx>, ty::ParamTy), - RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), -} - -impl<'a, 'tcx> HashStable> for OutlivesBound<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - OutlivesBound::RegionSubRegion(ref a, ref b) => { - a.hash_stable(hcx, hasher); - b.hash_stable(hcx, hasher); - } - OutlivesBound::RegionSubParam(ref a, ref b) => { - a.hash_stable(hcx, hasher); - b.hash_stable(hcx, hasher); - } - OutlivesBound::RegionSubProjection(ref a, ref b) => { - a.hash_stable(hcx, hasher); - b.hash_stable(hcx, hasher); - } - } - } -} +pub use rustc::traits::query::OutlivesBound; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Implied bounds are region relationships that we deduce diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index 46b656eb94548..b14b79f090778 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -1,21 +1,8 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; -use crate::ty::subst::UserSubsts; -use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -use rustc_hir::def_id::DefId; +use rustc::ty::{ParamEnvAnd, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] -pub struct AscribeUserType<'tcx> { - pub mir_ty: Ty<'tcx>, - pub def_id: DefId, - pub user_substs: UserSubsts<'tcx>, -} - -impl<'tcx> AscribeUserType<'tcx> { - pub fn new(mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>) -> Self { - Self { mir_ty, def_id, user_substs } - } -} +pub use rustc::traits::query::type_op::AscribeUserType; impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { type QueryResponse = (); diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 267722362c5c7..1de13430d4623 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -1,18 +1,8 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; -use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::{ParamEnvAnd, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] -pub struct Eq<'tcx> { - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} - -impl<'tcx> Eq<'tcx> { - pub fn new(a: Ty<'tcx>, b: Ty<'tcx>) -> Self { - Self { a, b } - } -} +pub use rustc::traits::query::type_op::Eq; impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { type QueryResponse = (); diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index adf63e4d60c99..2d03d77cf6645 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -19,6 +19,8 @@ pub mod prove_predicate; use self::prove_predicate::ProvePredicate; pub mod subtype; +pub use crate::traits::types::query::type_op::*; + /// "Type ops" are used in NLL to perform some particular action and /// extract out the resulting region constraints (or an error if it /// cannot be completed). diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index 8a028eecd5b62..b1e0e29620df6 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -4,19 +4,7 @@ use crate::ty::fold::TypeFoldable; use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; use std::fmt; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] -pub struct Normalize { - pub value: T, -} - -impl<'tcx, T> Normalize -where - T: fmt::Debug + TypeFoldable<'tcx>, -{ - pub fn new(value: T) -> Self { - Self { value } - } -} +pub use rustc::traits::query::type_op::Normalize; impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize where diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index 15870ec95d8d2..92cfb82e27e95 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -2,16 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] -pub struct ProvePredicate<'tcx> { - pub predicate: Predicate<'tcx>, -} - -impl<'tcx> ProvePredicate<'tcx> { - pub fn new(predicate: Predicate<'tcx>) -> Self { - ProvePredicate { predicate } - } -} +pub use rustc::traits::query::type_op::ProvePredicate; impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { type QueryResponse = (); diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index c70508a20a182..2877a74aaff01 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -1,18 +1,8 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; -use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::{ParamEnvAnd, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] -pub struct Subtype<'tcx> { - pub sub: Ty<'tcx>, - pub sup: Ty<'tcx>, -} - -impl<'tcx> Subtype<'tcx> { - pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { - Self { sub, sup } - } -} +pub use rustc::traits::query::type_op::Subtype; impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { type QueryResponse = (); diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs index 05fd02d6aa6cf..c795248802672 100644 --- a/src/librustc/traits/types/mod.rs +++ b/src/librustc/traits/types/mod.rs @@ -2,6 +2,7 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html +pub mod query; pub mod select; use crate::mir::interpret::ErrorHandled; diff --git a/src/librustc/traits/types/query.rs b/src/librustc/traits/types/query.rs new file mode 100644 index 0000000000000..c90551826202e --- /dev/null +++ b/src/librustc/traits/types/query.rs @@ -0,0 +1,332 @@ +//! Experimental types for the trait query interface. The methods +//! defined in this module are all based on **canonicalization**, +//! which makes a canonical query by replacing unbound inference +//! variables and regions, so that results can be reused more broadly. +//! The providers for the queries defined here can be found in +//! `librustc_traits`. + +use crate::ich::StableHashingContext; +use crate::infer::canonical::{Canonical, QueryResponse}; +use crate::ty::error::TypeError; +use crate::ty::subst::GenericArg; +use crate::ty::{self, Ty, TyCtxt}; + +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::Lrc; +use rustc_errors::struct_span_err; +use rustc_span::source_map::Span; +use std::iter::FromIterator; +use std::mem; + +pub mod type_op { + use crate::ty::fold::TypeFoldable; + use crate::ty::subst::UserSubsts; + use crate::ty::{Predicate, Ty}; + use rustc_hir::def_id::DefId; + use std::fmt; + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] + pub struct AscribeUserType<'tcx> { + pub mir_ty: Ty<'tcx>, + pub def_id: DefId, + pub user_substs: UserSubsts<'tcx>, + } + + impl<'tcx> AscribeUserType<'tcx> { + pub fn new(mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>) -> Self { + Self { mir_ty, def_id, user_substs } + } + } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] + pub struct Eq<'tcx> { + pub a: Ty<'tcx>, + pub b: Ty<'tcx>, + } + + impl<'tcx> Eq<'tcx> { + pub fn new(a: Ty<'tcx>, b: Ty<'tcx>) -> Self { + Self { a, b } + } + } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] + pub struct Subtype<'tcx> { + pub sub: Ty<'tcx>, + pub sup: Ty<'tcx>, + } + + impl<'tcx> Subtype<'tcx> { + pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { + Self { sub, sup } + } + } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] + pub struct ProvePredicate<'tcx> { + pub predicate: Predicate<'tcx>, + } + + impl<'tcx> ProvePredicate<'tcx> { + pub fn new(predicate: Predicate<'tcx>) -> Self { + ProvePredicate { predicate } + } + } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] + pub struct Normalize { + pub value: T, + } + + impl<'tcx, T> Normalize + where + T: fmt::Debug + TypeFoldable<'tcx>, + { + pub fn new(value: T) -> Self { + Self { value } + } + } +} + +pub type CanonicalProjectionGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>; + +pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; + +pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; + +pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>; + +pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>; + +pub type CanonicalTypeOpSubtypeGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>; + +pub type CanonicalTypeOpProvePredicateGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>; + +pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; + +#[derive(Clone, Debug, HashStable)] +pub struct NoSolution; + +pub type Fallible = Result; + +impl<'tcx> From> for NoSolution { + fn from(_: TypeError<'tcx>) -> NoSolution { + NoSolution + } +} + +#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] +pub struct DropckOutlivesResult<'tcx> { + pub kinds: Vec>, + pub overflows: Vec>, +} + +impl<'tcx> DropckOutlivesResult<'tcx> { + pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) { + if let Some(overflow_ty) = self.overflows.iter().next() { + let mut err = struct_span_err!( + tcx.sess, + span, + E0320, + "overflow while adding drop-check rules for {}", + ty, + ); + err.note(&format!("overflowed on {}", overflow_ty)); + err.emit(); + } + } + + pub fn into_kinds_reporting_overflows( + self, + tcx: TyCtxt<'tcx>, + span: Span, + ty: Ty<'tcx>, + ) -> Vec> { + self.report_overflows(tcx, span, ty); + let DropckOutlivesResult { kinds, overflows: _ } = self; + kinds + } +} + +/// A set of constraints that need to be satisfied in order for +/// a type to be valid for destruction. +#[derive(Clone, Debug, HashStable)] +pub struct DtorckConstraint<'tcx> { + /// Types that are required to be alive in order for this + /// type to be valid for destruction. + pub outlives: Vec>, + + /// Types that could not be resolved: projections and params. + pub dtorck_types: Vec>, + + /// If, during the computation of the dtorck constraint, we + /// overflow, that gets recorded here. The caller is expected to + /// report an error. + pub overflows: Vec>, +} + +impl<'tcx> DtorckConstraint<'tcx> { + pub fn empty() -> DtorckConstraint<'tcx> { + DtorckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } + } +} + +impl<'tcx> FromIterator> for DtorckConstraint<'tcx> { + fn from_iter>>(iter: I) -> Self { + let mut result = Self::empty(); + + for DtorckConstraint { outlives, dtorck_types, overflows } in iter { + result.outlives.extend(outlives); + result.dtorck_types.extend(dtorck_types); + result.overflows.extend(overflows); + } + + result + } +} + +/// This returns true if the type `ty` is "trivial" for +/// dropck-outlives -- that is, if it doesn't require any types to +/// outlive. This is similar but not *quite* the same as the +/// `needs_drop` test in the compiler already -- that is, for every +/// type T for which this function return true, needs-drop would +/// return `false`. But the reverse does not hold: in particular, +/// `needs_drop` returns false for `PhantomData`, but it is not +/// trivial for dropck-outlives. +/// +/// Note also that `needs_drop` requires a "global" type (i.e., one +/// with erased regions), but this function does not. +pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { + match ty.kind { + // None of these types have a destructor and hence they do not + // require anything in particular to outlive the dtor's + // execution. + ty::Infer(ty::FreshIntTy(_)) + | ty::Infer(ty::FreshFloatTy(_)) + | ty::Bool + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Never + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Char + | ty::GeneratorWitness(..) + | ty::RawPtr(_) + | ty::Ref(..) + | ty::Str + | ty::Foreign(..) + | ty::Error => true, + + // [T; N] and [T] have same properties as T. + ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), + + // (T1..Tn) and closures have same properties as T1..Tn -- + // check if *any* of those are trivial. + ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), + ty::Closure(def_id, ref substs) => { + substs.as_closure().upvar_tys(def_id, tcx).all(|t| trivial_dropck_outlives(tcx, t)) + } + + ty::Adt(def, _) => { + if Some(def.did) == tcx.lang_items().manually_drop() { + // `ManuallyDrop` never has a dtor. + true + } else { + // Other types might. Moreover, PhantomData doesn't + // have a dtor, but it is considered to own its + // content, so it is non-trivial. Unions can have `impl Drop`, + // and hence are non-trivial as well. + false + } + } + + // The following *might* require a destructor: needs deeper inspection. + ty::Dynamic(..) + | ty::Projection(..) + | ty::Param(_) + | ty::Opaque(..) + | ty::Placeholder(..) + | ty::Infer(_) + | ty::Bound(..) + | ty::Generator(..) => false, + + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + } +} + +#[derive(Debug, HashStable)] +pub struct CandidateStep<'tcx> { + pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, + pub autoderefs: usize, + /// `true` if the type results from a dereference of a raw pointer. + /// when assembling candidates, we include these steps, but not when + /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods + /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then + /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't. + pub from_unsafe_deref: bool, + pub unsize: bool, +} + +#[derive(Clone, Debug, HashStable)] +pub struct MethodAutoderefStepsResult<'tcx> { + /// The valid autoderef steps that could be find. + pub steps: Lrc>>, + /// If Some(T), a type autoderef reported an error on. + pub opt_bad_ty: Option>>, + /// If `true`, `steps` has been truncated due to reaching the + /// recursion limit. + pub reached_recursion_limit: bool, +} + +#[derive(Debug, HashStable)] +pub struct MethodAutoderefBadTy<'tcx> { + pub reached_raw_pointer: bool, + pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, +} + +/// Result from the `normalize_projection_ty` query. +#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] +pub struct NormalizationResult<'tcx> { + /// Result of normalization. + pub normalized_ty: Ty<'tcx>, +} + +/// Outlives bounds are relationships between generic parameters, +/// whether they both be regions (`'a: 'b`) or whether types are +/// involved (`T: 'a`). These relationships can be extracted from the +/// full set of predicates we understand or also from types (in which +/// case they are called implied bounds). They are fed to the +/// `OutlivesEnv` which in turn is supplied to the region checker and +/// other parts of the inference system. +#[derive(Clone, Debug, TypeFoldable, Lift)] +pub enum OutlivesBound<'tcx> { + RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), + RegionSubParam(ty::Region<'tcx>, ty::ParamTy), + RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), +} + +impl<'a, 'tcx> HashStable> for OutlivesBound<'tcx> { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + OutlivesBound::RegionSubRegion(ref a, ref b) => { + a.hash_stable(hcx, hasher); + b.hash_stable(hcx, hasher); + } + OutlivesBound::RegionSubParam(ref a, ref b) => { + a.hash_stable(hcx, hasher); + b.hash_stable(hcx, hasher); + } + OutlivesBound::RegionSubProjection(ref a, ref b) => { + a.hash_stable(hcx, hasher); + b.hash_stable(hcx, hasher); + } + } + } +} From 9c07dad7258fad6b7504f9e2569fece97fa394b6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:31:42 +0100 Subject: [PATCH 0915/1253] Move infer::region_constraints::MemberConstraint to infer::types module. --- src/librustc/infer/mod.rs | 1 + src/librustc/infer/region_constraints/mod.rs | 26 ++---------------- src/librustc/infer/types/mod.rs | 29 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 src/librustc/infer/types/mod.rs diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index f67669e367f00..1f1ff1fd8bc13 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -61,6 +61,7 @@ pub mod region_constraints; pub mod resolve; mod sub; pub mod type_variable; +mod types; pub mod unify_key; #[must_use] diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 27ed3c7813892..410058b70b5d8 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -23,6 +23,8 @@ use std::{cmp, fmt, mem}; mod leak_check; +pub use rustc::infer::types::MemberConstraint; + #[derive(Default)] pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. @@ -145,30 +147,6 @@ impl Constraint<'_> { } } -/// Requires that `region` must be equal to one of the regions in `choice_regions`. -/// We often denote this using the syntax: -/// -/// ``` -/// R0 member of [O1..On] -/// ``` -#[derive(Debug, Clone, HashStable, TypeFoldable, Lift)] -pub struct MemberConstraint<'tcx> { - /// The `DefId` of the opaque type causing this constraint: used for error reporting. - pub opaque_type_def_id: DefId, - - /// The span where the hidden type was instantiated. - pub definition_span: Span, - - /// The hidden type in which `member_region` appears: used for error reporting. - pub hidden_ty: Ty<'tcx>, - - /// The region `R0`. - pub member_region: Region<'tcx>, - - /// The options `O1..On`. - pub choice_regions: Lrc>>, -} - /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or /// associated type) must outlive the region `R`. `T` is known to /// outlive `RS`. Therefore, verify that `R <= RS[i]` for some diff --git a/src/librustc/infer/types/mod.rs b/src/librustc/infer/types/mod.rs new file mode 100644 index 0000000000000..f9346b99cde40 --- /dev/null +++ b/src/librustc/infer/types/mod.rs @@ -0,0 +1,29 @@ +use crate::ty::Region; +use crate::ty::Ty; +use rustc_data_structures::sync::Lrc; +use rustc_hir::def_id::DefId; +use rustc_span::Span; + +/// Requires that `region` must be equal to one of the regions in `choice_regions`. +/// We often denote this using the syntax: +/// +/// ``` +/// R0 member of [O1..On] +/// ``` +#[derive(Debug, Clone, HashStable, TypeFoldable, Lift)] +pub struct MemberConstraint<'tcx> { + /// The `DefId` of the opaque type causing this constraint: used for error reporting. + pub opaque_type_def_id: DefId, + + /// The span where the hidden type was instantiated. + pub definition_span: Span, + + /// The hidden type in which `member_region` appears: used for error reporting. + pub hidden_ty: Ty<'tcx>, + + /// The region `R0`. + pub member_region: Region<'tcx>, + + /// The options `O1..On`. + pub choice_regions: Lrc>>, +} From 005f14d51809e385eb396bb2c1a115cf9ba21872 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:35:27 +0100 Subject: [PATCH 0916/1253] Move infer::canonical datatypes to infer::types. --- src/librustc/infer/canonical/mod.rs | 339 +----------------------- src/librustc/infer/types/canonical.rs | 357 ++++++++++++++++++++++++++ src/librustc/infer/types/mod.rs | 2 + 3 files changed, 364 insertions(+), 334 deletions(-) create mode 100644 src/librustc/infer/types/canonical.rs diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index a588d3d028a2c..f157d805bcd8c 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -21,18 +21,15 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use crate::infer::region_constraints::MemberConstraint; use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; -use crate::ty::fold::TypeFoldable; -use crate::ty::subst::GenericArg; -use crate::ty::{self, BoundVar, List, Region, TyCtxt}; +use rustc::ty::fold::TypeFoldable; +use rustc::ty::subst::GenericArg; +use rustc::ty::{self, BoundVar, List}; use rustc_index::vec::IndexVec; -use rustc_macros::HashStable; -use rustc_serialize::UseSpecializedDecodable; use rustc_span::source_map::Span; -use smallvec::SmallVec; -use std::ops::Index; + +pub use rustc::infer::types::canonical::*; mod canonicalizer; @@ -40,265 +37,6 @@ pub mod query_response; mod substitute; -/// A "canonicalized" type `V` is one where all free inference -/// variables have been rewritten to "canonical vars". These are -/// numbered starting from 0 in order of first appearance. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] -#[derive(HashStable, TypeFoldable, Lift)] -pub struct Canonical<'tcx, V> { - pub max_universe: ty::UniverseIndex, - pub variables: CanonicalVarInfos<'tcx>, - pub value: V, -} - -pub type CanonicalVarInfos<'tcx> = &'tcx List; - -impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {} - -/// A set of values corresponding to the canonical variables from some -/// `Canonical`. You can give these values to -/// `canonical_value.substitute` to substitute them into the canonical -/// value at the right places. -/// -/// When you canonicalize a value `V`, you get back one of these -/// vectors with the original values that were replaced by canonical -/// variables. You will need to supply it later to instantiate the -/// canonicalized query response. -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] -#[derive(HashStable, TypeFoldable, Lift)] -pub struct CanonicalVarValues<'tcx> { - pub var_values: IndexVec>, -} - -/// When we canonicalize a value to form a query, we wind up replacing -/// various parts of it with canonical variables. This struct stores -/// those replaced bits to remember for when we process the query -/// result. -#[derive(Clone, Debug)] -pub struct OriginalQueryValues<'tcx> { - /// Map from the universes that appear in the query to the - /// universes in the caller context. For the time being, we only - /// ever put ROOT values into the query, so this map is very - /// simple. - pub universe_map: SmallVec<[ty::UniverseIndex; 4]>, - - /// This is equivalent to `CanonicalVarValues`, but using a - /// `SmallVec` yields a significant performance win. - pub var_values: SmallVec<[GenericArg<'tcx>; 8]>, -} - -impl Default for OriginalQueryValues<'tcx> { - fn default() -> Self { - let mut universe_map = SmallVec::default(); - universe_map.push(ty::UniverseIndex::ROOT); - - Self { universe_map, var_values: SmallVec::default() } - } -} - -/// Information about a canonical variable that is included with the -/// canonical value. This is sufficient information for code to create -/// a copy of the canonical value in some other inference context, -/// with fresh inference variables replacing the canonical values. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] -pub struct CanonicalVarInfo { - pub kind: CanonicalVarKind, -} - -impl CanonicalVarInfo { - pub fn universe(&self) -> ty::UniverseIndex { - self.kind.universe() - } - - pub fn is_existential(&self) -> bool { - match self.kind { - CanonicalVarKind::Ty(_) => true, - CanonicalVarKind::PlaceholderTy(_) => false, - CanonicalVarKind::Region(_) => true, - CanonicalVarKind::PlaceholderRegion(..) => false, - CanonicalVarKind::Const(_) => true, - CanonicalVarKind::PlaceholderConst(_) => false, - } - } -} - -/// Describes the "kind" of the canonical variable. This is a "kind" -/// in the type-theory sense of the term -- i.e., a "meta" type system -/// that analyzes type-like values. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] -pub enum CanonicalVarKind { - /// Some kind of type inference variable. - Ty(CanonicalTyVarKind), - - /// A "placeholder" that represents "any type". - PlaceholderTy(ty::PlaceholderType), - - /// Region variable `'?R`. - Region(ty::UniverseIndex), - - /// A "placeholder" that represents "any region". Created when you - /// are solving a goal like `for<'a> T: Foo<'a>` to represent the - /// bound region `'a`. - PlaceholderRegion(ty::PlaceholderRegion), - - /// Some kind of const inference variable. - Const(ty::UniverseIndex), - - /// A "placeholder" that represents "any const". - PlaceholderConst(ty::PlaceholderConst), -} - -impl CanonicalVarKind { - pub fn universe(self) -> ty::UniverseIndex { - match self { - CanonicalVarKind::Ty(kind) => match kind { - CanonicalTyVarKind::General(ui) => ui, - CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT, - }, - - CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe, - CanonicalVarKind::Region(ui) => ui, - CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe, - CanonicalVarKind::Const(ui) => ui, - CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe, - } - } -} - -/// Rust actually has more than one category of type variables; -/// notably, the type variables we create for literals (e.g., 22 or -/// 22.) can only be instantiated with integral/float types (e.g., -/// usize or f32). In order to faithfully reproduce a type, we need to -/// know what set of types a given type variable can be unified with. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] -pub enum CanonicalTyVarKind { - /// General type variable `?T` that can be unified with arbitrary types. - General(ty::UniverseIndex), - - /// Integral type variable `?I` (that can only be unified with integral types). - Int, - - /// Floating-point type variable `?F` (that can only be unified with float types). - Float, -} - -/// After we execute a query with a canonicalized key, we get back a -/// `Canonical>`. You can use -/// `instantiate_query_result` to access the data in this result. -#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] -pub struct QueryResponse<'tcx, R> { - pub var_values: CanonicalVarValues<'tcx>, - pub region_constraints: QueryRegionConstraints<'tcx>, - pub certainty: Certainty, - pub value: R, -} - -#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] -pub struct QueryRegionConstraints<'tcx> { - pub outlives: Vec>, - pub member_constraints: Vec>, -} - -impl QueryRegionConstraints<'_> { - /// Represents an empty (trivially true) set of region - /// constraints. - pub fn is_empty(&self) -> bool { - self.outlives.is_empty() && self.member_constraints.is_empty() - } -} - -pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>; - -pub type CanonicalizedQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>; - -/// Indicates whether or not we were able to prove the query to be -/// true. -#[derive(Copy, Clone, Debug, HashStable)] -pub enum Certainty { - /// The query is known to be true, presuming that you apply the - /// given `var_values` and the region-constraints are satisfied. - Proven, - - /// The query is not known to be true, but also not known to be - /// false. The `var_values` represent *either* values that must - /// hold in order for the query to be true, or helpful tips that - /// *might* make it true. Currently rustc's trait solver cannot - /// distinguish the two (e.g., due to our preference for where - /// clauses over impls). - /// - /// After some unifiations and things have been done, it makes - /// sense to try and prove again -- of course, at that point, the - /// canonical form will be different, making this a distinct - /// query. - Ambiguous, -} - -impl Certainty { - pub fn is_proven(&self) -> bool { - match self { - Certainty::Proven => true, - Certainty::Ambiguous => false, - } - } - - pub fn is_ambiguous(&self) -> bool { - !self.is_proven() - } -} - -impl<'tcx, R> QueryResponse<'tcx, R> { - pub fn is_proven(&self) -> bool { - self.certainty.is_proven() - } - - pub fn is_ambiguous(&self) -> bool { - !self.is_proven() - } -} - -impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> { - pub fn is_proven(&self) -> bool { - self.value.is_proven() - } - - pub fn is_ambiguous(&self) -> bool { - !self.is_proven() - } -} - -impl<'tcx, V> Canonical<'tcx, V> { - /// Allows you to map the `value` of a canonical while keeping the - /// same set of bound variables. - /// - /// **WARNING:** This function is very easy to mis-use, hence the - /// name! In particular, the new value `W` must use all **the - /// same type/region variables** in **precisely the same order** - /// as the original! (The ordering is defined by the - /// `TypeFoldable` implementation of the type in question.) - /// - /// An example of a **correct** use of this: - /// - /// ```rust,ignore (not real code) - /// let a: Canonical<'_, T> = ...; - /// let b: Canonical<'_, (T,)> = a.unchecked_map(|v| (v, )); - /// ``` - /// - /// An example of an **incorrect** use of this: - /// - /// ```rust,ignore (not real code) - /// let a: Canonical<'tcx, T> = ...; - /// let ty: Ty<'tcx> = ...; - /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty)); - /// ``` - pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W> { - let Canonical { max_universe, variables, value } = self; - Canonical { max_universe, variables, value: map_op(value) } - } -} - -pub type QueryOutlivesConstraint<'tcx> = - ty::Binder, Region<'tcx>>>; - impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Creates a substitution S for the canonical value with fresh /// inference variables and applies it to the canonical value. @@ -424,70 +162,3 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { } } } - -CloneTypeFoldableAndLiftImpls! { - crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalVarInfo, - crate::infer::canonical::CanonicalVarKind, -} - -CloneTypeFoldableImpls! { - for <'tcx> { - crate::infer::canonical::CanonicalVarInfos<'tcx>, - } -} - -impl<'tcx> CanonicalVarValues<'tcx> { - pub fn len(&self) -> usize { - self.var_values.len() - } - - /// Makes an identity substitution from this one: each bound var - /// is matched to the same bound var, preserving the original kinds. - /// For example, if we have: - /// `self.var_values == [Type(u32), Lifetime('a), Type(u64)]` - /// we'll return a substitution `subst` with: - /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`. - pub fn make_identity(&self, tcx: TyCtxt<'tcx>) -> Self { - use crate::ty::subst::GenericArgKind; - - CanonicalVarValues { - var_values: self - .var_values - .iter() - .zip(0..) - .map(|(kind, i)| match kind.unpack() { - GenericArgKind::Type(..) => { - tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() - } - GenericArgKind::Lifetime(..) => tcx - .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))) - .into(), - GenericArgKind::Const(ct) => tcx - .mk_const(ty::Const { - ty: ct.ty, - val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), - }) - .into(), - }) - .collect(), - } - } -} - -impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> { - type Item = GenericArg<'tcx>; - type IntoIter = ::std::iter::Cloned<::std::slice::Iter<'a, GenericArg<'tcx>>>; - - fn into_iter(self) -> Self::IntoIter { - self.var_values.iter().cloned() - } -} - -impl<'tcx> Index for CanonicalVarValues<'tcx> { - type Output = GenericArg<'tcx>; - - fn index(&self, value: BoundVar) -> &GenericArg<'tcx> { - &self.var_values[value] - } -} diff --git a/src/librustc/infer/types/canonical.rs b/src/librustc/infer/types/canonical.rs new file mode 100644 index 0000000000000..133cf1b592862 --- /dev/null +++ b/src/librustc/infer/types/canonical.rs @@ -0,0 +1,357 @@ +//! **Canonicalization** is the key to constructing a query in the +//! middle of type inference. Ordinarily, it is not possible to store +//! types from type inference in query keys, because they contain +//! references to inference variables whose lifetimes are too short +//! and so forth. Canonicalizing a value T1 using `canonicalize_query` +//! produces two things: +//! +//! - a value T2 where each unbound inference variable has been +//! replaced with a **canonical variable**; +//! - a map M (of type `CanonicalVarValues`) from those canonical +//! variables back to the original. +//! +//! We can then do queries using T2. These will give back constraints +//! on the canonical variables which can be translated, using the map +//! M, into constraints in our source context. This process of +//! translating the results back is done by the +//! `instantiate_query_result` method. +//! +//! For a more detailed look at what is happening here, check +//! out the [chapter in the rustc guide][c]. +//! +//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html + +use crate::infer::region_constraints::MemberConstraint; +use crate::ty::subst::GenericArg; +use crate::ty::{self, BoundVar, List, Region, TyCtxt}; +use rustc_index::vec::IndexVec; +use rustc_macros::HashStable; +use rustc_serialize::UseSpecializedDecodable; +use smallvec::SmallVec; +use std::ops::Index; + +/// A "canonicalized" type `V` is one where all free inference +/// variables have been rewritten to "canonical vars". These are +/// numbered starting from 0 in order of first appearance. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] +#[derive(HashStable, TypeFoldable, Lift)] +pub struct Canonical<'tcx, V> { + pub max_universe: ty::UniverseIndex, + pub variables: CanonicalVarInfos<'tcx>, + pub value: V, +} + +pub type CanonicalVarInfos<'tcx> = &'tcx List; + +impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {} + +/// A set of values corresponding to the canonical variables from some +/// `Canonical`. You can give these values to +/// `canonical_value.substitute` to substitute them into the canonical +/// value at the right places. +/// +/// When you canonicalize a value `V`, you get back one of these +/// vectors with the original values that were replaced by canonical +/// variables. You will need to supply it later to instantiate the +/// canonicalized query response. +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] +#[derive(HashStable, TypeFoldable, Lift)] +pub struct CanonicalVarValues<'tcx> { + pub var_values: IndexVec>, +} + +/// When we canonicalize a value to form a query, we wind up replacing +/// various parts of it with canonical variables. This struct stores +/// those replaced bits to remember for when we process the query +/// result. +#[derive(Clone, Debug)] +pub struct OriginalQueryValues<'tcx> { + /// Map from the universes that appear in the query to the + /// universes in the caller context. For the time being, we only + /// ever put ROOT values into the query, so this map is very + /// simple. + pub universe_map: SmallVec<[ty::UniverseIndex; 4]>, + + /// This is equivalent to `CanonicalVarValues`, but using a + /// `SmallVec` yields a significant performance win. + pub var_values: SmallVec<[GenericArg<'tcx>; 8]>, +} + +impl Default for OriginalQueryValues<'tcx> { + fn default() -> Self { + let mut universe_map = SmallVec::default(); + universe_map.push(ty::UniverseIndex::ROOT); + + Self { universe_map, var_values: SmallVec::default() } + } +} + +/// Information about a canonical variable that is included with the +/// canonical value. This is sufficient information for code to create +/// a copy of the canonical value in some other inference context, +/// with fresh inference variables replacing the canonical values. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] +pub struct CanonicalVarInfo { + pub kind: CanonicalVarKind, +} + +impl CanonicalVarInfo { + pub fn universe(&self) -> ty::UniverseIndex { + self.kind.universe() + } + + pub fn is_existential(&self) -> bool { + match self.kind { + CanonicalVarKind::Ty(_) => true, + CanonicalVarKind::PlaceholderTy(_) => false, + CanonicalVarKind::Region(_) => true, + CanonicalVarKind::PlaceholderRegion(..) => false, + CanonicalVarKind::Const(_) => true, + CanonicalVarKind::PlaceholderConst(_) => false, + } + } +} + +/// Describes the "kind" of the canonical variable. This is a "kind" +/// in the type-theory sense of the term -- i.e., a "meta" type system +/// that analyzes type-like values. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] +pub enum CanonicalVarKind { + /// Some kind of type inference variable. + Ty(CanonicalTyVarKind), + + /// A "placeholder" that represents "any type". + PlaceholderTy(ty::PlaceholderType), + + /// Region variable `'?R`. + Region(ty::UniverseIndex), + + /// A "placeholder" that represents "any region". Created when you + /// are solving a goal like `for<'a> T: Foo<'a>` to represent the + /// bound region `'a`. + PlaceholderRegion(ty::PlaceholderRegion), + + /// Some kind of const inference variable. + Const(ty::UniverseIndex), + + /// A "placeholder" that represents "any const". + PlaceholderConst(ty::PlaceholderConst), +} + +impl CanonicalVarKind { + pub fn universe(self) -> ty::UniverseIndex { + match self { + CanonicalVarKind::Ty(kind) => match kind { + CanonicalTyVarKind::General(ui) => ui, + CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT, + }, + + CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe, + CanonicalVarKind::Region(ui) => ui, + CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe, + CanonicalVarKind::Const(ui) => ui, + CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe, + } + } +} + +/// Rust actually has more than one category of type variables; +/// notably, the type variables we create for literals (e.g., 22 or +/// 22.) can only be instantiated with integral/float types (e.g., +/// usize or f32). In order to faithfully reproduce a type, we need to +/// know what set of types a given type variable can be unified with. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)] +pub enum CanonicalTyVarKind { + /// General type variable `?T` that can be unified with arbitrary types. + General(ty::UniverseIndex), + + /// Integral type variable `?I` (that can only be unified with integral types). + Int, + + /// Floating-point type variable `?F` (that can only be unified with float types). + Float, +} + +/// After we execute a query with a canonicalized key, we get back a +/// `Canonical>`. You can use +/// `instantiate_query_result` to access the data in this result. +#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] +pub struct QueryResponse<'tcx, R> { + pub var_values: CanonicalVarValues<'tcx>, + pub region_constraints: QueryRegionConstraints<'tcx>, + pub certainty: Certainty, + pub value: R, +} + +#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] +pub struct QueryRegionConstraints<'tcx> { + pub outlives: Vec>, + pub member_constraints: Vec>, +} + +impl QueryRegionConstraints<'_> { + /// Represents an empty (trivially true) set of region + /// constraints. + pub fn is_empty(&self) -> bool { + self.outlives.is_empty() && self.member_constraints.is_empty() + } +} + +pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>; + +pub type CanonicalizedQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>; + +/// Indicates whether or not we were able to prove the query to be +/// true. +#[derive(Copy, Clone, Debug, HashStable)] +pub enum Certainty { + /// The query is known to be true, presuming that you apply the + /// given `var_values` and the region-constraints are satisfied. + Proven, + + /// The query is not known to be true, but also not known to be + /// false. The `var_values` represent *either* values that must + /// hold in order for the query to be true, or helpful tips that + /// *might* make it true. Currently rustc's trait solver cannot + /// distinguish the two (e.g., due to our preference for where + /// clauses over impls). + /// + /// After some unifiations and things have been done, it makes + /// sense to try and prove again -- of course, at that point, the + /// canonical form will be different, making this a distinct + /// query. + Ambiguous, +} + +impl Certainty { + pub fn is_proven(&self) -> bool { + match self { + Certainty::Proven => true, + Certainty::Ambiguous => false, + } + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +impl<'tcx, R> QueryResponse<'tcx, R> { + pub fn is_proven(&self) -> bool { + self.certainty.is_proven() + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> { + pub fn is_proven(&self) -> bool { + self.value.is_proven() + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +impl<'tcx, V> Canonical<'tcx, V> { + /// Allows you to map the `value` of a canonical while keeping the + /// same set of bound variables. + /// + /// **WARNING:** This function is very easy to mis-use, hence the + /// name! In particular, the new value `W` must use all **the + /// same type/region variables** in **precisely the same order** + /// as the original! (The ordering is defined by the + /// `TypeFoldable` implementation of the type in question.) + /// + /// An example of a **correct** use of this: + /// + /// ```rust,ignore (not real code) + /// let a: Canonical<'_, T> = ...; + /// let b: Canonical<'_, (T,)> = a.unchecked_map(|v| (v, )); + /// ``` + /// + /// An example of an **incorrect** use of this: + /// + /// ```rust,ignore (not real code) + /// let a: Canonical<'tcx, T> = ...; + /// let ty: Ty<'tcx> = ...; + /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty)); + /// ``` + pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W> { + let Canonical { max_universe, variables, value } = self; + Canonical { max_universe, variables, value: map_op(value) } + } +} + +pub type QueryOutlivesConstraint<'tcx> = + ty::Binder, Region<'tcx>>>; + +CloneTypeFoldableAndLiftImpls! { + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalVarInfo, + crate::infer::canonical::CanonicalVarKind, +} + +CloneTypeFoldableImpls! { + for <'tcx> { + crate::infer::canonical::CanonicalVarInfos<'tcx>, + } +} + +impl<'tcx> CanonicalVarValues<'tcx> { + pub fn len(&self) -> usize { + self.var_values.len() + } + + /// Makes an identity substitution from this one: each bound var + /// is matched to the same bound var, preserving the original kinds. + /// For example, if we have: + /// `self.var_values == [Type(u32), Lifetime('a), Type(u64)]` + /// we'll return a substitution `subst` with: + /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`. + pub fn make_identity(&self, tcx: TyCtxt<'tcx>) -> Self { + use crate::ty::subst::GenericArgKind; + + CanonicalVarValues { + var_values: self + .var_values + .iter() + .zip(0..) + .map(|(kind, i)| match kind.unpack() { + GenericArgKind::Type(..) => { + tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() + } + GenericArgKind::Lifetime(..) => tcx + .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))) + .into(), + GenericArgKind::Const(ct) => tcx + .mk_const(ty::Const { + ty: ct.ty, + val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), + }) + .into(), + }) + .collect(), + } + } +} + +impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> { + type Item = GenericArg<'tcx>; + type IntoIter = ::std::iter::Cloned<::std::slice::Iter<'a, GenericArg<'tcx>>>; + + fn into_iter(self) -> Self::IntoIter { + self.var_values.iter().cloned() + } +} + +impl<'tcx> Index for CanonicalVarValues<'tcx> { + type Output = GenericArg<'tcx>; + + fn index(&self, value: BoundVar) -> &GenericArg<'tcx> { + &self.var_values[value] + } +} diff --git a/src/librustc/infer/types/mod.rs b/src/librustc/infer/types/mod.rs index f9346b99cde40..534f4cb179c4f 100644 --- a/src/librustc/infer/types/mod.rs +++ b/src/librustc/infer/types/mod.rs @@ -1,3 +1,5 @@ +pub mod canonical; + use crate::ty::Region; use crate::ty::Ty; use rustc_data_structures::sync::Lrc; From b3f13b00f5fadad44efd048c69136d18108e0647 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:39:53 +0100 Subject: [PATCH 0917/1253] Move implementation of UnifyKey to unify_key.rs. --- src/librustc/infer/type_variable.rs | 15 --------------- src/librustc/infer/unify_key.rs | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 8ea1b705d443d..f391a054a2a5d 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -453,18 +453,3 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { } } } - -/// Raw `TyVid` are used as the unification key for `sub_relations`; -/// they carry no values. -impl ut::UnifyKey for ty::TyVid { - type Value = (); - fn index(&self) -> u32 { - self.index - } - fn from_index(i: u32) -> ty::TyVid { - ty::TyVid { index: i } - } - fn tag() -> &'static str { - "TyVid" - } -} diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index c5ec0ba73e49d..d88188538fccb 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -12,6 +12,21 @@ pub trait ToType { fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>; } +/// Raw `TyVid` are used as the unification key for `sub_relations`; +/// they carry no values. +impl UnifyKey for ty::TyVid { + type Value = (); + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> ty::TyVid { + ty::TyVid { index: i } + } + fn tag() -> &'static str { + "TyVid" + } +} + impl UnifyKey for ty::IntVid { type Value = Option; fn index(&self) -> u32 { From c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 5 Feb 2020 16:28:13 +0800 Subject: [PATCH 0918/1253] Reorder declarations of Result::export/unwrap to match Option --- src/libcore/result.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index bc70dbd62eb52..3361ab6c97d80 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -935,8 +935,8 @@ impl Result { /// /// # Panics /// - /// Panics if the value is an [`Err`], with a panic message provided by the - /// [`Err`]'s value. + /// Panics if the value is an [`Err`], with a panic message including the + /// passed message, and the content of the [`Err`]. /// /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err @@ -945,22 +945,17 @@ impl Result { /// /// Basic usage: /// - /// ``` - /// let x: Result = Ok(2); - /// assert_eq!(x.unwrap(), 2); - /// ``` - /// /// ```{.should_panic} /// let x: Result = Err("emergency failure"); - /// x.unwrap(); // panics with `emergency failure` + /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` /// ``` #[inline] #[track_caller] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap(self) -> T { + #[stable(feature = "result_expect", since = "1.4.0")] + pub fn expect(self, msg: &str) -> T { match self { Ok(t) => t, - Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e), + Err(e) => unwrap_failed(msg, &e), } } @@ -968,8 +963,8 @@ impl Result { /// /// # Panics /// - /// Panics if the value is an [`Err`], with a panic message including the - /// passed message, and the content of the [`Err`]. + /// Panics if the value is an [`Err`], with a panic message provided by the + /// [`Err`]'s value. /// /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err @@ -978,17 +973,22 @@ impl Result { /// /// Basic usage: /// + /// ``` + /// let x: Result = Ok(2); + /// assert_eq!(x.unwrap(), 2); + /// ``` + /// /// ```{.should_panic} /// let x: Result = Err("emergency failure"); - /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` + /// x.unwrap(); // panics with `emergency failure` /// ``` #[inline] #[track_caller] - #[stable(feature = "result_expect", since = "1.4.0")] - pub fn expect(self, msg: &str) -> T { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap(self) -> T { match self { Ok(t) => t, - Err(e) => unwrap_failed(msg, &e), + Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e), } } } From db9b578b71190540cfd84f16f5d310d6ce4cb659 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 5 Feb 2020 16:31:12 +0800 Subject: [PATCH 0919/1253] Reorder declarations of Result::expect_err/unwrap_err to match Option --- src/libcore/result.rs | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 3361ab6c97d80..ee28946f0da7a 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -998,30 +998,26 @@ impl Result { /// /// # Panics /// - /// Panics if the value is an [`Ok`], with a custom panic message provided - /// by the [`Ok`]'s value. + /// Panics if the value is an [`Ok`], with a panic message including the + /// passed message, and the content of the [`Ok`]. /// /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err /// - /// /// # Examples /// - /// ```{.should_panic} - /// let x: Result = Ok(2); - /// x.unwrap_err(); // panics with `2` - /// ``` + /// Basic usage: /// - /// ``` - /// let x: Result = Err("emergency failure"); - /// assert_eq!(x.unwrap_err(), "emergency failure"); + /// ```{.should_panic} + /// let x: Result = Ok(10); + /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` /// ``` #[inline] #[track_caller] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_err(self) -> E { + #[stable(feature = "result_expect_err", since = "1.17.0")] + pub fn expect_err(self, msg: &str) -> E { match self { - Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t), + Ok(t) => unwrap_failed(msg, &t), Err(e) => e, } } @@ -1030,26 +1026,30 @@ impl Result { /// /// # Panics /// - /// Panics if the value is an [`Ok`], with a panic message including the - /// passed message, and the content of the [`Ok`]. + /// Panics if the value is an [`Ok`], with a custom panic message provided + /// by the [`Ok`]'s value. /// /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err /// - /// # Examples /// - /// Basic usage: + /// # Examples /// /// ```{.should_panic} - /// let x: Result = Ok(10); - /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` + /// let x: Result = Ok(2); + /// x.unwrap_err(); // panics with `2` + /// ``` + /// + /// ``` + /// let x: Result = Err("emergency failure"); + /// assert_eq!(x.unwrap_err(), "emergency failure"); /// ``` #[inline] #[track_caller] - #[stable(feature = "result_expect_err", since = "1.17.0")] - pub fn expect_err(self, msg: &str) -> E { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_err(self) -> E { match self { - Ok(t) => unwrap_failed(msg, &t), + Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t), Err(e) => e, } } From 28b0ed020a36e94fe233e2a0ef950fd888b16256 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 5 Feb 2020 11:11:34 +0100 Subject: [PATCH 0920/1253] merge item id stable hashing functions --- src/librustc/ich/impls_hir.rs | 21 +-------------------- src/librustc_hir/stable_hash_impls.rs | 10 ++++------ 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 061b82ebb430e..1e5a722c10116 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -47,33 +47,14 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { // want to pick up on a reference changing its target, so we hash the NodeIds // in "DefPath Mode". - fn hash_item_id(&mut self, id: hir::ItemId, hasher: &mut StableHasher) { + fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) { let hcx = self; - let hir::ItemId { id } = id; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { id.hash_stable(hcx, hasher); }) } - fn hash_impl_item_id(&mut self, id: hir::ImplItemId, hasher: &mut StableHasher) { - let hcx = self; - let hir::ImplItemId { hir_id } = id; - - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - hir_id.hash_stable(hcx, hasher); - }) - } - - fn hash_trait_item_id(&mut self, id: hir::TraitItemId, hasher: &mut StableHasher) { - let hcx = self; - let hir::TraitItemId { hir_id } = id; - - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - hir_id.hash_stable(hcx, hasher); - }) - } - fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) { let hcx = self; let hir::Mod { inner: ref inner_span, ref item_ids } = *module; diff --git a/src/librustc_hir/stable_hash_impls.rs b/src/librustc_hir/stable_hash_impls.rs index 696a350ebdd15..94e02d9cd94fe 100644 --- a/src/librustc_hir/stable_hash_impls.rs +++ b/src/librustc_hir/stable_hash_impls.rs @@ -11,9 +11,7 @@ pub trait HashStableContext: syntax::HashStableContext + rustc_target::HashStabl fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher); fn hash_hir_id(&mut self, _: HirId, hasher: &mut StableHasher); fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher); - fn hash_item_id(&mut self, _: ItemId, hasher: &mut StableHasher); - fn hash_impl_item_id(&mut self, _: ImplItemId, hasher: &mut StableHasher); - fn hash_trait_item_id(&mut self, _: TraitItemId, hasher: &mut StableHasher); + fn hash_reference_to_item(&mut self, _: HirId, hasher: &mut StableHasher); fn hash_hir_mod(&mut self, _: &Mod<'_>, hasher: &mut StableHasher); fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher); fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher); @@ -40,19 +38,19 @@ impl HashStable for BodyId { impl HashStable for ItemId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - hcx.hash_item_id(*self, hasher) + hcx.hash_reference_to_item(self.id, hasher) } } impl HashStable for ImplItemId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - hcx.hash_impl_item_id(*self, hasher) + hcx.hash_reference_to_item(self.hir_id, hasher) } } impl HashStable for TraitItemId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - hcx.hash_trait_item_id(*self, hasher) + hcx.hash_reference_to_item(self.hir_id, hasher) } } From e8b72f44b0064d0e591f078f6b7f2cf3aa28f540 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 5 Feb 2020 11:29:07 +0100 Subject: [PATCH 0921/1253] move item reference comment --- src/librustc/ich/impls_hir.rs | 7 ------- src/librustc_hir/stable_hash_impls.rs | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 1e5a722c10116..0155861549773 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -40,13 +40,6 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { } } - // The following implementations of HashStable for `ItemId`, `TraitItemId`, and - // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within - // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al - // are used when another item in the HIR is *referenced* and we certainly - // want to pick up on a reference changing its target, so we hash the NodeIds - // in "DefPath Mode". - fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) { let hcx = self; diff --git a/src/librustc_hir/stable_hash_impls.rs b/src/librustc_hir/stable_hash_impls.rs index 94e02d9cd94fe..294074cd3e5a4 100644 --- a/src/librustc_hir/stable_hash_impls.rs +++ b/src/librustc_hir/stable_hash_impls.rs @@ -36,6 +36,13 @@ impl HashStable for BodyId { } } +// The following implementations of HashStable for `ItemId`, `TraitItemId`, and +// `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within +// the HIR, since they just signify a HIR nodes own path. But `ItemId` et al +// are used when another item in the HIR is *referenced* and we certainly +// want to pick up on a reference changing its target, so we hash the NodeIds +// in "DefPath Mode". + impl HashStable for ItemId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { hcx.hash_reference_to_item(self.id, hasher) From 9a4eac3944e2e2668b4aea0b5afd3d83b88e992e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Feb 2020 12:27:45 +0100 Subject: [PATCH 0922/1253] ast_validation: fix visiting bug. --- src/librustc_ast_passes/ast_validation.rs | 49 +++++++++++-------- .../issue-68788-in-trait-item-propagation.rs | 21 ++++++++ 2 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/parser/issue-68788-in-trait-item-propagation.rs diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 53911d147802d..79ed7f234f72e 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -81,6 +81,12 @@ struct AstValidator<'a> { } impl<'a> AstValidator<'a> { + fn with_in_trait_impl(&mut self, is_in: bool, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.in_trait_impl, is_in); + f(self); + self.in_trait_impl = old; + } + fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.is_impl_trait_banned, true); f(self); @@ -737,28 +743,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ref self_ty, items: _, } => { - let old_in_trait_impl = mem::replace(&mut self.in_trait_impl, true); - - self.invalid_visibility(&item.vis, None); - if let TyKind::Err = self_ty.kind { - self.err_handler() - .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") - .help("use `auto trait Trait {}` instead") + self.with_in_trait_impl(true, |this| { + this.invalid_visibility(&item.vis, None); + if let TyKind::Err = self_ty.kind { + this.err_handler() + .struct_span_err( + item.span, + "`impl Trait for .. {}` is an obsolete syntax", + ) + .help("use `auto trait Trait {}` instead") + .emit(); + } + if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { + struct_span_err!( + this.session, + item.span, + E0198, + "negative impls cannot be unsafe" + ) .emit(); - } - if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { - struct_span_err!( - self.session, - item.span, - E0198, - "negative impls cannot be unsafe" - ) - .emit(); - } - - visit::walk_item(self, item); + } - self.in_trait_impl = old_in_trait_impl; + visit::walk_item(this, item); + }); return; // Avoid visiting again. } ItemKind::Impl { @@ -1142,7 +1149,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } - visit::walk_assoc_item(self, item, ctxt); + self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt)); } } diff --git a/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs b/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs new file mode 100644 index 0000000000000..7c3dd1d5a98c7 --- /dev/null +++ b/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs @@ -0,0 +1,21 @@ +// Make sure we don't propagate restrictions on trait impl items to items inside them. + +// check-pass +// edition:2018 + +fn main() {} + +trait X { + fn foo(); +} + +impl X for () { + fn foo() { + struct S; + impl S { + pub const X: u8 = 0; + pub const fn bar() {} + async fn qux() {} + } + } +} From 82684ad30a0929afba9463b89232730a9c6dadf4 Mon Sep 17 00:00:00 2001 From: Josh White Date: Wed, 5 Feb 2020 06:28:31 -0500 Subject: [PATCH 0923/1253] Added long error description & modifed error_codes.rs --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0637.md | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/librustc_error_codes/error_codes/E0637.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index c3d9ed088981d..ba43b29538d50 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -353,6 +353,7 @@ E0631: include_str!("./error_codes/E0631.md"), E0633: include_str!("./error_codes/E0633.md"), E0635: include_str!("./error_codes/E0635.md"), E0636: include_str!("./error_codes/E0636.md"), +E0637: include_str!("./error_codes/E0637.md"), E0638: include_str!("./error_codes/E0638.md"), E0639: include_str!("./error_codes/E0639.md"), E0641: include_str!("./error_codes/E0641.md"), @@ -584,7 +585,6 @@ E0746: include_str!("./error_codes/E0746.md"), E0632, // cannot provide explicit generic arguments when `impl Trait` is // used in argument position E0634, // type has conflicting packed representaton hints - E0637, // "'_" is not a valid lifetime bound E0640, // infer outlives requirements // E0645, // trait aliases not finished E0657, // `impl Trait` can only capture lifetimes bound at the fn level diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md new file mode 100644 index 0000000000000..4f139b0ec49d6 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -0,0 +1,22 @@ +The underscore `_` character has been used as the identifier for a lifetime. + +Erroneous code example: +``` +fn some_function<'_>(x: &'_ str, y: &'_ str) -> &'_ str { + //Some code +} +``` + +Lifetimes are named with 'ident, where ident is the name of the +lifetime or loop. The `_` character, which represents the ignore pattern, +cannot be used because it is a reserved lifetime name. +To fix this, use a single lowercase letter as the +lifetime identifier, such as `'a`. For more information, see [The Rust Book](https://doc.rust-lang.org/stable/book/appendix-02-operators.html#non-operator-symbols). + +Corrected code example: +``` +fn some_function<'a>(x: &'a str, y: &'a str) -> &'a str { + //Some code +} +``` + From 9444975e96e417beaf9a261292f02c29f0eb7b2b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:42:04 +0100 Subject: [PATCH 0924/1253] Split traits::structural_impls in two. --- src/librustc/traits/structural_impls.rs | 704 +---------------- src/librustc/traits/types/mod.rs | 1 + src/librustc/traits/types/structural_impls.rs | 712 ++++++++++++++++++ 3 files changed, 714 insertions(+), 703 deletions(-) create mode 100644 src/librustc/traits/types/structural_impls.rs diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 1db83c5bafac9..80731c7b1892f 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -1,13 +1,9 @@ use crate::traits; use crate::traits::project::Normalized; +use crate::ty; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::{self, Lift, Ty, TyCtxt}; -use rustc_span::symbol::Symbol; -use smallvec::SmallVec; -use std::collections::{BTreeMap, BTreeSet}; use std::fmt; -use std::rc::Rc; // Structural impls for the structs in `traits`. @@ -31,102 +27,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { } } -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - super::VtableImpl(ref v) => write!(f, "{:?}", v), - - super::VtableAutoImpl(ref t) => write!(f, "{:?}", t), - - super::VtableClosure(ref d) => write!(f, "{:?}", d), - - super::VtableGenerator(ref d) => write!(f, "{:?}", d), - - super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d), - - super::VtableObject(ref d) => write!(f, "{:?}", d), - - super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n), - - super::VtableBuiltin(ref d) => write!(f, "{:?}", d), - - super::VtableTraitAlias(ref d) => write!(f, "{:?}", d), - } - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableImplData(impl_def_id={:?}, substs={:?}, nested={:?})", - self.impl_def_id, self.substs, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})", - self.generator_def_id, self.substs, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableClosureData(closure_def_id={:?}, substs={:?}, nested={:?})", - self.closure_def_id, self.substs, self.nested - ) - } -} - -impl fmt::Debug for traits::VtableBuiltinData { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "VtableBuiltinData(nested={:?})", self.nested) - } -} - -impl fmt::Debug for traits::VtableAutoImplData { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableAutoImplData(trait_def_id={:?}, nested={:?})", - self.trait_def_id, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableObjectData(upcast={:?}, vtable_base={}, nested={:?})", - self.upcast_trait_ref, self.vtable_base, self.nested - ) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested) - } -} - -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})", - self.alias_def_id, self.substs, self.nested - ) - } -} - impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "FulfillmentError({:?},{:?})", self.obligation, self.code) @@ -152,531 +52,6 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { } } -impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::WhereClause::*; - - // Bypass `ty::print` because it does not print out anonymous regions. - // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`. - fn write_region_name<'tcx>( - r: ty::Region<'tcx>, - fmt: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - match r { - ty::ReLateBound(index, br) => match br { - ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name), - ty::BoundRegion::BrAnon(var) => { - if *index == ty::INNERMOST { - write!(fmt, "'^{}", var) - } else { - write!(fmt, "'^{}_{}", index.index(), var) - } - } - _ => write!(fmt, "'_"), - }, - - _ => write!(fmt, "{}", r), - } - } - - match self { - Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref), - ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection), - RegionOutlives(predicate) => { - write!(fmt, "RegionOutlives({}: ", predicate.0)?; - write_region_name(predicate.1, fmt)?; - write!(fmt, ")") - } - TypeOutlives(predicate) => { - write!(fmt, "TypeOutlives({}: ", predicate.0)?; - write_region_name(predicate.1, fmt)?; - write!(fmt, ")") - } - } - } -} - -impl<'tcx> fmt::Display for traits::WellFormed<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::WellFormed::*; - - match self { - Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref), - Ty(ty) => write!(fmt, "WellFormed({})", ty), - } - } -} - -impl<'tcx> fmt::Display for traits::FromEnv<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::FromEnv::*; - - match self { - Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref), - Ty(ty) => write!(fmt, "FromEnv({})", ty), - } - } -} - -impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::DomainGoal::*; - - match self { - Holds(wc) => write!(fmt, "{}", wc), - WellFormed(wf) => write!(fmt, "{}", wf), - FromEnv(from_env) => write!(fmt, "{}", from_env), - Normalize(projection) => { - write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty) - } - } - } -} - -impl fmt::Display for traits::QuantifierKind { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::QuantifierKind::*; - - match self { - Universal => write!(fmt, "forall"), - Existential => write!(fmt, "exists"), - } - } -} - -/// Collect names for regions / types bound by a quantified goal / clause. -/// This collector does not try to do anything clever like in `ty::print`, it's just used -/// for debug output in tests anyway. -struct BoundNamesCollector { - // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. - regions: BTreeSet, - - // Sort by `BoundVar` index, so usually this should be equivalent to the order given - // by the list of type parameters. - types: BTreeMap, - - binder_index: ty::DebruijnIndex, -} - -impl BoundNamesCollector { - fn new() -> Self { - BoundNamesCollector { - regions: BTreeSet::new(), - types: BTreeMap::new(), - binder_index: ty::INNERMOST, - } - } - - fn is_empty(&self) -> bool { - self.regions.is_empty() && self.types.is_empty() - } - - fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut start = true; - for r in &self.regions { - if !start { - write!(fmt, ", ")?; - } - start = false; - write!(fmt, "{}", r)?; - } - for (_, t) in &self.types { - if !start { - write!(fmt, ", ")?; - } - start = false; - write!(fmt, "{}", t)?; - } - Ok(()) - } -} - -impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { - fn visit_binder>(&mut self, t: &ty::Binder) -> bool { - self.binder_index.shift_in(1); - let result = t.super_visit_with(self); - self.binder_index.shift_out(1); - result - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - match t.kind { - ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { - self.types.insert( - bound_ty.var.as_u32(), - match bound_ty.kind { - ty::BoundTyKind::Param(name) => name, - ty::BoundTyKind::Anon => { - Symbol::intern(&format!("^{}", bound_ty.var.as_u32())) - } - }, - ); - } - - _ => (), - }; - - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - match r { - ty::ReLateBound(index, br) if *index == self.binder_index => match br { - ty::BoundRegion::BrNamed(_, name) => { - self.regions.insert(*name); - } - - ty::BoundRegion::BrAnon(var) => { - self.regions.insert(Symbol::intern(&format!("'^{}", var))); - } - - _ => (), - }, - - _ => (), - }; - - r.super_visit_with(self) - } -} - -impl<'tcx> fmt::Display for traits::Goal<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::GoalKind::*; - - match self { - Implies(hypotheses, goal) => { - write!(fmt, "if (")?; - for (index, hyp) in hypotheses.iter().enumerate() { - if index > 0 { - write!(fmt, ", ")?; - } - write!(fmt, "{}", hyp)?; - } - write!(fmt, ") {{ {} }}", goal) - } - And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2), - Not(goal) => write!(fmt, "not {{ {} }}", goal), - DomainGoal(goal) => write!(fmt, "{}", goal), - Quantified(qkind, goal) => { - let mut collector = BoundNamesCollector::new(); - goal.skip_binder().visit_with(&mut collector); - - if !collector.is_empty() { - write!(fmt, "{}<", qkind)?; - collector.write_names(fmt)?; - write!(fmt, "> {{ ")?; - } - - write!(fmt, "{}", goal.skip_binder())?; - - if !collector.is_empty() { - write!(fmt, " }}")?; - } - - Ok(()) - } - Subtype(a, b) => write!(fmt, "{} <: {}", a, b), - CannotProve => write!(fmt, "CannotProve"), - } - } -} - -impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let traits::ProgramClause { goal, hypotheses, .. } = self; - write!(fmt, "{}", goal)?; - if !hypotheses.is_empty() { - write!(fmt, " :- ")?; - for (index, condition) in hypotheses.iter().enumerate() { - if index > 0 { - write!(fmt, ", ")?; - } - write!(fmt, "{}", condition)?; - } - } - write!(fmt, ".") - } -} - -impl<'tcx> fmt::Display for traits::Clause<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use crate::traits::Clause::*; - - match self { - Implies(clause) => write!(fmt, "{}", clause), - ForAll(clause) => { - let mut collector = BoundNamesCollector::new(); - clause.skip_binder().visit_with(&mut collector); - - if !collector.is_empty() { - write!(fmt, "forall<")?; - collector.write_names(fmt)?; - write!(fmt, "> {{ ")?; - } - - write!(fmt, "{}", clause.skip_binder())?; - - if !collector.is_empty() { - write!(fmt, " }}")?; - } - - Ok(()) - } - } - } -} - -/////////////////////////////////////////////////////////////////////////// -// Lift implementations - -impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> { - type Lifted = traits::SelectionError<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - match *self { - super::Unimplemented => Some(super::Unimplemented), - super::OutputTypeParameterMismatch(a, b, ref err) => { - tcx.lift(&(a, b)).and_then(|(a, b)| { - tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err)) - }) - } - super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)), - super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)), - super::Overflow => Some(super::Overflow), - } - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { - type Lifted = traits::ObligationCauseCode<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - match *self { - super::ReturnNoExpression => Some(super::ReturnNoExpression), - super::MiscObligation => Some(super::MiscObligation), - super::SliceOrArrayElem => Some(super::SliceOrArrayElem), - super::TupleElem => Some(super::TupleElem), - super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf), - super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)), - super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)), - super::ReferenceOutlivesReferent(ty) => { - tcx.lift(&ty).map(super::ReferenceOutlivesReferent) - } - super::ObjectTypeBound(ty, r) => tcx - .lift(&ty) - .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))), - super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation), - super::Coercion { source, target } => { - Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? }) - } - super::AssignmentLhsSized => Some(super::AssignmentLhsSized), - super::TupleInitializerSized => Some(super::TupleInitializerSized), - super::StructInitializerSized => Some(super::StructInitializerSized), - super::VariableType(id) => Some(super::VariableType(id)), - super::ReturnValue(id) => Some(super::ReturnValue(id)), - super::ReturnType => Some(super::ReturnType), - super::SizedArgumentType => Some(super::SizedArgumentType), - super::SizedReturnType => Some(super::SizedReturnType), - super::SizedYieldType => Some(super::SizedYieldType), - super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)), - super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }), - super::ConstSized => Some(super::ConstSized), - super::ConstPatternStructural => Some(super::ConstPatternStructural), - super::SharedStatic => Some(super::SharedStatic), - super::BuiltinDerivedObligation(ref cause) => { - tcx.lift(cause).map(super::BuiltinDerivedObligation) - } - super::ImplDerivedObligation(ref cause) => { - tcx.lift(cause).map(super::ImplDerivedObligation) - } - super::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } => Some(super::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - }), - super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => { - Some(super::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - }) - } - super::ExprAssignable => Some(super::ExprAssignable), - super::MatchExpressionArm(box super::MatchExpressionArmCause { - arm_span, - source, - ref prior_arms, - last_ty, - scrut_hir_id, - }) => tcx.lift(&last_ty).map(|last_ty| { - super::MatchExpressionArm(box super::MatchExpressionArmCause { - arm_span, - source, - prior_arms: prior_arms.clone(), - last_ty, - scrut_hir_id, - }) - }), - super::Pattern { span, root_ty, origin_expr } => { - tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr }) - } - super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { - Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) - } - super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse), - super::MainFunctionType => Some(super::MainFunctionType), - super::StartFunctionType => Some(super::StartFunctionType), - super::IntrinsicType => Some(super::IntrinsicType), - super::MethodReceiver => Some(super::MethodReceiver), - super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)), - super::TrivialBound => Some(super::TrivialBound), - super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())), - } - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { - type Lifted = traits::DerivedObligationCause<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| { - tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause { - parent_trait_ref: trait_ref, - parent_code: Rc::new(code), - }) - }) - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> { - type Lifted = traits::ObligationCause<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.code).map(|code| traits::ObligationCause { - span: self.span, - body_id: self.body_id, - code, - }) - } -} - -// For codegen only. -impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { - type Lifted = traits::Vtable<'tcx, ()>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - match self.clone() { - traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => { - tcx.lift(&substs).map(|substs| { - traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) - }) - } - traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)), - traits::VtableGenerator(traits::VtableGeneratorData { - generator_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::VtableGenerator(traits::VtableGeneratorData { - generator_def_id: generator_def_id, - substs: substs, - nested: nested, - }) - }), - traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => { - tcx.lift(&substs).map(|substs| { - traits::VtableClosure(traits::VtableClosureData { - closure_def_id, - substs, - nested, - }) - }) - } - traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => { - tcx.lift(&fn_ty).map(|fn_ty| { - traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) - }) - } - traits::VtableParam(n) => Some(traits::VtableParam(n)), - traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)), - traits::VtableObject(traits::VtableObjectData { - upcast_trait_ref, - vtable_base, - nested, - }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| { - traits::VtableObject(traits::VtableObjectData { - upcast_trait_ref: trait_ref, - vtable_base, - nested, - }) - }), - traits::VtableTraitAlias(traits::VtableTraitAliasData { - alias_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::VtableTraitAlias(traits::VtableTraitAliasData { - alias_def_id, - substs, - nested, - }) - }), - } - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> { - type Lifted = traits::Environment<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses }) - } -} - -impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> { - type Lifted = traits::InEnvironment<'tcx, G::Lifted>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.environment).and_then(|environment| { - tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal }) - }) - } -} - -impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause -where - C: chalk_engine::context::Context + Clone, - C: traits::ChalkContextLift<'tcx>, -{ - type Lifted = C::LiftedExClause; - - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - ::lift_ex_clause_to_tcx(self, tcx) - } -} - -impl<'tcx, C> Lift<'tcx> for chalk_engine::DelayedLiteral -where - C: chalk_engine::context::Context + Clone, - C: traits::ChalkContextLift<'tcx>, -{ - type Lifted = C::LiftedDelayedLiteral; - - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - ::lift_delayed_literal_to_tcx(self, tcx) - } -} - -impl<'tcx, C> Lift<'tcx> for chalk_engine::Literal -where - C: chalk_engine::context::Context + Clone, - C: traits::ChalkContextLift<'tcx>, -{ - type Lifted = C::LiftedLiteral; - - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - ::lift_literal_to_tcx(self, tcx) - } -} - /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. @@ -694,80 +69,3 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx self.predicate.visit_with(visitor) } } - -CloneTypeFoldableAndLiftImpls! { - traits::QuantifierKind, -} - -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); - folder.tcx().intern_goals(&v) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.iter().any(|t| t.visit_with(visitor)) - } -} - -impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { - fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = (**self).fold_with(folder); - folder.tcx().mk_goal(v) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - (**self).visit_with(visitor) - } -} - -CloneTypeFoldableAndLiftImpls! { - traits::ProgramClauseCategory, -} - -impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> { - fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); - folder.tcx().intern_clauses(&v) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.iter().any(|t| t.visit_with(visitor)) - } -} - -impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause -where - C: traits::ExClauseFold<'tcx>, - C::Substitution: Clone, - C::RegionConstraint: Clone, -{ - fn super_fold_with>(&self, folder: &mut F) -> Self { - ::fold_ex_clause_with(self, folder) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - ::visit_ex_clause_with(self, visitor) - } -} - -EnumTypeFoldableImpl! { - impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::DelayedLiteral { - (chalk_engine::DelayedLiteral::CannotProve)(a), - (chalk_engine::DelayedLiteral::Negative)(a), - (chalk_engine::DelayedLiteral::Positive)(a, b), - } where - C: chalk_engine::context::Context> + Clone, -} - -EnumTypeFoldableImpl! { - impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::Literal { - (chalk_engine::Literal::Negative)(a), - (chalk_engine::Literal::Positive)(a), - } where - C: chalk_engine::context::Context> + Clone, -} - -CloneTypeFoldableAndLiftImpls! { - chalk_engine::TableIndex, -} diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs index c795248802672..b85a9d0193c8a 100644 --- a/src/librustc/traits/types/mod.rs +++ b/src/librustc/traits/types/mod.rs @@ -4,6 +4,7 @@ pub mod query; pub mod select; +mod structural_impls; use crate::mir::interpret::ErrorHandled; use crate::ty::fold::{TypeFolder, TypeVisitor}; diff --git a/src/librustc/traits/types/structural_impls.rs b/src/librustc/traits/types/structural_impls.rs new file mode 100644 index 0000000000000..48ed29f2bb338 --- /dev/null +++ b/src/librustc/traits/types/structural_impls.rs @@ -0,0 +1,712 @@ +use crate::traits; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::{self, Lift, Ty, TyCtxt}; +use rustc_span::symbol::Symbol; +use smallvec::SmallVec; + +use std::collections::{BTreeMap, BTreeSet}; +use std::fmt; +use std::rc::Rc; + +// Structural impls for the structs in `traits`. + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + super::VtableImpl(ref v) => write!(f, "{:?}", v), + + super::VtableAutoImpl(ref t) => write!(f, "{:?}", t), + + super::VtableClosure(ref d) => write!(f, "{:?}", d), + + super::VtableGenerator(ref d) => write!(f, "{:?}", d), + + super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d), + + super::VtableObject(ref d) => write!(f, "{:?}", d), + + super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n), + + super::VtableBuiltin(ref d) => write!(f, "{:?}", d), + + super::VtableTraitAlias(ref d) => write!(f, "{:?}", d), + } + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableImplData(impl_def_id={:?}, substs={:?}, nested={:?})", + self.impl_def_id, self.substs, self.nested + ) + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})", + self.generator_def_id, self.substs, self.nested + ) + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableClosureData(closure_def_id={:?}, substs={:?}, nested={:?})", + self.closure_def_id, self.substs, self.nested + ) + } +} + +impl fmt::Debug for traits::VtableBuiltinData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "VtableBuiltinData(nested={:?})", self.nested) + } +} + +impl fmt::Debug for traits::VtableAutoImplData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableAutoImplData(trait_def_id={:?}, nested={:?})", + self.trait_def_id, self.nested + ) + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableObjectData(upcast={:?}, vtable_base={}, nested={:?})", + self.upcast_trait_ref, self.vtable_base, self.nested + ) + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested) + } +} + +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "VtableTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})", + self.alias_def_id, self.substs, self.nested + ) + } +} + +impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::WhereClause::*; + + // Bypass `ty::print` because it does not print out anonymous regions. + // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`. + fn write_region_name<'tcx>( + r: ty::Region<'tcx>, + fmt: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + match r { + ty::ReLateBound(index, br) => match br { + ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name), + ty::BoundRegion::BrAnon(var) => { + if *index == ty::INNERMOST { + write!(fmt, "'^{}", var) + } else { + write!(fmt, "'^{}_{}", index.index(), var) + } + } + _ => write!(fmt, "'_"), + }, + + _ => write!(fmt, "{}", r), + } + } + + match self { + Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref), + ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection), + RegionOutlives(predicate) => { + write!(fmt, "RegionOutlives({}: ", predicate.0)?; + write_region_name(predicate.1, fmt)?; + write!(fmt, ")") + } + TypeOutlives(predicate) => { + write!(fmt, "TypeOutlives({}: ", predicate.0)?; + write_region_name(predicate.1, fmt)?; + write!(fmt, ")") + } + } + } +} + +impl<'tcx> fmt::Display for traits::WellFormed<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::WellFormed::*; + + match self { + Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref), + Ty(ty) => write!(fmt, "WellFormed({})", ty), + } + } +} + +impl<'tcx> fmt::Display for traits::FromEnv<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::FromEnv::*; + + match self { + Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref), + Ty(ty) => write!(fmt, "FromEnv({})", ty), + } + } +} + +impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::DomainGoal::*; + + match self { + Holds(wc) => write!(fmt, "{}", wc), + WellFormed(wf) => write!(fmt, "{}", wf), + FromEnv(from_env) => write!(fmt, "{}", from_env), + Normalize(projection) => { + write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty) + } + } + } +} + +impl fmt::Display for traits::QuantifierKind { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::QuantifierKind::*; + + match self { + Universal => write!(fmt, "forall"), + Existential => write!(fmt, "exists"), + } + } +} + +/// Collect names for regions / types bound by a quantified goal / clause. +/// This collector does not try to do anything clever like in `ty::print`, it's just used +/// for debug output in tests anyway. +struct BoundNamesCollector { + // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. + regions: BTreeSet, + + // Sort by `BoundVar` index, so usually this should be equivalent to the order given + // by the list of type parameters. + types: BTreeMap, + + binder_index: ty::DebruijnIndex, +} + +impl BoundNamesCollector { + fn new() -> Self { + BoundNamesCollector { + regions: BTreeSet::new(), + types: BTreeMap::new(), + binder_index: ty::INNERMOST, + } + } + + fn is_empty(&self) -> bool { + self.regions.is_empty() && self.types.is_empty() + } + + fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut start = true; + for r in &self.regions { + if !start { + write!(fmt, ", ")?; + } + start = false; + write!(fmt, "{}", r)?; + } + for (_, t) in &self.types { + if !start { + write!(fmt, ", ")?; + } + start = false; + write!(fmt, "{}", t)?; + } + Ok(()) + } +} + +impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { + fn visit_binder>(&mut self, t: &ty::Binder) -> bool { + self.binder_index.shift_in(1); + let result = t.super_visit_with(self); + self.binder_index.shift_out(1); + result + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + match t.kind { + ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { + self.types.insert( + bound_ty.var.as_u32(), + match bound_ty.kind { + ty::BoundTyKind::Param(name) => name, + ty::BoundTyKind::Anon => { + Symbol::intern(&format!("^{}", bound_ty.var.as_u32())) + } + }, + ); + } + + _ => (), + }; + + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + match r { + ty::ReLateBound(index, br) if *index == self.binder_index => match br { + ty::BoundRegion::BrNamed(_, name) => { + self.regions.insert(*name); + } + + ty::BoundRegion::BrAnon(var) => { + self.regions.insert(Symbol::intern(&format!("'^{}", var))); + } + + _ => (), + }, + + _ => (), + }; + + r.super_visit_with(self) + } +} + +impl<'tcx> fmt::Display for traits::Goal<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::GoalKind::*; + + match self { + Implies(hypotheses, goal) => { + write!(fmt, "if (")?; + for (index, hyp) in hypotheses.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{}", hyp)?; + } + write!(fmt, ") {{ {} }}", goal) + } + And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2), + Not(goal) => write!(fmt, "not {{ {} }}", goal), + DomainGoal(goal) => write!(fmt, "{}", goal), + Quantified(qkind, goal) => { + let mut collector = BoundNamesCollector::new(); + goal.skip_binder().visit_with(&mut collector); + + if !collector.is_empty() { + write!(fmt, "{}<", qkind)?; + collector.write_names(fmt)?; + write!(fmt, "> {{ ")?; + } + + write!(fmt, "{}", goal.skip_binder())?; + + if !collector.is_empty() { + write!(fmt, " }}")?; + } + + Ok(()) + } + Subtype(a, b) => write!(fmt, "{} <: {}", a, b), + CannotProve => write!(fmt, "CannotProve"), + } + } +} + +impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let traits::ProgramClause { goal, hypotheses, .. } = self; + write!(fmt, "{}", goal)?; + if !hypotheses.is_empty() { + write!(fmt, " :- ")?; + for (index, condition) in hypotheses.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{}", condition)?; + } + } + write!(fmt, ".") + } +} + +impl<'tcx> fmt::Display for traits::Clause<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + use crate::traits::Clause::*; + + match self { + Implies(clause) => write!(fmt, "{}", clause), + ForAll(clause) => { + let mut collector = BoundNamesCollector::new(); + clause.skip_binder().visit_with(&mut collector); + + if !collector.is_empty() { + write!(fmt, "forall<")?; + collector.write_names(fmt)?; + write!(fmt, "> {{ ")?; + } + + write!(fmt, "{}", clause.skip_binder())?; + + if !collector.is_empty() { + write!(fmt, " }}")?; + } + + Ok(()) + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// Lift implementations + +impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> { + type Lifted = traits::SelectionError<'tcx>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + match *self { + super::Unimplemented => Some(super::Unimplemented), + super::OutputTypeParameterMismatch(a, b, ref err) => { + tcx.lift(&(a, b)).and_then(|(a, b)| { + tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err)) + }) + } + super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)), + super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)), + super::Overflow => Some(super::Overflow), + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { + type Lifted = traits::ObligationCauseCode<'tcx>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + match *self { + super::ReturnNoExpression => Some(super::ReturnNoExpression), + super::MiscObligation => Some(super::MiscObligation), + super::SliceOrArrayElem => Some(super::SliceOrArrayElem), + super::TupleElem => Some(super::TupleElem), + super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf), + super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)), + super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)), + super::ReferenceOutlivesReferent(ty) => { + tcx.lift(&ty).map(super::ReferenceOutlivesReferent) + } + super::ObjectTypeBound(ty, r) => tcx + .lift(&ty) + .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))), + super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation), + super::Coercion { source, target } => { + Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? }) + } + super::AssignmentLhsSized => Some(super::AssignmentLhsSized), + super::TupleInitializerSized => Some(super::TupleInitializerSized), + super::StructInitializerSized => Some(super::StructInitializerSized), + super::VariableType(id) => Some(super::VariableType(id)), + super::ReturnValue(id) => Some(super::ReturnValue(id)), + super::ReturnType => Some(super::ReturnType), + super::SizedArgumentType => Some(super::SizedArgumentType), + super::SizedReturnType => Some(super::SizedReturnType), + super::SizedYieldType => Some(super::SizedYieldType), + super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)), + super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }), + super::ConstSized => Some(super::ConstSized), + super::ConstPatternStructural => Some(super::ConstPatternStructural), + super::SharedStatic => Some(super::SharedStatic), + super::BuiltinDerivedObligation(ref cause) => { + tcx.lift(cause).map(super::BuiltinDerivedObligation) + } + super::ImplDerivedObligation(ref cause) => { + tcx.lift(cause).map(super::ImplDerivedObligation) + } + super::CompareImplMethodObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } => Some(super::CompareImplMethodObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + }), + super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => { + Some(super::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + }) + } + super::ExprAssignable => Some(super::ExprAssignable), + super::MatchExpressionArm(box super::MatchExpressionArmCause { + arm_span, + source, + ref prior_arms, + last_ty, + scrut_hir_id, + }) => tcx.lift(&last_ty).map(|last_ty| { + super::MatchExpressionArm(box super::MatchExpressionArmCause { + arm_span, + source, + prior_arms: prior_arms.clone(), + last_ty, + scrut_hir_id, + }) + }), + super::Pattern { span, root_ty, origin_expr } => { + tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr }) + } + super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { + Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) + } + super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse), + super::MainFunctionType => Some(super::MainFunctionType), + super::StartFunctionType => Some(super::StartFunctionType), + super::IntrinsicType => Some(super::IntrinsicType), + super::MethodReceiver => Some(super::MethodReceiver), + super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)), + super::TrivialBound => Some(super::TrivialBound), + super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())), + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { + type Lifted = traits::DerivedObligationCause<'tcx>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| { + tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause { + parent_trait_ref: trait_ref, + parent_code: Rc::new(code), + }) + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> { + type Lifted = traits::ObligationCause<'tcx>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&self.code).map(|code| traits::ObligationCause { + span: self.span, + body_id: self.body_id, + code, + }) + } +} + +// For codegen only. +impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { + type Lifted = traits::Vtable<'tcx, ()>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + match self.clone() { + traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => { + tcx.lift(&substs).map(|substs| { + traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) + }) + } + traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)), + traits::VtableGenerator(traits::VtableGeneratorData { + generator_def_id, + substs, + nested, + }) => tcx.lift(&substs).map(|substs| { + traits::VtableGenerator(traits::VtableGeneratorData { + generator_def_id: generator_def_id, + substs: substs, + nested: nested, + }) + }), + traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => { + tcx.lift(&substs).map(|substs| { + traits::VtableClosure(traits::VtableClosureData { + closure_def_id, + substs, + nested, + }) + }) + } + traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => { + tcx.lift(&fn_ty).map(|fn_ty| { + traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) + }) + } + traits::VtableParam(n) => Some(traits::VtableParam(n)), + traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)), + traits::VtableObject(traits::VtableObjectData { + upcast_trait_ref, + vtable_base, + nested, + }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| { + traits::VtableObject(traits::VtableObjectData { + upcast_trait_ref: trait_ref, + vtable_base, + nested, + }) + }), + traits::VtableTraitAlias(traits::VtableTraitAliasData { + alias_def_id, + substs, + nested, + }) => tcx.lift(&substs).map(|substs| { + traits::VtableTraitAlias(traits::VtableTraitAliasData { + alias_def_id, + substs, + nested, + }) + }), + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> { + type Lifted = traits::Environment<'tcx>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses }) + } +} + +impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> { + type Lifted = traits::InEnvironment<'tcx, G::Lifted>; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&self.environment).and_then(|environment| { + tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal }) + }) + } +} + +impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause +where + C: chalk_engine::context::Context + Clone, + C: traits::ChalkContextLift<'tcx>, +{ + type Lifted = C::LiftedExClause; + + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + ::lift_ex_clause_to_tcx(self, tcx) + } +} + +impl<'tcx, C> Lift<'tcx> for chalk_engine::DelayedLiteral +where + C: chalk_engine::context::Context + Clone, + C: traits::ChalkContextLift<'tcx>, +{ + type Lifted = C::LiftedDelayedLiteral; + + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + ::lift_delayed_literal_to_tcx(self, tcx) + } +} + +impl<'tcx, C> Lift<'tcx> for chalk_engine::Literal +where + C: chalk_engine::context::Context + Clone, + C: traits::ChalkContextLift<'tcx>, +{ + type Lifted = C::LiftedLiteral; + + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + ::lift_literal_to_tcx(self, tcx) + } +} + +/////////////////////////////////////////////////////////////////////////// +// TypeFoldable implementations. + +CloneTypeFoldableAndLiftImpls! { + traits::QuantifierKind, +} + +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { + fn super_fold_with>(&self, folder: &mut F) -> Self { + let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); + folder.tcx().intern_goals(&v) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } +} + +impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { + let v = (**self).fold_with(folder); + folder.tcx().mk_goal(v) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + (**self).visit_with(visitor) + } +} + +CloneTypeFoldableAndLiftImpls! { + traits::ProgramClauseCategory, +} + +impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { + let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); + folder.tcx().intern_clauses(&v) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } +} + +impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause +where + C: traits::ExClauseFold<'tcx>, + C::Substitution: Clone, + C::RegionConstraint: Clone, +{ + fn super_fold_with>(&self, folder: &mut F) -> Self { + ::fold_ex_clause_with(self, folder) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + ::visit_ex_clause_with(self, visitor) + } +} + +EnumTypeFoldableImpl! { + impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::DelayedLiteral { + (chalk_engine::DelayedLiteral::CannotProve)(a), + (chalk_engine::DelayedLiteral::Negative)(a), + (chalk_engine::DelayedLiteral::Positive)(a, b), + } where + C: chalk_engine::context::Context> + Clone, +} + +EnumTypeFoldableImpl! { + impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::Literal { + (chalk_engine::Literal::Negative)(a), + (chalk_engine::Literal::Positive)(a), + } where + C: chalk_engine::context::Context> + Clone, +} + +CloneTypeFoldableAndLiftImpls! { + chalk_engine::TableIndex, +} From c851db94951643c2b200b13bf6d8ab6d5fdb541e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:44:59 +0100 Subject: [PATCH 0925/1253] Move specialization_graph definition in traits::types. --- .../traits/specialize/specialization_graph.rs | 200 +----------------- src/librustc/traits/types/mod.rs | 1 + .../traits/types/specialization_graph.rs | 199 +++++++++++++++++ 3 files changed, 204 insertions(+), 196 deletions(-) create mode 100644 src/librustc/traits/types/specialization_graph.rs diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 9509b6220eb0e..c90fa428001fc 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -1,58 +1,11 @@ use super::OverlapError; -use crate::ich::{self, StableHashingContext}; use crate::traits; -use crate::ty::fast_reject::{self, SimplifiedType}; -use crate::ty::{self, TyCtxt, TypeFoldable}; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_hir::def_id::{DefId, DefIdMap}; -use syntax::ast::Ident; - -/// A per-trait graph of impls in specialization order. At the moment, this -/// graph forms a tree rooted with the trait itself, with all other nodes -/// representing impls, and parent-child relationships representing -/// specializations. -/// -/// The graph provides two key services: -/// -/// - Construction. This implicitly checks for overlapping impls (i.e., impls -/// that overlap but where neither specializes the other -- an artifact of the -/// simple "chain" rule. -/// -/// - Parent extraction. In particular, the graph can give you the *immediate* -/// parents of a given specializing impl, which is needed for extracting -/// default items amongst other things. In the simple "chain" rule, every impl -/// has at most one parent. -#[derive(RustcEncodable, RustcDecodable, HashStable)] -pub struct Graph { - // All impls have a parent; the "root" impls have as their parent the `def_id` - // of the trait. - parent: DefIdMap, - - // The "root" impls are found by looking up the trait's def_id. - children: DefIdMap, -} +use rustc::ty::fast_reject::{self, SimplifiedType}; +use rustc::ty::{self, TyCtxt, TypeFoldable}; +use rustc_hir::def_id::DefId; -/// Children of a given impl, grouped into blanket/non-blanket varieties as is -/// done in `TraitDef`. -#[derive(Default, RustcEncodable, RustcDecodable)] -struct Children { - // Impls of a trait (or specializations of a given impl). To allow for - // quicker lookup, the impls are indexed by a simplified version of their - // `Self` type: impls with a simplifiable `Self` are stored in - // `nonblanket_impls` keyed by it, while all other impls are stored in - // `blanket_impls`. - // - // A similar division is used within `TraitDef`, but the lists there collect - // together *all* the impls for a trait, and are populated prior to building - // the specialization graph. - /// Impls of the trait. - nonblanket_impls: FxHashMap>, - - /// Blanket impls associated with the trait. - blanket_impls: Vec, -} +pub use rustc::traits::types::specialization_graph::*; #[derive(Copy, Clone, Debug)] pub enum FutureCompatOverlapErrorKind { @@ -269,10 +222,6 @@ where } impl<'tcx> Graph { - pub fn new() -> Graph { - Graph { parent: Default::default(), children: Default::default() } - } - /// Insert a local impl into the specialization graph. If an existing impl /// conflicts with it (has overlap, but neither specializes the other), /// information about the area of overlap is returned in the `Err`. @@ -383,145 +332,4 @@ impl<'tcx> Graph { self.children.entry(parent).or_default().insert_blindly(tcx, child); } - - /// The parent of a given impl, which is the `DefId` of the trait when the - /// impl is a "specialization root". - pub fn parent(&self, child: DefId) -> DefId { - *self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {:?}", child)) - } -} - -/// A node in the specialization graph is either an impl or a trait -/// definition; either can serve as a source of item definitions. -/// There is always exactly one trait definition node: the root. -#[derive(Debug, Copy, Clone)] -pub enum Node { - Impl(DefId), - Trait(DefId), -} - -impl<'tcx> Node { - pub fn is_from_trait(&self) -> bool { - match *self { - Node::Trait(..) => true, - _ => false, - } - } - - /// Iterate over the items defined directly by the given (impl or trait) node. - pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> { - tcx.associated_items(self.def_id()) - } - - /// Finds an associated item defined in this node. - /// - /// If this returns `None`, the item can potentially still be found in - /// parents of this node. - pub fn item( - &self, - tcx: TyCtxt<'tcx>, - trait_item_name: Ident, - trait_item_kind: ty::AssocKind, - trait_def_id: DefId, - ) -> Option { - use crate::ty::AssocKind::*; - - tcx.associated_items(self.def_id()).find(move |impl_item| { - match (trait_item_kind, impl_item.kind) { - | (Const, Const) - | (Method, Method) - | (Type, Type) - | (Type, OpaqueTy) // assoc. types can be made opaque in impls - => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), - - | (Const, _) - | (Method, _) - | (Type, _) - | (OpaqueTy, _) - => false, - } - }) - } - - pub fn def_id(&self) -> DefId { - match *self { - Node::Impl(did) => did, - Node::Trait(did) => did, - } - } -} - -#[derive(Copy, Clone)] -pub struct Ancestors<'tcx> { - trait_def_id: DefId, - specialization_graph: &'tcx Graph, - current_source: Option, -} - -impl Iterator for Ancestors<'_> { - type Item = Node; - fn next(&mut self) -> Option { - let cur = self.current_source.take(); - if let Some(Node::Impl(cur_impl)) = cur { - let parent = self.specialization_graph.parent(cur_impl); - - self.current_source = if parent == self.trait_def_id { - Some(Node::Trait(parent)) - } else { - Some(Node::Impl(parent)) - }; - } - cur - } -} - -pub struct NodeItem { - pub node: Node, - pub item: T, -} - -impl NodeItem { - pub fn map U>(self, f: F) -> NodeItem { - NodeItem { node: self.node, item: f(self.item) } - } -} - -impl<'tcx> Ancestors<'tcx> { - /// Finds the bottom-most (ie. most specialized) definition of an associated - /// item. - pub fn leaf_def( - mut self, - tcx: TyCtxt<'tcx>, - trait_item_name: Ident, - trait_item_kind: ty::AssocKind, - ) -> Option> { - let trait_def_id = self.trait_def_id; - self.find_map(|node| { - node.item(tcx, trait_item_name, trait_item_kind, trait_def_id) - .map(|item| NodeItem { node, item }) - }) - } -} - -/// Walk up the specialization ancestors of a given impl, starting with that -/// impl itself. -pub fn ancestors( - tcx: TyCtxt<'tcx>, - trait_def_id: DefId, - start_from_impl: DefId, -) -> Ancestors<'tcx> { - let specialization_graph = tcx.specialization_graph_of(trait_def_id); - Ancestors { - trait_def_id, - specialization_graph, - current_source: Some(Node::Impl(start_from_impl)), - } -} - -impl<'a> HashStable> for Children { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let Children { ref nonblanket_impls, ref blanket_impls } = *self; - - ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); - } } diff --git a/src/librustc/traits/types/mod.rs b/src/librustc/traits/types/mod.rs index b85a9d0193c8a..571fb505779ca 100644 --- a/src/librustc/traits/types/mod.rs +++ b/src/librustc/traits/types/mod.rs @@ -4,6 +4,7 @@ pub mod query; pub mod select; +pub mod specialization_graph; mod structural_impls; use crate::mir::interpret::ErrorHandled; diff --git a/src/librustc/traits/types/specialization_graph.rs b/src/librustc/traits/types/specialization_graph.rs new file mode 100644 index 0000000000000..3086850db6d9c --- /dev/null +++ b/src/librustc/traits/types/specialization_graph.rs @@ -0,0 +1,199 @@ +use crate::ich::{self, StableHashingContext}; +use crate::ty::fast_reject::SimplifiedType; +use crate::ty::{self, TyCtxt}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hir::def_id::{DefId, DefIdMap}; +use syntax::ast::Ident; + +/// A per-trait graph of impls in specialization order. At the moment, this +/// graph forms a tree rooted with the trait itself, with all other nodes +/// representing impls, and parent-child relationships representing +/// specializations. +/// +/// The graph provides two key services: +/// +/// - Construction. This implicitly checks for overlapping impls (i.e., impls +/// that overlap but where neither specializes the other -- an artifact of the +/// simple "chain" rule. +/// +/// - Parent extraction. In particular, the graph can give you the *immediate* +/// parents of a given specializing impl, which is needed for extracting +/// default items amongst other things. In the simple "chain" rule, every impl +/// has at most one parent. +#[derive(RustcEncodable, RustcDecodable, HashStable)] +pub struct Graph { + // All impls have a parent; the "root" impls have as their parent the `def_id` + // of the trait. + pub parent: DefIdMap, + + // The "root" impls are found by looking up the trait's def_id. + pub children: DefIdMap, +} + +impl Graph { + pub fn new() -> Graph { + Graph { parent: Default::default(), children: Default::default() } + } + + /// The parent of a given impl, which is the `DefId` of the trait when the + /// impl is a "specialization root". + pub fn parent(&self, child: DefId) -> DefId { + *self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {:?}", child)) + } +} + +/// Children of a given impl, grouped into blanket/non-blanket varieties as is +/// done in `TraitDef`. +#[derive(Default, RustcEncodable, RustcDecodable)] +pub struct Children { + // Impls of a trait (or specializations of a given impl). To allow for + // quicker lookup, the impls are indexed by a simplified version of their + // `Self` type: impls with a simplifiable `Self` are stored in + // `nonblanket_impls` keyed by it, while all other impls are stored in + // `blanket_impls`. + // + // A similar division is used within `TraitDef`, but the lists there collect + // together *all* the impls for a trait, and are populated prior to building + // the specialization graph. + /// Impls of the trait. + pub nonblanket_impls: FxHashMap>, + + /// Blanket impls associated with the trait. + pub blanket_impls: Vec, +} + +/// A node in the specialization graph is either an impl or a trait +/// definition; either can serve as a source of item definitions. +/// There is always exactly one trait definition node: the root. +#[derive(Debug, Copy, Clone)] +pub enum Node { + Impl(DefId), + Trait(DefId), +} + +impl<'tcx> Node { + pub fn is_from_trait(&self) -> bool { + match *self { + Node::Trait(..) => true, + _ => false, + } + } + + /// Iterate over the items defined directly by the given (impl or trait) node. + pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> { + tcx.associated_items(self.def_id()) + } + + /// Finds an associated item defined in this node. + /// + /// If this returns `None`, the item can potentially still be found in + /// parents of this node. + pub fn item( + &self, + tcx: TyCtxt<'tcx>, + trait_item_name: Ident, + trait_item_kind: ty::AssocKind, + trait_def_id: DefId, + ) -> Option { + use crate::ty::AssocKind::*; + + tcx.associated_items(self.def_id()).find(move |impl_item| { + match (trait_item_kind, impl_item.kind) { + | (Const, Const) + | (Method, Method) + | (Type, Type) + | (Type, OpaqueTy) // assoc. types can be made opaque in impls + => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), + + | (Const, _) + | (Method, _) + | (Type, _) + | (OpaqueTy, _) + => false, + } + }) + } + + pub fn def_id(&self) -> DefId { + match *self { + Node::Impl(did) => did, + Node::Trait(did) => did, + } + } +} + +#[derive(Copy, Clone)] +pub struct Ancestors<'tcx> { + trait_def_id: DefId, + specialization_graph: &'tcx Graph, + current_source: Option, +} + +impl Iterator for Ancestors<'_> { + type Item = Node; + fn next(&mut self) -> Option { + let cur = self.current_source.take(); + if let Some(Node::Impl(cur_impl)) = cur { + let parent = self.specialization_graph.parent(cur_impl); + + self.current_source = if parent == self.trait_def_id { + Some(Node::Trait(parent)) + } else { + Some(Node::Impl(parent)) + }; + } + cur + } +} + +pub struct NodeItem { + pub node: Node, + pub item: T, +} + +impl NodeItem { + pub fn map U>(self, f: F) -> NodeItem { + NodeItem { node: self.node, item: f(self.item) } + } +} + +impl<'tcx> Ancestors<'tcx> { + /// Finds the bottom-most (ie. most specialized) definition of an associated + /// item. + pub fn leaf_def( + mut self, + tcx: TyCtxt<'tcx>, + trait_item_name: Ident, + trait_item_kind: ty::AssocKind, + ) -> Option> { + let trait_def_id = self.trait_def_id; + self.find_map(|node| { + node.item(tcx, trait_item_name, trait_item_kind, trait_def_id) + .map(|item| NodeItem { node, item }) + }) + } +} + +/// Walk up the specialization ancestors of a given impl, starting with that +/// impl itself. +pub fn ancestors( + tcx: TyCtxt<'tcx>, + trait_def_id: DefId, + start_from_impl: DefId, +) -> Ancestors<'tcx> { + let specialization_graph = tcx.specialization_graph_of(trait_def_id); + Ancestors { + trait_def_id, + specialization_graph, + current_source: Some(Node::Impl(start_from_impl)), + } +} + +impl<'a> HashStable> for Children { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + let Children { ref nonblanket_impls, ref blanket_impls } = *self; + + ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); + } +} From 551cc5ebe626e93b23d02eb9ff363943e7505e52 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 13:55:05 +0100 Subject: [PATCH 0926/1253] Move ExpectedFound::new to ty::error. --- src/librustc/infer/mod.rs | 10 ---------- src/librustc/ty/error.rs | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 1f1ff1fd8bc13..4681a47317cf2 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -557,16 +557,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } } -impl ExpectedFound { - pub fn new(a_is_expected: bool, a: T, b: T) -> Self { - if a_is_expected { - ExpectedFound { expected: a, found: b } - } else { - ExpectedFound { expected: b, found: a } - } - } -} - impl<'tcx, T> InferOk<'tcx, T> { pub fn unit(self) -> InferOk<'tcx, ()> { InferOk { value: (), obligations: self.obligations } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 217ca0ca3f6f5..0282f409b328d 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -15,6 +15,16 @@ pub struct ExpectedFound { pub found: T, } +impl ExpectedFound { + pub fn new(a_is_expected: bool, a: T, b: T) -> Self { + if a_is_expected { + ExpectedFound { expected: a, found: b } + } else { + ExpectedFound { expected: b, found: a } + } + } +} + // Data structures used in type unification #[derive(Clone, Debug, TypeFoldable)] pub enum TypeError<'tcx> { From 735d664e7401de8f272cf26f404d1f0a44db5471 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Jan 2020 14:00:55 +0100 Subject: [PATCH 0927/1253] Move EvaluationCache::clear. --- src/librustc/traits/select.rs | 7 ------- src/librustc/traits/types/select.rs | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ca4a2aa5935a5..e4ef68c167f94 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3560,13 +3560,6 @@ impl<'tcx> TraitObligation<'tcx> { } } -impl<'tcx> EvaluationCache<'tcx> { - /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` - pub fn clear(&self) { - *self.hashmap.borrow_mut() = Default::default(); - } -} - impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList::with(self) diff --git a/src/librustc/traits/types/select.rs b/src/librustc/traits/types/select.rs index 9e5bd4cbb9a05..ac3d0049c0c7c 100644 --- a/src/librustc/traits/types/select.rs +++ b/src/librustc/traits/types/select.rs @@ -265,6 +265,13 @@ pub struct EvaluationCache<'tcx> { >, } +impl<'tcx> EvaluationCache<'tcx> { + /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` + pub fn clear(&self) { + *self.hashmap.borrow_mut() = Default::default(); + } +} + #[derive(Clone, Eq, PartialEq)] pub struct WithDepNode { dep_node: DepNodeIndex, From 183dfac1f31cc16975bb1f598779df5689d1e729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 11:26:06 -0800 Subject: [PATCH 0928/1253] Account for HKTB when suggesting introduction of named lifetime --- src/librustc_hir/hir.rs | 4 +- src/librustc_resolve/diagnostics.rs | 52 ++++++--- src/librustc_resolve/lifetimes.rs | 103 ++++++++++++++---- src/librustc_typeck/astconv.rs | 5 +- .../no_introducing_in_band_in_locals.stderr | 2 + src/test/ui/issues/issue-19707.stderr | 5 + .../ui/regions/regions-name-undeclared.stderr | 20 ++++ 7 files changed, 153 insertions(+), 38 deletions(-) diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 3ed0ad16eebf2..86252203f1d45 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2260,10 +2260,10 @@ impl TraitRef<'_> { #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub struct PolyTraitRef<'hir> { - /// The `'a` in `<'a> Foo<&'a T>`. + /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. + /// The `Foo<&'a T>` in `for <'a> Foo<&'a T>`. pub trait_ref: TraitRef<'hir>, pub span: Span, diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a612ad9e783f4..fafceb1f97cee 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -8,7 +8,6 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; -use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -20,6 +19,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; +use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1471,7 +1471,7 @@ crate fn add_missing_lifetime_specifiers_label( count: usize, lifetime_names: &FxHashSet, snippet: Option<&str>, - missing_named_lifetime_spots: &[&hir::Generics<'_>], + missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>], ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); @@ -1484,21 +1484,41 @@ crate fn add_missing_lifetime_specifiers_label( Applicability::MaybeIncorrect, ); }; - let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| { + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { err.span_label(span, "expected named lifetime parameter"); - if let Some(generics) = missing_named_lifetime_spots.iter().last() { + for missing in missing_named_lifetime_spots.iter().rev() { let mut introduce_suggestion = vec![]; - introduce_suggestion.push(match &generics.params { - [] => (generics.span, "<'lifetime>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + let msg; + let should_break; + introduce_suggestion.push(match missing { + MissingLifetimeSpot::Generics(generics) => { + msg = "consider introducing a named lifetime parameter"; + should_break = true; + match &generics.params { + [] => (generics.span, "<'lifetime>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + } + } + MissingLifetimeSpot::HRLT { span, span_type } => { + msg = "consider introducing a Higher-Ranked lifetime"; + should_break = false; + err.note( + "for more information on Higher-Ranked lifetimes, visit \ + https://doc.rust-lang.org/nomicon/hrtb.html", + ); + let suggestion = match span_type { + HRLTSpanType::Empty => "for<'lifetime> ", + HRLTSpanType::Tail => ", 'lifetime", + }; + (*span, suggestion.to_string()) + } }); - introduce_suggestion.push((span, sugg)); - err.multipart_suggestion( - "consider introducing a named lifetime parameter", - introduce_suggestion, - Applicability::MaybeIncorrect, - ); + introduce_suggestion.push((span, sugg.to_string())); + err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect); + if should_break { + break; + } } }; @@ -1513,13 +1533,13 @@ crate fn add_missing_lifetime_specifiers_label( suggest_existing(err, format!("{}<{}>", snippet, name)); } (0, _, Some("&")) => { - suggest_new(err, "&'lifetime ".to_string()); + suggest_new(err, "&'lifetime "); } (0, _, Some("'_")) => { - suggest_new(err, "'lifetime".to_string()); + suggest_new(err, "'lifetime"); } (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, format!("{}<'lifetime>", snippet)); + suggest_new(err, &format!("{}<'lifetime>", snippet)); } _ => { err.span_label(span, "expected lifetime parameter"); diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 6e9ed5fdc179c..a8d6afa0e55be 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -153,6 +153,22 @@ struct NamedRegionMap { object_lifetime_defaults: HirIdMap>, } +crate enum MissingLifetimeSpot<'tcx> { + Generics(&'tcx hir::Generics<'tcx>), + HRLT { span: Span, span_type: HRLTSpanType }, +} + +crate enum HRLTSpanType { + Empty, + Tail, +} + +impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { + fn into(self) -> MissingLifetimeSpot<'tcx> { + MissingLifetimeSpot::Generics(self) + } +} + struct LifetimeContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, map: &'a mut NamedRegionMap, @@ -186,7 +202,7 @@ struct LifetimeContext<'a, 'tcx> { /// When encountering an undefined named lifetime, we will suggest introducing it in these /// places. - missing_named_lifetime_spots: Vec<&'tcx hir::Generics<'tcx>>, + missing_named_lifetime_spots: Vec>, } #[derive(Debug)] @@ -389,7 +405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { match item.kind { hir::ItemKind::Fn(ref sig, ref generics, _) => { - self.missing_named_lifetime_spots.push(generics); + self.missing_named_lifetime_spots.push(generics.into()); self.visit_early_late(None, &sig.decl, generics, |this| { intravisit::walk_item(this, item); }); @@ -424,7 +440,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) | hir::ItemKind::Impl { ref generics, .. } => { - self.missing_named_lifetime_spots.push(generics); + self.missing_named_lifetime_spots.push(generics.into()); // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x @@ -696,7 +712,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; - self.missing_named_lifetime_spots.push(&trait_item.generics); + self.missing_named_lifetime_spots.push((&trait_item.generics).into()); match trait_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -753,7 +769,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { use self::hir::ImplItemKind::*; - self.missing_named_lifetime_spots.push(&impl_item.generics); + self.missing_named_lifetime_spots.push((&impl_item.generics).into()); match impl_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -953,6 +969,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ) { debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref); + let should_pop_missing_lt = self.is_trait_ref_fn_scope(trait_ref); if !self.trait_ref_hack || trait_ref.bound_generic_params.iter().any(|param| match param.kind { GenericParamKind::Lifetime { .. } => true, @@ -988,10 +1005,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); walk_list!(this, visit_generic_param, trait_ref.bound_generic_params); - this.visit_trait_ref(&trait_ref.trait_ref) + this.visit_trait_ref(&trait_ref.trait_ref); }) } else { - self.visit_trait_ref(&trait_ref.trait_ref) + self.visit_trait_ref(&trait_ref.trait_ref); + } + if should_pop_missing_lt { + self.missing_named_lifetime_spots.pop(); } } } @@ -1832,18 +1852,41 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_ref ); err.span_label(lifetime_ref.span, "undeclared lifetime"); - if !self.is_in_fn_syntax { - for generics in &self.missing_named_lifetime_spots { - let (span, sugg) = match &generics.params { - [] => (generics.span, format!("<{}>", lifetime_ref)), - [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), - }; - err.span_suggestion( - span, - &format!("consider introducing lifetime `{}` here", lifetime_ref), - sugg, - Applicability::MaybeIncorrect, - ); + for missing in &self.missing_named_lifetime_spots { + match missing { + MissingLifetimeSpot::Generics(generics) => { + let (span, sugg) = match &generics.params { + [] => (generics.span, format!("<{}>", lifetime_ref)), + [param, ..] => { + (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) + } + }; + err.span_suggestion( + span, + &format!("consider introducing lifetime `{}` here", lifetime_ref), + sugg, + Applicability::MaybeIncorrect, + ); + } + MissingLifetimeSpot::HRLT { span, span_type } => { + err.span_suggestion( + *span, + &format!( + "consider introducing a Higher-Ranked lifetime `{}` here", + lifetime_ref + ), + match span_type { + HRLTSpanType::Empty => format!("for<{}> ", lifetime_ref), + HRLTSpanType::Tail => format!(", {}", lifetime_ref), + } + .to_string(), + Applicability::MaybeIncorrect, + ); + err.note( + "for more information on Higher-Ranked lifetimes, visit \ + https://doc.rust-lang.org/nomicon/hrtb.html", + ); + } } } err.emit(); @@ -2441,6 +2484,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let elided_len = elided_params.len(); + // FIXME: collect spans of the input params when appropriate to use in the diagnostic. for (i, info) in elided_params.into_iter().enumerate() { let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info; @@ -2747,6 +2791,27 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let old_value = self.map.defs.remove(&lifetime_ref.hir_id); assert_eq!(old_value, Some(bad_def)); } + + fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { + if let Res::Def(_, did) = trait_ref.trait_ref.path.res { + if [ + self.tcx.lang_items().fn_once_trait(), + self.tcx.lang_items().fn_trait(), + self.tcx.lang_items().fn_mut_trait(), + ] + .contains(&Some(did)) + { + let (span, span_type) = match &trait_ref.bound_generic_params { + [] => (trait_ref.span.shrink_to_lo(), HRLTSpanType::Empty), + [.., bound] => (bound.span.shrink_to_hi(), HRLTSpanType::Tail), + }; + self.missing_named_lifetime_spots + .push(MissingLifetimeSpot::HRLT { span, span_type }); + return true; + } + }; + false + } } /// Detects late-bound lifetimes and inserts them into diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 231aed48fb6be..6bd120d818d09 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1307,12 +1307,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); } }; + // FIXME: point at the type params that don't have appropriate lifetimes: + // struct S1 Fn(&i32, &i32) -> &'a i32>(F); + // ---- ---- ^^^^^^^ struct_span_err!( tcx.sess, binding.span, E0582, "binding for associated type `{}` references lifetime `{}`, \ - which does not appear in the trait input types", + which does not appear in the trait input types", binding.item_name, br_name ) diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index bfb20ade035cf..7d71230e16210 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -9,6 +9,8 @@ LL | let y: &'test u32 = x; error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_introducing_in_band_in_locals.rs:10:16 | +LL | fn bar() { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | let y: fn(&'test u32) = foo2; | ^^^^^ undeclared lifetime diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 8a627bc0bd4de..c5129152aa581 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -17,6 +17,11 @@ LL | fn bar &u8>(f: &F) {} | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing a Higher-Ranked lifetime + | +LL | fn bar Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^^^^^ ^^^^^^^^^^ help: consider introducing a named lifetime parameter | LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index 79ebef41dccd6..cb72d1ec9bc71 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -88,12 +88,32 @@ error[E0261]: use of undeclared lifetime name `'b` | LL | ... &'b isize, | ^^ undeclared lifetime + | + = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing lifetime `'b` here + | +LL | fn fn_types<'b>(a: &'a isize, + | ^^^^ +help: consider introducing a Higher-Ranked lifetime `'b` here + | +LL | b: Box FnOnce(&'a isize, + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:45:36 | LL | ... &'b isize)>, | ^^ undeclared lifetime + | + = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing lifetime `'b` here + | +LL | fn fn_types<'b>(a: &'a isize, + | ^^^^ +help: consider introducing a Higher-Ranked lifetime `'b` here + | +LL | b: Box FnOnce(&'a isize, + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:46:17 From 70dbf5526d37ad031fca57ddde55bf8757bfc326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 11:48:52 -0800 Subject: [PATCH 0929/1253] Use spans for input borrowed types unrelated to return type --- src/librustc_resolve/lifetimes.rs | 27 +++++++++++++------ .../async-await/issues/issue-63388-2.stderr | 6 ++++- src/test/ui/issues/issue-19707.stderr | 12 +++++++-- src/test/ui/issues/issue-26638.stderr | 6 ++++- src/test/ui/issues/issue-30255.stderr | 18 ++++++++++--- ...urn-type-requires-explicit-lifetime.stderr | 12 +++++++-- .../ex1b-return-no-names-if-else.stderr | 6 ++++- src/test/ui/rfc1623.stderr | 12 +++++++-- .../return-without-lifetime.stderr | 12 +++++++-- ...oxed-closure-sugar-lifetime-elision.stderr | 6 ++++- .../in-fn-return-illegal.stderr | 6 ++++- .../underscore-lifetime-binders.stderr | 6 ++++- 12 files changed, 104 insertions(+), 25 deletions(-) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index a8d6afa0e55be..022f83af8159c 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -287,6 +287,7 @@ struct ElisionFailureInfo { index: usize, lifetime_count: usize, have_bound_regions: bool, + span: Span, } type ScopeRef<'a> = &'a Scope<'a>; @@ -2273,6 +2274,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { index: i, lifetime_count: gather.lifetimes.len(), have_bound_regions: gather.have_bound_regions, + span: input.span, } }) .collect(); @@ -2483,11 +2485,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { params.iter().cloned().filter(|info| info.lifetime_count > 0).collect(); let elided_len = elided_params.len(); + let mut spans = vec![]; - // FIXME: collect spans of the input params when appropriate to use in the diagnostic. for (i, info) in elided_params.into_iter().enumerate() { - let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info; + let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; + spans.push(span); let help_name = if let Some(ident) = parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident()) { @@ -2518,14 +2521,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + let help = |msg| { + if spans.is_empty() { + db.help(msg); + } else { + db.span_help(spans, msg); + } + }; + if len == 0 { db.help( "this function's return type contains a borrowed value, \ - but there is no value for it to be borrowed from", + but there is no value for it to be borrowed from", ); self.suggest_lifetime(db, span, "consider giving it a 'static lifetime") } else if elided_len == 0 { - db.help( + help( "this function's return type contains a borrowed value with \ an elided lifetime, but the lifetime cannot be derived from \ the arguments", @@ -2533,16 +2544,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let msg = "consider giving it an explicit bounded or 'static lifetime"; self.suggest_lifetime(db, span, msg) } else if elided_len == 1 { - db.help(&format!( + help(&format!( "this function's return type contains a borrowed value, \ - but the signature does not say which {} it is borrowed from", + but the signature does not say which {} it is borrowed from", m )); true } else { - db.help(&format!( + help(&format!( "this function's return type contains a borrowed value, \ - but the signature does not say whether it is borrowed from {}", + but the signature does not say whether it is borrowed from {}", m )); true diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index 7e45d588c6c6c..a12c601b936af 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` + --> $DIR/issue-63388-2.rs:11:14 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | ^^^^^^^^ ^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/issue-63388-2.rs:11:9 diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index c5129152aa581..1be066caa87a9 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | type Foo = fn(&u8, &u8) -> &u8; | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/issue-19707.rs:3:15 + | +LL | type Foo = fn(&u8, &u8) -> &u8; + | ^^^ ^^^ help: consider introducing a named lifetime parameter | LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; @@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier LL | fn bar &u8>(f: &F) {} | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/issue-19707.rs:5:14 + | +LL | fn bar &u8>(f: &F) {} + | ^^^ ^^^ = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing a Higher-Ranked lifetime | diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 85d5d9cc42e9a..882102799d913 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from + --> $DIR/issue-26638.rs:1:21 + | +LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider introducing a named lifetime parameter | LL | fn parse_type<'lifetime>(iter: Box+'static>) -> &'lifetime str { iter.next() } diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index c940227764099..e2b57a20325d3 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn f(a: &S, b: i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from + --> $DIR/issue-30255.rs:9:9 + | +LL | fn f(a: &S, b: i32) -> &i32 { + | ^^ help: consider introducing a named lifetime parameter | LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { @@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` + --> $DIR/issue-30255.rs:14:9 + | +LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { + | ^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { @@ -28,7 +36,11 @@ error[E0106]: missing lifetime specifier LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` + --> $DIR/issue-30255.rs:19:9 + | +LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { + | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 1d5eeac23f96a..d1b597804cda9 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -12,7 +12,11 @@ error[E0106]: missing lifetime specifier LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` + --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:10 + | +LL | fn g(_x: &isize, _y: &isize) -> &isize { + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { @@ -24,7 +28,11 @@ error[E0106]: missing lifetime specifier LL | fn h(_x: &Foo) -> &isize { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from + --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:10 + | +LL | fn h(_x: &Foo) -> &isize { + | ^^^^ help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index 2990ab8682434..52a980a61daa0 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + --> $DIR/ex1b-return-no-names-if-else.rs:1:11 + | +LL | fn foo(x: &i32, y: &i32) -> &i32 { + | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 5b665e181412a..aabe088d63ca6 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/rfc1623.rs:8:29 + | +LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = + | ^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:10:39 @@ -12,7 +16,11 @@ error[E0106]: missing lifetime specifier LL | &(non_elidable as fn(&u8, &u8) -> &u8); | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/rfc1623.rs:10:26 + | +LL | &(non_elidable as fn(&u8, &u8) -> &u8); + | ^^^ ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 7f5ff95938e30..3b7936c5f44b6 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -10,7 +10,11 @@ error[E0106]: missing lifetime specifier LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + --> $DIR/return-without-lifetime.rs:5:20 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:7:35 @@ -18,7 +22,11 @@ error[E0106]: missing lifetime specifier LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + --> $DIR/return-without-lifetime.rs:7:20 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 0a028e44919a6..1e15196f8ec85 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | let _: dyn Foo(&isize, &usize) -> &usize; | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:20 + | +LL | let _: dyn Foo(&isize, &usize) -> &usize; + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn main<'lifetime>() { diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index cf820249c80af..801504627c0ac 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + --> $DIR/in-fn-return-illegal.rs:5:11 + | +LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } + | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 517904ee62869..ef3ad18ee8861 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -30,7 +30,11 @@ error[E0106]: missing lifetime specifier LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` + --> $DIR/underscore-lifetime-binders.rs:16:12 + | +LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } From 7e1464336a627ecb962f4eb38173fbfbfdd2ccf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 12:41:49 -0800 Subject: [PATCH 0930/1253] When suggesting lifetimes, propose adding the new lifetime to all arguments --- src/librustc_resolve/diagnostics.rs | 12 +++++++++++- src/librustc_resolve/lifetimes.rs | 9 ++++++--- src/test/ui/issues/issue-19707.stderr | 12 ++++++------ src/test/ui/issues/issue-30255.stderr | 12 ++++++------ ...ion-return-type-requires-explicit-lifetime.stderr | 8 ++++---- .../ex1b-return-no-names-if-else.stderr | 4 ++-- .../underscore-lifetime/in-fn-return-illegal.stderr | 4 ++-- 7 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index fafceb1f97cee..56fb66004053c 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -19,7 +19,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot}; +use crate::lifetimes::{ElisionFailureInfo, HRLTSpanType, MissingLifetimeSpot}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1467,11 +1467,13 @@ crate fn report_missing_lifetime_specifiers( crate fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, + source_map: &SourceMap, span: Span, count: usize, lifetime_names: &FxHashSet, snippet: Option<&str>, missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>], + params: &[ElisionFailureInfo], ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); @@ -1514,6 +1516,14 @@ crate fn add_missing_lifetime_specifiers_label( (*span, suggestion.to_string()) } }); + for param in params { + if let Ok(snippet) = source_map.span_to_snippet(param.span) { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'lifetime {}", &snippet[1..]))); + } + } + } introduce_suggestion.push((span, sugg.to_string())); err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect); if should_break { diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 022f83af8159c..97d314c8f65a9 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -280,14 +280,14 @@ enum Elide { } #[derive(Clone, Debug)] -struct ElisionFailureInfo { +crate struct ElisionFailureInfo { /// Where we can find the argument pattern. parent: Option, /// The index of the argument in the original definition. index: usize, lifetime_count: usize, have_bound_regions: bool, - span: Span, + crate span: Span, } type ScopeRef<'a> = &'a Scope<'a>; @@ -2441,11 +2441,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if add_label { add_missing_lifetime_specifiers_label( &mut err, + self.tcx.sess.source_map(), span, lifetime_refs.len(), &lifetime_names, self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), &self.missing_named_lifetime_spots, + error.map(|p| &p[..]).unwrap_or(&[]), ); } @@ -2488,7 +2490,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut spans = vec![]; for (i, info) in elided_params.into_iter().enumerate() { - let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; + let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = + info; spans.push(span); let help_name = if let Some(ident) = diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 1be066caa87a9..f8917b7bdd087 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -11,8 +11,8 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | ^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | type Foo<'lifetime> = fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8; + | ^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 @@ -28,12 +28,12 @@ LL | fn bar &u8>(f: &F) {} = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing a Higher-Ranked lifetime | -LL | fn bar Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar<'lifetime, F: Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index e2b57a20325d3..fbe715de932f9 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -11,8 +11,8 @@ LL | fn f(a: &S, b: i32) -> &i32 { | ^^ help: consider introducing a named lifetime parameter | -LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn f<'lifetime>(a: &'lifetime S, b: i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 @@ -27,8 +27,8 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'lifetime>(a: &'lifetime S, b: bool, c: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 @@ -43,8 +43,8 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'lifetime>(a: &'lifetime bool, b: bool, c: &'lifetime S, d: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index d1b597804cda9..01236e3c77304 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -19,8 +19,8 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'lifetime>(_x: &'lifetime isize, _y: &'lifetime isize) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 @@ -35,8 +35,8 @@ LL | fn h(_x: &Foo) -> &isize { | ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'lifetime>(_x: &'lifetime Foo) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index 52a980a61daa0..bea1a8bf2c1fd 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn foo<'lifetime>(x: &'lifetime i32, y: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index 801504627c0ac..97014dae2b970 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } - | ^^^^^^^^^^^ ^^^^^^^^^ +LL | fn foo<'lifetime>(x: &'lifetime u32, y: &'lifetime u32) -> &'lifetime u32 { loop { } } + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to previous error From fa4594196d2bcc265c4cdc1382d33366b3008341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 12:49:12 -0800 Subject: [PATCH 0931/1253] Suggest `'r` instead of `'lifetime` --- src/librustc_resolve/diagnostics.rs | 16 +++--- src/test/ui/error-codes/E0106.stderr | 16 +++--- .../assoc-type.stderr | 8 +-- ...anon-lifetime-in-struct-declaration.stderr | 4 +- src/test/ui/issues/issue-19707.stderr | 12 ++--- src/test/ui/issues/issue-26638.stderr | 4 +- src/test/ui/issues/issue-30255.stderr | 12 ++--- ...urn-type-requires-explicit-lifetime.stderr | 8 +-- .../ex1b-return-no-names-if-else.stderr | 4 +- src/test/ui/proc-macro/item-error.stderr | 4 +- .../ui/regions/regions-in-enums-anon.stderr | 4 +- .../ui/regions/regions-in-structs-anon.stderr | 4 +- .../fn-missing-lifetime-in-item.rs | 8 +++ .../fn-missing-lifetime-in-item.stderr | 53 +++++++++++++++++++ ...oxed-closure-sugar-lifetime-elision.stderr | 2 +- .../dyn-trait-underscore-in-struct.stderr | 4 +- .../in-fn-return-illegal.stderr | 4 +- .../ui/underscore-lifetime/in-struct.stderr | 8 +-- .../underscore-lifetime-binders.stderr | 4 +- 19 files changed, 120 insertions(+), 59 deletions(-) create mode 100644 src/test/ui/suggestions/fn-missing-lifetime-in-item.rs create mode 100644 src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 56fb66004053c..8346dc3b85425 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1498,8 +1498,8 @@ crate fn add_missing_lifetime_specifiers_label( msg = "consider introducing a named lifetime parameter"; should_break = true; match &generics.params { - [] => (generics.span, "<'lifetime>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + [] => (generics.span, "<'r>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'r, ".to_string()), } } MissingLifetimeSpot::HRLT { span, span_type } => { @@ -1510,8 +1510,8 @@ crate fn add_missing_lifetime_specifiers_label( https://doc.rust-lang.org/nomicon/hrtb.html", ); let suggestion = match span_type { - HRLTSpanType::Empty => "for<'lifetime> ", - HRLTSpanType::Tail => ", 'lifetime", + HRLTSpanType::Empty => "for<'r> ", + HRLTSpanType::Tail => ", 'r", }; (*span, suggestion.to_string()) } @@ -1520,7 +1520,7 @@ crate fn add_missing_lifetime_specifiers_label( if let Ok(snippet) = source_map.span_to_snippet(param.span) { if snippet.starts_with("&") && !snippet.starts_with("&'") { introduce_suggestion - .push((param.span, format!("&'lifetime {}", &snippet[1..]))); + .push((param.span, format!("&'r {}", &snippet[1..]))); } } } @@ -1543,13 +1543,13 @@ crate fn add_missing_lifetime_specifiers_label( suggest_existing(err, format!("{}<{}>", snippet, name)); } (0, _, Some("&")) => { - suggest_new(err, "&'lifetime "); + suggest_new(err, "&'r "); } (0, _, Some("'_")) => { - suggest_new(err, "'lifetime"); + suggest_new(err, "'r"); } (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, &format!("{}<'lifetime>", snippet)); + suggest_new(err, &format!("{}<'r>", snippet)); } _ => { err.span_label(span, "expected lifetime parameter"); diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index e01e0a6f54b07..3792b8f637aa0 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -6,8 +6,8 @@ LL | x: &bool, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'lifetime> { -LL | x: &'lifetime bool, +LL | struct Foo<'r> { +LL | x: &'r bool, | error[E0106]: missing lifetime specifier @@ -18,9 +18,9 @@ LL | B(&bool), | help: consider introducing a named lifetime parameter | -LL | enum Bar<'lifetime> { +LL | enum Bar<'r> { LL | A(u8), -LL | B(&'lifetime bool), +LL | B(&'r bool), | error[E0106]: missing lifetime specifier @@ -31,8 +31,8 @@ LL | type MyStr = &str; | help: consider introducing a named lifetime parameter | -LL | type MyStr<'lifetime> = &'lifetime str; - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | type MyStr<'r> = &'r str; + | ^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:17:10 @@ -42,8 +42,8 @@ LL | baz: Baz, | help: consider introducing a named lifetime parameter | -LL | struct Quux<'lifetime> { -LL | baz: Baz<'lifetime>, +LL | struct Quux<'r> { +LL | baz: Baz<'r>, | error[E0106]: missing lifetime specifiers diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr index 14c53f906654b..d3968917bed54 100644 --- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -6,8 +6,8 @@ LL | type Output = &i32; | help: consider introducing a named lifetime parameter | -LL | type Output<'lifetime> = &'lifetime i32; - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | type Output<'r> = &'r i32; + | ^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/assoc-type.rs:16:20 @@ -17,8 +17,8 @@ LL | type Output = &'_ i32; | help: consider introducing a named lifetime parameter | -LL | type Output<'lifetime> = &'lifetime i32; - | ^^^^^^^^^^^ ^^^^^^^^^ +LL | type Output<'r> = &'r i32; + | ^^^^ ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr index 5f101a24c1d43..3688b222a3508 100644 --- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr +++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr @@ -6,8 +6,8 @@ LL | struct Heartbreak(Betrayal); | help: consider introducing a named lifetime parameter | -LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>); - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +LL | struct Heartbreak<'r>(Betrayal<'r>); + | ^^^^ ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index f8917b7bdd087..8246b0e54019f 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -11,8 +11,8 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | ^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | type Foo<'lifetime> = fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8; - | ^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | type Foo<'r> = fn(&'r u8, &'r u8) -> &'r u8; + | ^^^^ ^^^^^^ ^^^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 @@ -28,12 +28,12 @@ LL | fn bar &u8>(f: &F) {} = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing a Higher-Ranked lifetime | -LL | fn bar Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar Fn(&'r u8, &'r u8) -> &'r u8>(f: &F) {} + | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | fn bar<'lifetime, F: Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar<'r, F: Fn(&'r u8, &'r u8) -> &'r u8>(f: &F) {} + | ^^^ ^^^^^^ ^^^^^^ ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 882102799d913..8c114cf1ae8b4 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -11,8 +11,8 @@ LL | fn parse_type(iter: Box+'static>) -> &str { iter.ne | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn parse_type<'lifetime>(iter: Box+'static>) -> &'lifetime str { iter.next() } - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn parse_type<'r>(iter: Box+'static>) -> &'r str { iter.next() } + | ^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:4:40 diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index fbe715de932f9..fff3766e12dc7 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -11,8 +11,8 @@ LL | fn f(a: &S, b: i32) -> &i32 { | ^^ help: consider introducing a named lifetime parameter | -LL | fn f<'lifetime>(a: &'lifetime S, b: i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn f<'r>(a: &'r S, b: i32) -> &'r i32 { + | ^^^^ ^^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 @@ -27,8 +27,8 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(a: &'lifetime S, b: bool, c: &'lifetime i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'r>(a: &'r S, b: bool, c: &'r i32) -> &'r i32 { + | ^^^^ ^^^^^ ^^^^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 @@ -43,8 +43,8 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(a: &'lifetime bool, b: bool, c: &'lifetime S, d: &'lifetime i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'r>(a: &'r bool, b: bool, c: &'r S, d: &'r i32) -> &'r i32 { + | ^^^^ ^^^^^^^^ ^^^^^ ^^^^^^^ ^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 01236e3c77304..638c8b8612cf2 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -19,8 +19,8 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(_x: &'lifetime isize, _y: &'lifetime isize) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'r>(_x: &'r isize, _y: &'r isize) -> &'r isize { + | ^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 @@ -35,8 +35,8 @@ LL | fn h(_x: &Foo) -> &isize { | ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(_x: &'lifetime Foo) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'r>(_x: &'r Foo) -> &'r isize { + | ^^^^ ^^^^^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index bea1a8bf2c1fd..e1982ea393ef4 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &'lifetime i32, y: &'lifetime i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn foo<'r>(x: &'r i32, y: &'r i32) -> &'r i32 { + | ^^^^ ^^^^^^^ ^^^^^^^ ^^^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr index 01eadbe252e9f..be33f2e2f7695 100644 --- a/src/test/ui/proc-macro/item-error.stderr +++ b/src/test/ui/proc-macro/item-error.stderr @@ -6,8 +6,8 @@ LL | a: &u64 | help: consider introducing a named lifetime parameter | -LL | struct A<'lifetime> { -LL | a: &'lifetime u64 +LL | struct A<'r> { +LL | a: &'r u64 | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr index 41655a210b3c0..46555df59367e 100644 --- a/src/test/ui/regions/regions-in-enums-anon.stderr +++ b/src/test/ui/regions/regions-in-enums-anon.stderr @@ -6,8 +6,8 @@ LL | Bar(&isize) | help: consider introducing a named lifetime parameter | -LL | enum Foo<'lifetime> { -LL | Bar(&'lifetime isize) +LL | enum Foo<'r> { +LL | Bar(&'r isize) | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr index fbe8036880f48..e807810db26fb 100644 --- a/src/test/ui/regions/regions-in-structs-anon.stderr +++ b/src/test/ui/regions/regions-in-structs-anon.stderr @@ -6,8 +6,8 @@ LL | x: &isize | help: consider introducing a named lifetime parameter | -LL | struct Foo<'lifetime> { -LL | x: &'lifetime isize +LL | struct Foo<'r> { +LL | x: &'r isize | error: aborting due to previous error diff --git a/src/test/ui/suggestions/fn-missing-lifetime-in-item.rs b/src/test/ui/suggestions/fn-missing-lifetime-in-item.rs new file mode 100644 index 0000000000000..dac6610b3355f --- /dev/null +++ b/src/test/ui/suggestions/fn-missing-lifetime-in-item.rs @@ -0,0 +1,8 @@ +struct S1 &'a i32>(F); //~ ERROR use of undeclared lifetime name `'a` +struct S2 &i32>(F); //~ ERROR missing lifetime specifier +struct S3 Fn(&i32, &i32) -> &'a i32>(F); +//~^ ERROR binding for associated type `Output` references lifetime `'a`, which does not appear +struct S4 Fn(&'x i32, &'x i32) -> &'x i32>(F); +const C: Option Fn(&usize, &usize) -> &'a usize>> = None; +//~^ ERROR binding for associated type `Output` references lifetime `'a`, which does not appear +fn main() {} diff --git a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr new file mode 100644 index 0000000000000..c1a40ebc89286 --- /dev/null +++ b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr @@ -0,0 +1,53 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/fn-missing-lifetime-in-item.rs:1:33 + | +LL | struct S1 &'a i32>(F); + | ^^ undeclared lifetime + | + = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing lifetime `'a` here + | +LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F); + | ^^^ +help: consider introducing a Higher-Ranked lifetime `'a` here + | +LL | struct S1 Fn(&i32, &i32) -> &'a i32>(F); + | ^^^^^^^ + +error[E0106]: missing lifetime specifier + --> $DIR/fn-missing-lifetime-in-item.rs:2:32 + | +LL | struct S2 &i32>(F); + | ^ expected named lifetime parameter + | +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/fn-missing-lifetime-in-item.rs:2:17 + | +LL | struct S2 &i32>(F); + | ^^^^ ^^^^ + = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing a Higher-Ranked lifetime + | +LL | struct S2 Fn(&'r i32, &'r i32) -> &'r i32>(F); + | ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^ +help: consider introducing a named lifetime parameter + | +LL | struct S2<'r, F: Fn(&'r i32, &'r i32) -> &'r i32>(F); + | ^^^ ^^^^^^^ ^^^^^^^ ^^^ + +error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types + --> $DIR/fn-missing-lifetime-in-item.rs:3:40 + | +LL | struct S3 Fn(&i32, &i32) -> &'a i32>(F); + | ^^^^^^^ + +error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types + --> $DIR/fn-missing-lifetime-in-item.rs:6:55 + | +LL | const C: Option Fn(&usize, &usize) -> &'a usize>> = None; + | ^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0106, E0261, E0582. +For more information about an error, try `rustc --explain E0106`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 1e15196f8ec85..459000a3722ca 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -11,7 +11,7 @@ LL | let _: dyn Foo(&isize, &usize) -> &usize; | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn main<'lifetime>() { +LL | fn main<'r>() { LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, LL | dyn Foo(&isize) -> &isize >(); LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index 04df2e4570396..d0efd788dc1a9 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -6,8 +6,8 @@ LL | x: Box, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'lifetime> { -LL | x: Box, +LL | struct Foo<'r> { +LL | x: Box, | error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index 97014dae2b970..998028622c265 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &'lifetime u32, y: &'lifetime u32) -> &'lifetime u32 { loop { } } - | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^ +LL | fn foo<'r>(x: &'r u32, y: &'r u32) -> &'r u32 { loop { } } + | ^^^^ ^^^^^^^ ^^^^^^^ ^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr index e01b39a4b64f4..406e0a92013d4 100644 --- a/src/test/ui/underscore-lifetime/in-struct.stderr +++ b/src/test/ui/underscore-lifetime/in-struct.stderr @@ -6,8 +6,8 @@ LL | x: &'_ u32, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'lifetime> { -LL | x: &'lifetime u32, +LL | struct Foo<'r> { +LL | x: &'r u32, | error[E0106]: missing lifetime specifier @@ -18,8 +18,8 @@ LL | Variant(&'_ u32), | help: consider introducing a named lifetime parameter | -LL | enum Bar<'lifetime> { -LL | Variant(&'lifetime u32), +LL | enum Bar<'r> { +LL | Variant(&'r u32), | error: aborting due to 2 previous errors diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index ef3ad18ee8861..94f3499df5f26 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -37,8 +37,8 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } - | ^^^^^^^^^^^ ^^^^^^^^^ +LL | fn foo2<'r>(_: &'_ u8, y: &'_ u8) -> &'r u8 { y } + | ^^^^ ^^ error: aborting due to 5 previous errors From 2100b31535a2a6a51876c024591b9e5679692a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 14:08:59 -0800 Subject: [PATCH 0932/1253] review comments --- src/librustc_hir/hir.rs | 2 +- src/librustc_resolve/diagnostics.rs | 20 +++++++++---------- src/librustc_resolve/lifetimes.rs | 4 ++-- src/test/ui/error-codes/E0106.stderr | 14 ++++++------- .../assoc-type.stderr | 4 ++-- ...anon-lifetime-in-struct-declaration.stderr | 2 +- src/test/ui/issues/issue-19707.stderr | 10 +++++----- src/test/ui/issues/issue-26638.stderr | 2 +- src/test/ui/issues/issue-30255.stderr | 6 +++--- ...urn-type-requires-explicit-lifetime.stderr | 4 ++-- .../ex1b-return-no-names-if-else.stderr | 2 +- src/test/ui/proc-macro/item-error.stderr | 4 ++-- .../ui/regions/regions-in-enums-anon.stderr | 4 ++-- .../ui/regions/regions-in-structs-anon.stderr | 4 ++-- .../ui/regions/regions-name-undeclared.stderr | 8 ++++---- .../fn-missing-lifetime-in-item.stderr | 12 +++++------ ...oxed-closure-sugar-lifetime-elision.stderr | 2 +- .../dyn-trait-underscore-in-struct.stderr | 4 ++-- .../in-fn-return-illegal.stderr | 2 +- .../ui/underscore-lifetime/in-struct.stderr | 8 ++++---- .../underscore-lifetime-binders.stderr | 2 +- 21 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 86252203f1d45..0c93a192667e5 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2263,7 +2263,7 @@ pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], - /// The `Foo<&'a T>` in `for <'a> Foo<&'a T>`. + /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`. pub trait_ref: TraitRef<'hir>, pub span: Span, diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 8346dc3b85425..b62c9f4747c0b 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1498,20 +1498,20 @@ crate fn add_missing_lifetime_specifiers_label( msg = "consider introducing a named lifetime parameter"; should_break = true; match &generics.params { - [] => (generics.span, "<'r>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'r, ".to_string()), + [] => (generics.span, "<'a>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), } } MissingLifetimeSpot::HRLT { span, span_type } => { - msg = "consider introducing a Higher-Ranked lifetime"; + msg = "consider introducing a higher-ranked lifetime"; should_break = false; err.note( - "for more information on Higher-Ranked lifetimes, visit \ + "for more information on higher-ranked lifetimes, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); let suggestion = match span_type { - HRLTSpanType::Empty => "for<'r> ", - HRLTSpanType::Tail => ", 'r", + HRLTSpanType::Empty => "for<'a> ", + HRLTSpanType::Tail => ", 'a", }; (*span, suggestion.to_string()) } @@ -1520,7 +1520,7 @@ crate fn add_missing_lifetime_specifiers_label( if let Ok(snippet) = source_map.span_to_snippet(param.span) { if snippet.starts_with("&") && !snippet.starts_with("&'") { introduce_suggestion - .push((param.span, format!("&'r {}", &snippet[1..]))); + .push((param.span, format!("&'a {}", &snippet[1..]))); } } } @@ -1543,13 +1543,13 @@ crate fn add_missing_lifetime_specifiers_label( suggest_existing(err, format!("{}<{}>", snippet, name)); } (0, _, Some("&")) => { - suggest_new(err, "&'r "); + suggest_new(err, "&'a "); } (0, _, Some("'_")) => { - suggest_new(err, "'r"); + suggest_new(err, "'a"); } (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, &format!("{}<'r>", snippet)); + suggest_new(err, &format!("{}<'a>", snippet)); } _ => { err.span_label(span, "expected lifetime parameter"); diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 97d314c8f65a9..69deffe4a4c9a 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -1873,7 +1873,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { err.span_suggestion( *span, &format!( - "consider introducing a Higher-Ranked lifetime `{}` here", + "consider introducing a higher-ranked lifetime `{}` here", lifetime_ref ), match span_type { @@ -1884,7 +1884,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Applicability::MaybeIncorrect, ); err.note( - "for more information on Higher-Ranked lifetimes, visit \ + "for more information on higher-ranked lifetimes, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); } diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index 3792b8f637aa0..a23bcbfd71a56 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -6,8 +6,8 @@ LL | x: &bool, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'r> { -LL | x: &'r bool, +LL | struct Foo<'a> { +LL | x: &'a bool, | error[E0106]: missing lifetime specifier @@ -18,9 +18,9 @@ LL | B(&bool), | help: consider introducing a named lifetime parameter | -LL | enum Bar<'r> { +LL | enum Bar<'a> { LL | A(u8), -LL | B(&'r bool), +LL | B(&'a bool), | error[E0106]: missing lifetime specifier @@ -31,7 +31,7 @@ LL | type MyStr = &str; | help: consider introducing a named lifetime parameter | -LL | type MyStr<'r> = &'r str; +LL | type MyStr<'a> = &'a str; | ^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -42,8 +42,8 @@ LL | baz: Baz, | help: consider introducing a named lifetime parameter | -LL | struct Quux<'r> { -LL | baz: Baz<'r>, +LL | struct Quux<'a> { +LL | baz: Baz<'a>, | error[E0106]: missing lifetime specifiers diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr index d3968917bed54..211a3286cc355 100644 --- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -6,7 +6,7 @@ LL | type Output = &i32; | help: consider introducing a named lifetime parameter | -LL | type Output<'r> = &'r i32; +LL | type Output<'a> = &'a i32; | ^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -17,7 +17,7 @@ LL | type Output = &'_ i32; | help: consider introducing a named lifetime parameter | -LL | type Output<'r> = &'r i32; +LL | type Output<'a> = &'a i32; | ^^^^ ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr index 3688b222a3508..f2a4150632d2f 100644 --- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr +++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr @@ -6,7 +6,7 @@ LL | struct Heartbreak(Betrayal); | help: consider introducing a named lifetime parameter | -LL | struct Heartbreak<'r>(Betrayal<'r>); +LL | struct Heartbreak<'a>(Betrayal<'a>); | ^^^^ ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 8246b0e54019f..e84bfb969d4f9 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -11,7 +11,7 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | ^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | type Foo<'r> = fn(&'r u8, &'r u8) -> &'r u8; +LL | type Foo<'a> = fn(&'a u8, &'a u8) -> &'a u8; | ^^^^ ^^^^^^ ^^^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -25,14 +25,14 @@ help: this function's return type contains a borrowed value, but the signature d | LL | fn bar &u8>(f: &F) {} | ^^^ ^^^ - = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html -help: consider introducing a Higher-Ranked lifetime + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing a higher-ranked lifetime | -LL | fn bar Fn(&'r u8, &'r u8) -> &'r u8>(f: &F) {} +LL | fn bar Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {} | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | fn bar<'r, F: Fn(&'r u8, &'r u8) -> &'r u8>(f: &F) {} +LL | fn bar<'a, F: Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {} | ^^^ ^^^^^^ ^^^^^^ ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 8c114cf1ae8b4..75cd5332fd9a4 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -11,7 +11,7 @@ LL | fn parse_type(iter: Box+'static>) -> &str { iter.ne | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn parse_type<'r>(iter: Box+'static>) -> &'r str { iter.next() } +LL | fn parse_type<'a>(iter: Box+'static>) -> &'a str { iter.next() } | ^^^^ ^^^ error[E0106]: missing lifetime specifier diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index fff3766e12dc7..3c26365d5d168 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -11,7 +11,7 @@ LL | fn f(a: &S, b: i32) -> &i32 { | ^^ help: consider introducing a named lifetime parameter | -LL | fn f<'r>(a: &'r S, b: i32) -> &'r i32 { +LL | fn f<'a>(a: &'a S, b: i32) -> &'a i32 { | ^^^^ ^^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -27,7 +27,7 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'r>(a: &'r S, b: bool, c: &'r i32) -> &'r i32 { +LL | fn g<'a>(a: &'a S, b: bool, c: &'a i32) -> &'a i32 { | ^^^^ ^^^^^ ^^^^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -43,7 +43,7 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'r>(a: &'r bool, b: bool, c: &'r S, d: &'r i32) -> &'r i32 { +LL | fn h<'a>(a: &'a bool, b: bool, c: &'a S, d: &'a i32) -> &'a i32 { | ^^^^ ^^^^^^^^ ^^^^^ ^^^^^^^ ^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 638c8b8612cf2..b81ce552b3908 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -19,7 +19,7 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'r>(_x: &'r isize, _y: &'r isize) -> &'r isize { +LL | fn g<'a>(_x: &'a isize, _y: &'a isize) -> &'a isize { | ^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^ error[E0106]: missing lifetime specifier @@ -35,7 +35,7 @@ LL | fn h(_x: &Foo) -> &isize { | ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'r>(_x: &'r Foo) -> &'r isize { +LL | fn h<'a>(_x: &'a Foo) -> &'a isize { | ^^^^ ^^^^^^^ ^^^ error[E0106]: missing lifetime specifier diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index e1982ea393ef4..47b048a7a9779 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -11,7 +11,7 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'r>(x: &'r i32, y: &'r i32) -> &'r i32 { +LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ^^^^ ^^^^^^^ ^^^^^^^ ^^^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr index be33f2e2f7695..27f7639d213d2 100644 --- a/src/test/ui/proc-macro/item-error.stderr +++ b/src/test/ui/proc-macro/item-error.stderr @@ -6,8 +6,8 @@ LL | a: &u64 | help: consider introducing a named lifetime parameter | -LL | struct A<'r> { -LL | a: &'r u64 +LL | struct A<'a> { +LL | a: &'a u64 | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr index 46555df59367e..b3649c5b48530 100644 --- a/src/test/ui/regions/regions-in-enums-anon.stderr +++ b/src/test/ui/regions/regions-in-enums-anon.stderr @@ -6,8 +6,8 @@ LL | Bar(&isize) | help: consider introducing a named lifetime parameter | -LL | enum Foo<'r> { -LL | Bar(&'r isize) +LL | enum Foo<'a> { +LL | Bar(&'a isize) | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr index e807810db26fb..60a6fb9a0fad9 100644 --- a/src/test/ui/regions/regions-in-structs-anon.stderr +++ b/src/test/ui/regions/regions-in-structs-anon.stderr @@ -6,8 +6,8 @@ LL | x: &isize | help: consider introducing a named lifetime parameter | -LL | struct Foo<'r> { -LL | x: &'r isize +LL | struct Foo<'a> { +LL | x: &'a isize | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index cb72d1ec9bc71..498667abe36d9 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -89,12 +89,12 @@ error[E0261]: use of undeclared lifetime name `'b` LL | ... &'b isize, | ^^ undeclared lifetime | - = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, | ^^^^ -help: consider introducing a Higher-Ranked lifetime `'b` here +help: consider introducing a higher-ranked lifetime `'b` here | LL | b: Box FnOnce(&'a isize, | ^^^^ @@ -105,12 +105,12 @@ error[E0261]: use of undeclared lifetime name `'b` LL | ... &'b isize)>, | ^^ undeclared lifetime | - = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, | ^^^^ -help: consider introducing a Higher-Ranked lifetime `'b` here +help: consider introducing a higher-ranked lifetime `'b` here | LL | b: Box FnOnce(&'a isize, | ^^^^ diff --git a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr index c1a40ebc89286..858f23f1362cc 100644 --- a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr +++ b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr @@ -4,12 +4,12 @@ error[E0261]: use of undeclared lifetime name `'a` LL | struct S1 &'a i32>(F); | ^^ undeclared lifetime | - = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'a` here | LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F); | ^^^ -help: consider introducing a Higher-Ranked lifetime `'a` here +help: consider introducing a higher-ranked lifetime `'a` here | LL | struct S1 Fn(&i32, &i32) -> &'a i32>(F); | ^^^^^^^ @@ -25,14 +25,14 @@ help: this function's return type contains a borrowed value, but the signature d | LL | struct S2 &i32>(F); | ^^^^ ^^^^ - = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html -help: consider introducing a Higher-Ranked lifetime + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing a higher-ranked lifetime | -LL | struct S2 Fn(&'r i32, &'r i32) -> &'r i32>(F); +LL | struct S2 Fn(&'a i32, &'a i32) -> &'a i32>(F); | ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | struct S2<'r, F: Fn(&'r i32, &'r i32) -> &'r i32>(F); +LL | struct S2<'a, F: Fn(&'a i32, &'a i32) -> &'a i32>(F); | ^^^ ^^^^^^^ ^^^^^^^ ^^^ error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 459000a3722ca..2431e8ece3807 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -11,7 +11,7 @@ LL | let _: dyn Foo(&isize, &usize) -> &usize; | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn main<'r>() { +LL | fn main<'a>() { LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, LL | dyn Foo(&isize) -> &isize >(); LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index d0efd788dc1a9..fe242e6a909e3 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -6,8 +6,8 @@ LL | x: Box, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'r> { -LL | x: Box, +LL | struct Foo<'a> { +LL | x: Box, | error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index 998028622c265..0e410e25ecf25 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -11,7 +11,7 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'r>(x: &'r u32, y: &'r u32) -> &'r u32 { loop { } } +LL | fn foo<'a>(x: &'a u32, y: &'a u32) -> &'a u32 { loop { } } | ^^^^ ^^^^^^^ ^^^^^^^ ^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr index 406e0a92013d4..4275cc26f735f 100644 --- a/src/test/ui/underscore-lifetime/in-struct.stderr +++ b/src/test/ui/underscore-lifetime/in-struct.stderr @@ -6,8 +6,8 @@ LL | x: &'_ u32, | help: consider introducing a named lifetime parameter | -LL | struct Foo<'r> { -LL | x: &'r u32, +LL | struct Foo<'a> { +LL | x: &'a u32, | error[E0106]: missing lifetime specifier @@ -18,8 +18,8 @@ LL | Variant(&'_ u32), | help: consider introducing a named lifetime parameter | -LL | enum Bar<'r> { -LL | Variant(&'r u32), +LL | enum Bar<'a> { +LL | Variant(&'a u32), | error: aborting due to 2 previous errors diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 94f3499df5f26..f2eab86ae57ad 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -37,7 +37,7 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo2<'r>(_: &'_ u8, y: &'_ u8) -> &'r u8 { y } +LL | fn foo2<'a>(_: &'_ u8, y: &'_ u8) -> &'a u8 { y } | ^^^^ ^^ error: aborting due to 5 previous errors From ba3b44c508b133829f7b6a57f3e62c0735a7d110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 14:35:20 -0800 Subject: [PATCH 0933/1253] Account for `'_` in suggestions --- src/librustc_resolve/diagnostics.rs | 3 +++ .../ui/underscore-lifetime/underscore-lifetime-binders.stderr | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b62c9f4747c0b..3b689f03b43ba 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1521,6 +1521,9 @@ crate fn add_missing_lifetime_specifiers_label( if snippet.starts_with("&") && !snippet.starts_with("&'") { introduce_suggestion .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[4..]))); } } } diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index f2eab86ae57ad..d0eda1b615381 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -37,8 +37,8 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo2<'a>(_: &'_ u8, y: &'_ u8) -> &'a u8 { y } - | ^^^^ ^^ +LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y } + | ^^^^ ^^^^^^ ^^^^^^ ^^ error: aborting due to 5 previous errors From 92505df338a860f1055241a07949de2af7ddc6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 16:13:45 -0800 Subject: [PATCH 0934/1253] Account for `fn()` types in lifetime suggestions --- src/librustc_resolve/diagnostics.rs | 24 +++++-- src/librustc_resolve/lifetimes.rs | 64 ++++++++++++------- .../async-await/issues/issue-63388-2.stderr | 8 +-- .../ui/generic/generic-extern-lifetime.stderr | 12 ++++ .../no_introducing_in_band_in_locals.stderr | 12 +++- src/test/ui/issues/issue-19707.stderr | 21 +++--- src/test/ui/issues/issue-26638.stderr | 8 +-- src/test/ui/issues/issue-30255.stderr | 24 ++----- ...urn-type-requires-explicit-lifetime.stderr | 16 ++--- .../ex1b-return-no-names-if-else.stderr | 8 +-- .../ui/regions/regions-name-undeclared.stderr | 4 +- src/test/ui/rfc1623-2.rs | 13 ++++ src/test/ui/rfc1623-2.stderr | 29 +++++++++ src/test/ui/rfc1623.rs | 13 ++-- src/test/ui/rfc1623.stderr | 55 ++++++++++------ .../fn-missing-lifetime-in-item.stderr | 12 ++-- .../return-without-lifetime.stderr | 16 ++--- ...oxed-closure-sugar-lifetime-elision.stderr | 8 +-- .../in-fn-return-illegal.stderr | 8 +-- .../underscore-lifetime-binders.stderr | 8 +-- 20 files changed, 210 insertions(+), 153 deletions(-) create mode 100644 src/test/ui/rfc1623-2.rs create mode 100644 src/test/ui/rfc1623-2.stderr diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 3b689f03b43ba..8213a99a92d1e 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -19,7 +19,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{ElisionFailureInfo, HRLTSpanType, MissingLifetimeSpot}; +use crate::lifetimes::{ElisionFailureInfo, ForLifetimeSpanType, MissingLifetimeSpot}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1495,7 +1495,7 @@ crate fn add_missing_lifetime_specifiers_label( let should_break; introduce_suggestion.push(match missing { MissingLifetimeSpot::Generics(generics) => { - msg = "consider introducing a named lifetime parameter"; + msg = "consider introducing a named lifetime parameter".to_string(); should_break = true; match &generics.params { [] => (generics.span, "<'a>".to_string()), @@ -1503,15 +1503,27 @@ crate fn add_missing_lifetime_specifiers_label( } } MissingLifetimeSpot::HRLT { span, span_type } => { - msg = "consider introducing a higher-ranked lifetime"; + msg = format!( + "consider making the {} lifetime-generic with a new `'a` lifetime", + match span_type { + ForLifetimeSpanType::BoundEmpty + | ForLifetimeSpanType::BoundTail => "bound", + ForLifetimeSpanType::TypeEmpty | ForLifetimeSpanType::TypeTail => + "type", + } + ); should_break = false; err.note( "for more information on higher-ranked lifetimes, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); let suggestion = match span_type { - HRLTSpanType::Empty => "for<'a> ", - HRLTSpanType::Tail => ", 'a", + ForLifetimeSpanType::BoundEmpty | ForLifetimeSpanType::TypeEmpty => { + "for<'a> " + } + ForLifetimeSpanType::BoundTail | ForLifetimeSpanType::TypeTail => { + ", 'a" + } }; (*span, suggestion.to_string()) } @@ -1528,7 +1540,7 @@ crate fn add_missing_lifetime_specifiers_label( } } introduce_suggestion.push((span, sugg.to_string())); - err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect); + err.multipart_suggestion(&msg, introduce_suggestion, Applicability::MaybeIncorrect); if should_break { break; } diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 69deffe4a4c9a..9bb852b2093aa 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -155,12 +155,14 @@ struct NamedRegionMap { crate enum MissingLifetimeSpot<'tcx> { Generics(&'tcx hir::Generics<'tcx>), - HRLT { span: Span, span_type: HRLTSpanType }, + HRLT { span: Span, span_type: ForLifetimeSpanType }, } -crate enum HRLTSpanType { - Empty, - Tail, +crate enum ForLifetimeSpanType { + BoundEmpty, + BoundTail, + TypeEmpty, + TypeTail, } impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { @@ -509,6 +511,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let next_early_index = self.next_early_index(); let was_in_fn_syntax = self.is_in_fn_syntax; self.is_in_fn_syntax = true; + let lifetime_span: Option = c + .generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(param.span), + _ => None, + }) + .last(); + let (span, span_type) = if let Some(span) = lifetime_span { + (span.shrink_to_hi(), ForLifetimeSpanType::TypeTail) + } else { + (ty.span.shrink_to_lo(), ForLifetimeSpanType::TypeEmpty) + }; + self.missing_named_lifetime_spots + .push(MissingLifetimeSpot::HRLT { span, span_type }); let scope = Scope::Binder { lifetimes: c .generic_params @@ -531,6 +548,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.check_lifetime_params(old_scope, &c.generic_params); intravisit::walk_ty(this, ty); }); + self.missing_named_lifetime_spots.pop(); self.is_in_fn_syntax = was_in_fn_syntax; } hir::TyKind::TraitObject(bounds, ref lifetime) => { @@ -1873,12 +1891,23 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { err.span_suggestion( *span, &format!( - "consider introducing a higher-ranked lifetime `{}` here", + "consider making the {} lifetime-generic with a new `{}` lifetime", + match span_type { + ForLifetimeSpanType::BoundEmpty + | ForLifetimeSpanType::BoundTail => "bound", + ForLifetimeSpanType::TypeEmpty + | ForLifetimeSpanType::TypeTail => "type", + }, lifetime_ref ), match span_type { - HRLTSpanType::Empty => format!("for<{}> ", lifetime_ref), - HRLTSpanType::Tail => format!(", {}", lifetime_ref), + ForLifetimeSpanType::TypeEmpty + | ForLifetimeSpanType::BoundEmpty => { + format!("for<{}> ", lifetime_ref) + } + ForLifetimeSpanType::TypeTail | ForLifetimeSpanType::BoundTail => { + format!(", {}", lifetime_ref) + } } .to_string(), Applicability::MaybeIncorrect, @@ -2487,13 +2516,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { params.iter().cloned().filter(|info| info.lifetime_count > 0).collect(); let elided_len = elided_params.len(); - let mut spans = vec![]; for (i, info) in elided_params.into_iter().enumerate() { let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; - spans.push(span); + db.span_label(span, ""); let help_name = if let Some(ident) = parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident()) { @@ -2524,14 +2552,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - let help = |msg| { - if spans.is_empty() { - db.help(msg); - } else { - db.span_help(spans, msg); - } - }; - if len == 0 { db.help( "this function's return type contains a borrowed value, \ @@ -2539,7 +2559,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ); self.suggest_lifetime(db, span, "consider giving it a 'static lifetime") } else if elided_len == 0 { - help( + db.help( "this function's return type contains a borrowed value with \ an elided lifetime, but the lifetime cannot be derived from \ the arguments", @@ -2547,14 +2567,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let msg = "consider giving it an explicit bounded or 'static lifetime"; self.suggest_lifetime(db, span, msg) } else if elided_len == 1 { - help(&format!( + db.help(&format!( "this function's return type contains a borrowed value, \ but the signature does not say which {} it is borrowed from", m )); true } else { - help(&format!( + db.help(&format!( "this function's return type contains a borrowed value, \ but the signature does not say whether it is borrowed from {}", m @@ -2816,8 +2836,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .contains(&Some(did)) { let (span, span_type) = match &trait_ref.bound_generic_params { - [] => (trait_ref.span.shrink_to_lo(), HRLTSpanType::Empty), - [.., bound] => (bound.span.shrink_to_hi(), HRLTSpanType::Tail), + [] => (trait_ref.span.shrink_to_lo(), ForLifetimeSpanType::BoundEmpty), + [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), }; self.missing_named_lifetime_spots .push(MissingLifetimeSpot::HRLT { span, span_type }); diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index a12c601b936af..9f51ced9c3f49 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -1,14 +1,12 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-63388-2.rs:12:10 | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | -------- ----------- LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` - --> $DIR/issue-63388-2.rs:11:14 - | -LL | foo: &dyn Foo, bar: &'a dyn Foo - | ^^^^^^^^ ^^^^^^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` error: cannot infer an appropriate lifetime --> $DIR/issue-63388-2.rs:11:9 diff --git a/src/test/ui/generic/generic-extern-lifetime.stderr b/src/test/ui/generic/generic-extern-lifetime.stderr index 39372c9315831..5e25952390b2d 100644 --- a/src/test/ui/generic/generic-extern-lifetime.stderr +++ b/src/test/ui/generic/generic-extern-lifetime.stderr @@ -9,12 +9,24 @@ error[E0261]: use of undeclared lifetime name `'a` | LL | pub fn life4<'b>(x: for<'c> fn(&'a i32)); | ^^ undeclared lifetime + | + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | pub fn life4<'b>(x: for<'c, 'a> fn(&'a i32)); + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/generic-extern-lifetime.rs:11:38 | LL | pub fn life7<'b>() -> for<'c> fn(&'a i32); | ^^ undeclared lifetime + | + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | pub fn life7<'b>() -> for<'c, 'a> fn(&'a i32); + | ^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index 7d71230e16210..5abaf3c3aefff 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -9,10 +9,18 @@ LL | let y: &'test u32 = x; error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_introducing_in_band_in_locals.rs:10:16 | -LL | fn bar() { - | - help: consider introducing lifetime `'test` here: `<'test>` LL | let y: fn(&'test u32) = foo2; | ^^^^^ undeclared lifetime + | + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing lifetime `'test` here + | +LL | fn bar<'test>() { + | ^^^^^^^ +help: consider making the type lifetime-generic with a new `'test` lifetime + | +LL | let y: for<'test> fn(&'test u32) = foo2; + | ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index e84bfb969d4f9..398e97a6f207a 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -2,13 +2,14 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:3:28 | LL | type Foo = fn(&u8, &u8) -> &u8; - | ^ expected named lifetime parameter + | --- --- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/issue-19707.rs:3:15 + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime | -LL | type Foo = fn(&u8, &u8) -> &u8; - | ^^^ ^^^ +LL | type Foo = for<'a> fn(&'a u8, &'a u8) -> &'a u8; + | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ help: consider introducing a named lifetime parameter | LL | type Foo<'a> = fn(&'a u8, &'a u8) -> &'a u8; @@ -18,15 +19,11 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 | LL | fn bar &u8>(f: &F) {} - | ^ expected named lifetime parameter + | --- --- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/issue-19707.rs:5:14 - | -LL | fn bar &u8>(f: &F) {} - | ^^^ ^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html -help: consider introducing a higher-ranked lifetime +help: consider making the bound lifetime-generic with a new `'a` lifetime | LL | fn bar Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {} | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 75cd5332fd9a4..1d8fbdc63c5e0 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -2,13 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:1:62 | LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } - | ^ expected named lifetime parameter + | ------------------------------------ ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from - --> $DIR/issue-26638.rs:1:21 - | -LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from help: consider introducing a named lifetime parameter | LL | fn parse_type<'a>(iter: Box+'static>) -> &'a str { iter.next() } diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index 3c26365d5d168..ab43d4a3c6002 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -2,13 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:9:24 | LL | fn f(a: &S, b: i32) -> &i32 { - | ^ expected named lifetime parameter + | -- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from - --> $DIR/issue-30255.rs:9:9 - | -LL | fn f(a: &S, b: i32) -> &i32 { - | ^^ + = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from help: consider introducing a named lifetime parameter | LL | fn f<'a>(a: &'a S, b: i32) -> &'a i32 { @@ -18,13 +14,9 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 | LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { - | ^ expected named lifetime parameter - | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` - --> $DIR/issue-30255.rs:14:9 + | -- ---- ^ expected named lifetime parameter | -LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { - | ^^ ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` help: consider introducing a named lifetime parameter | LL | fn g<'a>(a: &'a S, b: bool, c: &'a i32) -> &'a i32 { @@ -34,13 +26,9 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 | LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { - | ^ expected named lifetime parameter - | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` - --> $DIR/issue-30255.rs:19:9 + | ----- -- ---- ^ expected named lifetime parameter | -LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { - | ^^^^^ ^^ ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` help: consider introducing a named lifetime parameter | LL | fn h<'a>(a: &'a bool, b: bool, c: &'a S, d: &'a i32) -> &'a i32 { diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index b81ce552b3908..461c1832e9af9 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -10,13 +10,9 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33 | LL | fn g(_x: &isize, _y: &isize) -> &isize { - | ^ expected named lifetime parameter + | ------ ------ ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` - --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:10 - | -LL | fn g(_x: &isize, _y: &isize) -> &isize { - | ^^^^^^ ^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` help: consider introducing a named lifetime parameter | LL | fn g<'a>(_x: &'a isize, _y: &'a isize) -> &'a isize { @@ -26,13 +22,9 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 | LL | fn h(_x: &Foo) -> &isize { - | ^ expected named lifetime parameter + | ---- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from - --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:10 - | -LL | fn h(_x: &Foo) -> &isize { - | ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from help: consider introducing a named lifetime parameter | LL | fn h<'a>(_x: &'a Foo) -> &'a isize { diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index 47b048a7a9779..c1fcab2409f64 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -2,13 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/ex1b-return-no-names-if-else.rs:1:29 | LL | fn foo(x: &i32, y: &i32) -> &i32 { - | ^ expected named lifetime parameter + | ---- ---- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` - --> $DIR/ex1b-return-no-names-if-else.rs:1:11 - | -LL | fn foo(x: &i32, y: &i32) -> &i32 { - | ^^^^ ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` help: consider introducing a named lifetime parameter | LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index 498667abe36d9..e139e3f425189 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -94,7 +94,7 @@ help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, | ^^^^ -help: consider introducing a higher-ranked lifetime `'b` here +help: consider making the bound lifetime-generic with a new `'b` lifetime | LL | b: Box FnOnce(&'a isize, | ^^^^ @@ -110,7 +110,7 @@ help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, | ^^^^ -help: consider introducing a higher-ranked lifetime `'b` here +help: consider making the bound lifetime-generic with a new `'b` lifetime | LL | b: Box FnOnce(&'a isize, | ^^^^ diff --git a/src/test/ui/rfc1623-2.rs b/src/test/ui/rfc1623-2.rs new file mode 100644 index 0000000000000..35a2ef10c2e3c --- /dev/null +++ b/src/test/ui/rfc1623-2.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} + +// the boundaries of elision +static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = +//~^ ERROR missing lifetime specifier [E0106] + &(non_elidable as fn(&u8, &u8) -> &u8); + //~^ ERROR missing lifetime specifier [E0106] + +fn main() {} diff --git a/src/test/ui/rfc1623-2.stderr b/src/test/ui/rfc1623-2.stderr new file mode 100644 index 0000000000000..c927ad9e0ba4b --- /dev/null +++ b/src/test/ui/rfc1623-2.stderr @@ -0,0 +1,29 @@ +error[E0106]: missing lifetime specifier + --> $DIR/rfc1623-2.rs:8:42 + | +LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = + | --- --- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = + | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ + +error[E0106]: missing lifetime specifier + --> $DIR/rfc1623-2.rs:10:39 + | +LL | &(non_elidable as fn(&u8, &u8) -> &u8); + | --- --- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); + | ^^^^^^^ ^^^^^^ ^^^^^^ ^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfc1623.rs index ebb4d56af9eec..55f5d0b94dcb0 100644 --- a/src/test/ui/rfc1623.rs +++ b/src/test/ui/rfc1623.rs @@ -4,11 +4,10 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } -// the boundaries of elision -static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = -//~^ ERROR missing lifetime specifier [E0106] - &(non_elidable as fn(&u8, &u8) -> &u8); - //~^ ERROR missing lifetime specifier [E0106] +// The incorrect case without `for<'a>` is tested for in `rfc1623-2.rs` +static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = + &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); + struct SomeStruct<'x, 'y, 'z: 'x> { foo: &'x Foo<'z>, @@ -20,10 +19,12 @@ fn id(t: T) -> T { t } -static SOME_STRUCT: &SomeStruct = SomeStruct { +static SOME_STRUCT: &SomeStruct = SomeStruct { //~ ERROR mismatched types foo: &Foo { bools: &[false, true] }, bar: &Bar { bools: &[true, true] }, f: &id, + //~^ ERROR type mismatch in function arguments + //~| ERROR type mismatch resolving }; // very simple test for a 'static static with default lifetime diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index aabe088d63ca6..ca956004ef76f 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -1,27 +1,46 @@ -error[E0106]: missing lifetime specifier - --> $DIR/rfc1623.rs:8:42 +error[E0308]: mismatched types + --> $DIR/rfc1623.rs:22:35 | -LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = - | ^ expected named lifetime parameter +LL | static SOME_STRUCT: &SomeStruct = SomeStruct { + | ___________________________________^ +LL | | foo: &Foo { bools: &[false, true] }, +LL | | bar: &Bar { bools: &[true, true] }, +LL | | f: &id, +LL | | +LL | | +LL | | }; + | |_^ expected `&SomeStruct<'static, 'static, 'static>`, found struct `SomeStruct` | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/rfc1623.rs:8:29 +help: consider borrowing here | -LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = - | ^^^ ^^^ +LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { +LL | foo: &Foo { bools: &[false, true] }, +LL | bar: &Bar { bools: &[true, true] }, +LL | f: &id, +LL | +LL | + ... -error[E0106]: missing lifetime specifier - --> $DIR/rfc1623.rs:10:39 +error[E0631]: type mismatch in function arguments + --> $DIR/rfc1623.rs:25:8 | -LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^ expected named lifetime parameter +LL | fn id(t: T) -> T { + | ------------------- found signature of `fn(_) -> _` +... +LL | f: &id, + | ^^^ expected signature of `for<'a, 'b> fn(&'a Foo<'b>) -> _` | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/rfc1623.rs:10:26 + = note: required for the cast to the object type `dyn for<'a, 'b> std::ops::Fn(&'a Foo<'b>) -> &'a Foo<'b>` + +error[E0271]: type mismatch resolving `for<'a, 'b> _ {id::<_>} as std::ops::FnOnce<(&'a Foo<'b>,)>>::Output == &'a Foo<'b>` + --> $DIR/rfc1623.rs:25:8 + | +LL | f: &id, + | ^^^ expected bound lifetime parameter 'a, found concrete lifetime | -LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^^^ ^^^ + = note: required for the cast to the object type `dyn for<'a, 'b> std::ops::Fn(&'a Foo<'b>) -> &'a Foo<'b>` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0106`. +Some errors have detailed explanations: E0271, E0308, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr index 858f23f1362cc..66913a3c544b3 100644 --- a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr +++ b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr @@ -9,7 +9,7 @@ help: consider introducing lifetime `'a` here | LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F); | ^^^ -help: consider introducing a higher-ranked lifetime `'a` here +help: consider making the bound lifetime-generic with a new `'a` lifetime | LL | struct S1 Fn(&i32, &i32) -> &'a i32>(F); | ^^^^^^^ @@ -18,15 +18,11 @@ error[E0106]: missing lifetime specifier --> $DIR/fn-missing-lifetime-in-item.rs:2:32 | LL | struct S2 &i32>(F); - | ^ expected named lifetime parameter + | ---- ---- ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/fn-missing-lifetime-in-item.rs:2:17 - | -LL | struct S2 &i32>(F); - | ^^^^ ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html -help: consider introducing a higher-ranked lifetime +help: consider making the bound lifetime-generic with a new `'a` lifetime | LL | struct S2 Fn(&'a i32, &'a i32) -> &'a i32>(F); | ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^ diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 3b7936c5f44b6..ce3b1748da435 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -8,25 +8,17 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:5:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime: `&'a` + | --------- ^ help: consider using the named lifetime: `&'a` | -help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from - --> $DIR/return-without-lifetime.rs:5:20 - | -LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } - | ^^^^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:7:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime: `&'a` + | ---------- ^ help: consider using the named lifetime: `&'a` | -help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from - --> $DIR/return-without-lifetime.rs:7:20 - | -LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } - | ^^^^^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 2431e8ece3807..1719a99d421d0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -2,13 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:39 | LL | let _: dyn Foo(&isize, &usize) -> &usize; - | ^ expected named lifetime parameter + | ------ ------ ^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:20 - | -LL | let _: dyn Foo(&isize, &usize) -> &usize; - | ^^^^^^ ^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 help: consider introducing a named lifetime parameter | LL | fn main<'a>() { diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index 0e410e25ecf25..8d2c82e59edc1 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -2,13 +2,9 @@ error[E0106]: missing lifetime specifier --> $DIR/in-fn-return-illegal.rs:5:30 | LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } - | ^^ expected named lifetime parameter + | ---- ---- ^^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` - --> $DIR/in-fn-return-illegal.rs:5:11 - | -LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } - | ^^^^ ^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` help: consider introducing a named lifetime parameter | LL | fn foo<'a>(x: &'a u32, y: &'a u32) -> &'a u32 { loop { } } diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index d0eda1b615381..c7cda38e47691 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -28,13 +28,9 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:16:35 | LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } - | ^^ expected named lifetime parameter + | ------ ------ ^^ expected named lifetime parameter | -help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` - --> $DIR/underscore-lifetime-binders.rs:16:12 - | -LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } - | ^^^^^^ ^^^^^^ + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` help: consider introducing a named lifetime parameter | LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y } From 30d927874a06d552c56c298fecb90d2af7444ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 16:25:43 -0800 Subject: [PATCH 0935/1253] review comments: wording --- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/lifetimes.rs | 2 +- src/test/ui/generic/generic-extern-lifetime.stderr | 4 ++-- .../in-band-lifetimes/no_introducing_in_band_in_locals.stderr | 2 +- src/test/ui/issues/issue-19707.stderr | 4 ++-- src/test/ui/regions/regions-name-undeclared.stderr | 4 ++-- src/test/ui/rfc1623-2.stderr | 4 ++-- src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 8213a99a92d1e..c254207cc3e7c 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1514,7 +1514,7 @@ crate fn add_missing_lifetime_specifiers_label( ); should_break = false; err.note( - "for more information on higher-ranked lifetimes, visit \ + "for more information on higher-ranked polymorphism, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); let suggestion = match span_type { diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 9bb852b2093aa..b69eea6634b5a 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -1913,7 +1913,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Applicability::MaybeIncorrect, ); err.note( - "for more information on higher-ranked lifetimes, visit \ + "for more information on higher-ranked polymorphism, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); } diff --git a/src/test/ui/generic/generic-extern-lifetime.stderr b/src/test/ui/generic/generic-extern-lifetime.stderr index 5e25952390b2d..72951aea4aaf0 100644 --- a/src/test/ui/generic/generic-extern-lifetime.stderr +++ b/src/test/ui/generic/generic-extern-lifetime.stderr @@ -10,7 +10,7 @@ error[E0261]: use of undeclared lifetime name `'a` LL | pub fn life4<'b>(x: for<'c> fn(&'a i32)); | ^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the type lifetime-generic with a new `'a` lifetime | LL | pub fn life4<'b>(x: for<'c, 'a> fn(&'a i32)); @@ -22,7 +22,7 @@ error[E0261]: use of undeclared lifetime name `'a` LL | pub fn life7<'b>() -> for<'c> fn(&'a i32); | ^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the type lifetime-generic with a new `'a` lifetime | LL | pub fn life7<'b>() -> for<'c, 'a> fn(&'a i32); diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index 5abaf3c3aefff..a43b49041ec2a 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -12,7 +12,7 @@ error[E0261]: use of undeclared lifetime name `'test` LL | let y: fn(&'test u32) = foo2; | ^^^^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'test` here | LL | fn bar<'test>() { diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 398e97a6f207a..337f2f971ede0 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -5,7 +5,7 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | --- --- ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the type lifetime-generic with a new `'a` lifetime | LL | type Foo = for<'a> fn(&'a u8, &'a u8) -> &'a u8; @@ -22,7 +22,7 @@ LL | fn bar &u8>(f: &F) {} | --- --- ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the bound lifetime-generic with a new `'a` lifetime | LL | fn bar Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {} diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index e139e3f425189..eb19a30c52b97 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -89,7 +89,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | ... &'b isize, | ^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, @@ -105,7 +105,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | ... &'b isize)>, | ^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, diff --git a/src/test/ui/rfc1623-2.stderr b/src/test/ui/rfc1623-2.stderr index c927ad9e0ba4b..732bb61e6eebb 100644 --- a/src/test/ui/rfc1623-2.stderr +++ b/src/test/ui/rfc1623-2.stderr @@ -5,7 +5,7 @@ LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = | --- --- ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the type lifetime-generic with a new `'a` lifetime | LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = @@ -18,7 +18,7 @@ LL | &(non_elidable as fn(&u8, &u8) -> &u8); | --- --- ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the type lifetime-generic with a new `'a` lifetime | LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); diff --git a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr index 66913a3c544b3..fe9c3445fc46f 100644 --- a/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr +++ b/src/test/ui/suggestions/fn-missing-lifetime-in-item.stderr @@ -4,7 +4,7 @@ error[E0261]: use of undeclared lifetime name `'a` LL | struct S1 &'a i32>(F); | ^^ undeclared lifetime | - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing lifetime `'a` here | LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F); @@ -21,7 +21,7 @@ LL | struct S2 &i32>(F); | ---- ---- ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 - = note: for more information on higher-ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider making the bound lifetime-generic with a new `'a` lifetime | LL | struct S2 Fn(&'a i32, &'a i32) -> &'a i32>(F); From 49f9bf897b93349464c2046047991b3e77ca0f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jan 2020 17:33:13 -0800 Subject: [PATCH 0936/1253] review comments --- src/librustc_resolve/diagnostics.rs | 21 +++------------ src/librustc_resolve/lifetimes.rs | 42 +++++++++++++++-------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index c254207cc3e7c..be7a9de4317c5 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -19,7 +19,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{ElisionFailureInfo, ForLifetimeSpanType, MissingLifetimeSpot}; +use crate::lifetimes::{ElisionFailureInfo, MissingLifetimeSpot}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1502,30 +1502,17 @@ crate fn add_missing_lifetime_specifiers_label( [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), } } - MissingLifetimeSpot::HRLT { span, span_type } => { + MissingLifetimeSpot::HigherRanked { span, span_type } => { msg = format!( "consider making the {} lifetime-generic with a new `'a` lifetime", - match span_type { - ForLifetimeSpanType::BoundEmpty - | ForLifetimeSpanType::BoundTail => "bound", - ForLifetimeSpanType::TypeEmpty | ForLifetimeSpanType::TypeTail => - "type", - } + span_type.descr(), ); should_break = false; err.note( "for more information on higher-ranked polymorphism, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", ); - let suggestion = match span_type { - ForLifetimeSpanType::BoundEmpty | ForLifetimeSpanType::TypeEmpty => { - "for<'a> " - } - ForLifetimeSpanType::BoundTail | ForLifetimeSpanType::TypeTail => { - ", 'a" - } - }; - (*span, suggestion.to_string()) + (*span, span_type.suggestion("'a")) } }); for param in params { diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index b69eea6634b5a..811b36022a5b9 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -155,7 +155,7 @@ struct NamedRegionMap { crate enum MissingLifetimeSpot<'tcx> { Generics(&'tcx hir::Generics<'tcx>), - HRLT { span: Span, span_type: ForLifetimeSpanType }, + HigherRanked { span: Span, span_type: ForLifetimeSpanType }, } crate enum ForLifetimeSpanType { @@ -165,6 +165,22 @@ crate enum ForLifetimeSpanType { TypeTail, } +impl ForLifetimeSpanType { + crate fn descr(&self) -> &'static str { + match self { + Self::BoundEmpty | Self::BoundTail => "bound", + Self::TypeEmpty | Self::TypeTail => "type", + } + } + + crate fn suggestion(&self, sugg: &str) -> String { + match self { + Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg), + Self::BoundTail | Self::TypeTail => format!(", {}", sugg), + } + } +} + impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { fn into(self) -> MissingLifetimeSpot<'tcx> { MissingLifetimeSpot::Generics(self) @@ -525,7 +541,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { (ty.span.shrink_to_lo(), ForLifetimeSpanType::TypeEmpty) }; self.missing_named_lifetime_spots - .push(MissingLifetimeSpot::HRLT { span, span_type }); + .push(MissingLifetimeSpot::HigherRanked { span, span_type }); let scope = Scope::Binder { lifetimes: c .generic_params @@ -1887,29 +1903,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - MissingLifetimeSpot::HRLT { span, span_type } => { + MissingLifetimeSpot::HigherRanked { span, span_type } => { err.span_suggestion( *span, &format!( "consider making the {} lifetime-generic with a new `{}` lifetime", - match span_type { - ForLifetimeSpanType::BoundEmpty - | ForLifetimeSpanType::BoundTail => "bound", - ForLifetimeSpanType::TypeEmpty - | ForLifetimeSpanType::TypeTail => "type", - }, + span_type.descr(), lifetime_ref ), - match span_type { - ForLifetimeSpanType::TypeEmpty - | ForLifetimeSpanType::BoundEmpty => { - format!("for<{}> ", lifetime_ref) - } - ForLifetimeSpanType::TypeTail | ForLifetimeSpanType::BoundTail => { - format!(", {}", lifetime_ref) - } - } - .to_string(), + span_type.suggestion(&lifetime_ref.to_string()), Applicability::MaybeIncorrect, ); err.note( @@ -2840,7 +2842,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), }; self.missing_named_lifetime_spots - .push(MissingLifetimeSpot::HRLT { span, span_type }); + .push(MissingLifetimeSpot::HigherRanked { span, span_type }); return true; } }; From 1beac2b774fa7081ad22f9856ebb6bb9d04297fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 28 Jan 2020 15:04:18 -0800 Subject: [PATCH 0937/1253] Move code to `diagnostics.rs` --- src/librustc_resolve/diagnostics.rs | 298 +++++++++++++++++++--------- src/librustc_resolve/lifetimes.rs | 116 +---------- 2 files changed, 214 insertions(+), 200 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index be7a9de4317c5..2732197f36125 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -8,6 +8,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; +use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -19,7 +20,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{ElisionFailureInfo, MissingLifetimeSpot}; +use crate::lifetimes::{ElisionFailureInfo, LifetimeContext}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -48,6 +49,40 @@ crate struct ImportSuggestion { pub path: Path, } +crate enum MissingLifetimeSpot<'tcx> { + Generics(&'tcx hir::Generics<'tcx>), + HigherRanked { span: Span, span_type: ForLifetimeSpanType }, +} + +crate enum ForLifetimeSpanType { + BoundEmpty, + BoundTail, + TypeEmpty, + TypeTail, +} + +impl ForLifetimeSpanType { + crate fn descr(&self) -> &'static str { + match self { + Self::BoundEmpty | Self::BoundTail => "bound", + Self::TypeEmpty | Self::TypeTail => "type", + } + } + + crate fn suggestion(&self, sugg: &str) -> String { + match self { + Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg), + Self::BoundTail | Self::TypeTail => format!(", {}", sugg), + } + } +} + +impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { + fn into(self) -> MissingLifetimeSpot<'tcx> { + MissingLifetimeSpot::Generics(self) + } +} + /// Adjust the impl span so that just the `impl` keyword is taken by removing /// everything after `<` (`"impl Iterator for A {}" -> "impl"`) and /// everything after the first whitespace (`"impl Iterator for A" -> "impl"`). @@ -1457,104 +1492,185 @@ crate fn show_candidates( } } -crate fn report_missing_lifetime_specifiers( - sess: &Session, - span: Span, - count: usize, -) -> DiagnosticBuilder<'_> { - struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count)) -} +impl<'tcx> LifetimeContext<'_, 'tcx> { + crate fn report_missing_lifetime_specifiers( + &self, + span: Span, + count: usize, + ) -> DiagnosticBuilder<'tcx> { + struct_span_err!( + self.tcx.sess, + span, + E0106, + "missing lifetime specifier{}", + pluralize!(count) + ) + } -crate fn add_missing_lifetime_specifiers_label( - err: &mut DiagnosticBuilder<'_>, - source_map: &SourceMap, - span: Span, - count: usize, - lifetime_names: &FxHashSet, - snippet: Option<&str>, - missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>], - params: &[ElisionFailureInfo], -) { - if count > 1 { - err.span_label(span, format!("expected {} lifetime parameters", count)); - } else { - let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { - err.span_suggestion( - span, - "consider using the named lifetime", - sugg, - Applicability::MaybeIncorrect, - ); + crate fn emit_undeclared_lifetime_error(&self, lifetime_ref: &hir::Lifetime) { + let mut err = struct_span_err!( + self.tcx.sess, + lifetime_ref.span, + E0261, + "use of undeclared lifetime name `{}`", + lifetime_ref + ); + err.span_label(lifetime_ref.span, "undeclared lifetime"); + for missing in &self.missing_named_lifetime_spots { + match missing { + MissingLifetimeSpot::Generics(generics) => { + let (span, sugg) = match &generics.params { + [] => (generics.span, format!("<{}>", lifetime_ref)), + [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), + }; + err.span_suggestion( + span, + &format!("consider introducing lifetime `{}` here", lifetime_ref), + sugg, + Applicability::MaybeIncorrect, + ); + } + MissingLifetimeSpot::HigherRanked { span, span_type } => { + err.span_suggestion( + *span, + &format!( + "consider making the {} lifetime-generic with a new `{}` lifetime", + span_type.descr(), + lifetime_ref + ), + span_type.suggestion(&lifetime_ref.to_string()), + Applicability::MaybeIncorrect, + ); + err.note( + "for more information on higher-ranked polymorphism, visit \ + https://doc.rust-lang.org/nomicon/hrtb.html", + ); + } + } + } + err.emit(); + } + + crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { + if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { + if [ + self.tcx.lang_items().fn_once_trait(), + self.tcx.lang_items().fn_trait(), + self.tcx.lang_items().fn_mut_trait(), + ] + .contains(&Some(did)) + { + let (span, span_type) = match &trait_ref.bound_generic_params { + [] => (trait_ref.span.shrink_to_lo(), ForLifetimeSpanType::BoundEmpty), + [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), + }; + self.missing_named_lifetime_spots + .push(MissingLifetimeSpot::HigherRanked { span, span_type }); + return true; + } }; - let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { - err.span_label(span, "expected named lifetime parameter"); - - for missing in missing_named_lifetime_spots.iter().rev() { - let mut introduce_suggestion = vec![]; - let msg; - let should_break; - introduce_suggestion.push(match missing { - MissingLifetimeSpot::Generics(generics) => { - msg = "consider introducing a named lifetime parameter".to_string(); - should_break = true; - match &generics.params { - [] => (generics.span, "<'a>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), + false + } + + crate fn add_missing_lifetime_specifiers_label( + &self, + err: &mut DiagnosticBuilder<'_>, + span: Span, + count: usize, + lifetime_names: &FxHashSet, + params: &[ElisionFailureInfo], + ) { + if count > 1 { + err.span_label(span, format!("expected {} lifetime parameters", count)); + } else { + let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok(); + let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_suggestion( + span, + "consider using the named lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + }; + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { + err.span_label(span, "expected named lifetime parameter"); + + for missing in self.missing_named_lifetime_spots.iter().rev() { + let mut introduce_suggestion = vec![]; + let msg; + let should_break; + introduce_suggestion.push(match missing { + MissingLifetimeSpot::Generics(generics) => { + msg = "consider introducing a named lifetime parameter".to_string(); + should_break = true; + match &generics.params { + [] => (generics.span, "<'a>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), + } } - } - MissingLifetimeSpot::HigherRanked { span, span_type } => { - msg = format!( - "consider making the {} lifetime-generic with a new `'a` lifetime", - span_type.descr(), - ); - should_break = false; - err.note( - "for more information on higher-ranked polymorphism, visit \ + MissingLifetimeSpot::HigherRanked { span, span_type } => { + msg = format!( + "consider making the {} lifetime-generic with a new `'a` lifetime", + span_type.descr(), + ); + should_break = false; + err.note( + "for more information on higher-ranked polymorphism, visit \ https://doc.rust-lang.org/nomicon/hrtb.html", - ); - (*span, span_type.suggestion("'a")) - } - }); - for param in params { - if let Ok(snippet) = source_map.span_to_snippet(param.span) { - if snippet.starts_with("&") && !snippet.starts_with("&'") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); + ); + (*span, span_type.suggestion("'a")) + } + }); + for param in params { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) + { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[4..]))); + } } } + introduce_suggestion.push((span, sugg.to_string())); + err.multipart_suggestion( + &msg, + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + if should_break { + break; + } } - introduce_suggestion.push((span, sugg.to_string())); - err.multipart_suggestion(&msg, introduce_suggestion, Applicability::MaybeIncorrect); - if should_break { - break; - } - } - }; + }; - match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { - (1, Some(name), Some("&")) => { - suggest_existing(err, format!("&{} ", name)); - } - (1, Some(name), Some("'_")) => { - suggest_existing(err, name.to_string()); - } - (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { - suggest_existing(err, format!("{}<{}>", snippet, name)); - } - (0, _, Some("&")) => { - suggest_new(err, "&'a "); - } - (0, _, Some("'_")) => { - suggest_new(err, "'a"); - } - (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, &format!("{}<'a>", snippet)); - } - _ => { - err.span_label(span, "expected lifetime parameter"); + match ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet.as_ref().map(|s| s.as_str()), + ) { + (1, Some(name), Some("&")) => { + suggest_existing(err, format!("&{} ", name)); + } + (1, Some(name), Some("'_")) => { + suggest_existing(err, name.to_string()); + } + (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { + suggest_existing(err, format!("{}<{}>", snippet, name)); + } + (0, _, Some("&")) => { + suggest_new(err, "&'a "); + } + (0, _, Some("'_")) => { + suggest_new(err, "'a"); + } + (0, _, Some(snippet)) if !snippet.ends_with(">") => { + suggest_new(err, &format!("{}<'a>", snippet)); + } + _ => { + err.span_label(span, "expected lifetime parameter"); + } } } } diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 811b36022a5b9..0ba9b4f17068e 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -5,9 +5,7 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. -use crate::diagnostics::{ - add_missing_lifetime_specifiers_label, report_missing_lifetime_specifiers, -}; +use crate::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::resolve_lifetime::*; @@ -153,42 +151,8 @@ struct NamedRegionMap { object_lifetime_defaults: HirIdMap>, } -crate enum MissingLifetimeSpot<'tcx> { - Generics(&'tcx hir::Generics<'tcx>), - HigherRanked { span: Span, span_type: ForLifetimeSpanType }, -} - -crate enum ForLifetimeSpanType { - BoundEmpty, - BoundTail, - TypeEmpty, - TypeTail, -} - -impl ForLifetimeSpanType { - crate fn descr(&self) -> &'static str { - match self { - Self::BoundEmpty | Self::BoundTail => "bound", - Self::TypeEmpty | Self::TypeTail => "type", - } - } - - crate fn suggestion(&self, sugg: &str) -> String { - match self { - Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg), - Self::BoundTail | Self::TypeTail => format!(", {}", sugg), - } - } -} - -impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { - fn into(self) -> MissingLifetimeSpot<'tcx> { - MissingLifetimeSpot::Generics(self) - } -} - -struct LifetimeContext<'a, 'tcx> { - tcx: TyCtxt<'tcx>, +crate struct LifetimeContext<'a, 'tcx> { + crate tcx: TyCtxt<'tcx>, map: &'a mut NamedRegionMap, scope: ScopeRef<'a>, @@ -220,7 +184,7 @@ struct LifetimeContext<'a, 'tcx> { /// When encountering an undefined named lifetime, we will suggest introducing it in these /// places. - missing_named_lifetime_spots: Vec>, + crate missing_named_lifetime_spots: Vec>, } #[derive(Debug)] @@ -1879,49 +1843,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, def); } else { - let mut err = struct_span_err!( - self.tcx.sess, - lifetime_ref.span, - E0261, - "use of undeclared lifetime name `{}`", - lifetime_ref - ); - err.span_label(lifetime_ref.span, "undeclared lifetime"); - for missing in &self.missing_named_lifetime_spots { - match missing { - MissingLifetimeSpot::Generics(generics) => { - let (span, sugg) = match &generics.params { - [] => (generics.span, format!("<{}>", lifetime_ref)), - [param, ..] => { - (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) - } - }; - err.span_suggestion( - span, - &format!("consider introducing lifetime `{}` here", lifetime_ref), - sugg, - Applicability::MaybeIncorrect, - ); - } - MissingLifetimeSpot::HigherRanked { span, span_type } => { - err.span_suggestion( - *span, - &format!( - "consider making the {} lifetime-generic with a new `{}` lifetime", - span_type.descr(), - lifetime_ref - ), - span_type.suggestion(&lifetime_ref.to_string()), - Applicability::MaybeIncorrect, - ); - err.note( - "for more information on higher-ranked polymorphism, visit \ - https://doc.rust-lang.org/nomicon/hrtb.html", - ); - } - } - } - err.emit(); + self.emit_undeclared_lifetime_error(lifetime_ref); } } @@ -2461,7 +2383,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } }; - let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len()); + let mut err = self.report_missing_lifetime_specifiers(span, lifetime_refs.len()); let mut add_label = true; if let Some(params) = error { @@ -2470,14 +2392,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label( + self.add_missing_lifetime_specifiers_label( &mut err, - self.tcx.sess.source_map(), span, lifetime_refs.len(), &lifetime_names, - self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), - &self.missing_named_lifetime_spots, error.map(|p| &p[..]).unwrap_or(&[]), ); } @@ -2827,27 +2746,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let old_value = self.map.defs.remove(&lifetime_ref.hir_id); assert_eq!(old_value, Some(bad_def)); } - - fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { - if let Res::Def(_, did) = trait_ref.trait_ref.path.res { - if [ - self.tcx.lang_items().fn_once_trait(), - self.tcx.lang_items().fn_trait(), - self.tcx.lang_items().fn_mut_trait(), - ] - .contains(&Some(did)) - { - let (span, span_type) = match &trait_ref.bound_generic_params { - [] => (trait_ref.span.shrink_to_lo(), ForLifetimeSpanType::BoundEmpty), - [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), - }; - self.missing_named_lifetime_spots - .push(MissingLifetimeSpot::HigherRanked { span, span_type }); - return true; - } - }; - false - } } /// Detects late-bound lifetimes and inserts them into From 96bbb0d67eee9cbe8565afd8b56d537c5937dd62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 Jan 2020 11:53:47 -0800 Subject: [PATCH 0938/1253] Account for `impl Trait` Address #49287 --- src/librustc_resolve/diagnostics.rs | 89 ++++++++++++------- .../impl-trait-missing-lifetime.rs | 2 + .../impl-trait-missing-lifetime.stderr | 14 +++ 3 files changed, 71 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/suggestions/impl-trait-missing-lifetime.rs create mode 100644 src/test/ui/suggestions/impl-trait-missing-lifetime.stderr diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 2732197f36125..075dca8f01d7b 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1519,9 +1519,21 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { for missing in &self.missing_named_lifetime_spots { match missing { MissingLifetimeSpot::Generics(generics) => { - let (span, sugg) = match &generics.params { - [] => (generics.span, format!("<{}>", lifetime_ref)), - [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), + let (span, sugg) = if let Some(param) = generics + .params + .iter() + .filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }) + .next() + { + (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) + } else { + (generics.span, format!("<{}>", lifetime_ref)) }; err.span_suggestion( span, @@ -1592,20 +1604,28 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { Applicability::MaybeIncorrect, ); }; - let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { - err.span_label(span, "expected named lifetime parameter"); - - for missing in self.missing_named_lifetime_spots.iter().rev() { - let mut introduce_suggestion = vec![]; - let msg; - let should_break; - introduce_suggestion.push(match missing { + let suggest_new = + |err: &mut DiagnosticBuilder<'_>, sugg: &str| { + err.span_label(span, "expected named lifetime parameter"); + + for missing in self.missing_named_lifetime_spots.iter().rev() { + let mut introduce_suggestion = vec![]; + let msg; + let should_break; + introduce_suggestion.push(match missing { MissingLifetimeSpot::Generics(generics) => { msg = "consider introducing a named lifetime parameter".to_string(); should_break = true; - match &generics.params { - [] => (generics.span, "<'a>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), + if let Some(param) = generics.params.iter().filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }).next() { + (param.span.shrink_to_lo(), "'a, ".to_string()) + } else { + (generics.span, "<'a>".to_string()) } } MissingLifetimeSpot::HigherRanked { span, span_type } => { @@ -1621,29 +1641,30 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { (*span, span_type.suggestion("'a")) } }); - for param in params { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) - { - if snippet.starts_with("&") && !snippet.starts_with("&'") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); + for param in params { + if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(param.span) + { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[4..]))); + } } } + introduce_suggestion.push((span, sugg.to_string())); + err.multipart_suggestion( + &msg, + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + if should_break { + break; + } } - introduce_suggestion.push((span, sugg.to_string())); - err.multipart_suggestion( - &msg, - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - if should_break { - break; - } - } - }; + }; match ( lifetime_names.len(), diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs new file mode 100644 index 0000000000000..22dc448c97ff0 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs @@ -0,0 +1,2 @@ +fn f(_: impl Iterator) {} //~ ERROR missing lifetime specifier +fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr new file mode 100644 index 0000000000000..e31f25ab60304 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr @@ -0,0 +1,14 @@ +error[E0106]: missing lifetime specifier + --> $DIR/impl-trait-missing-lifetime.rs:1:31 + | +LL | fn f(_: impl Iterator) {} + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn f<'a>(_: impl Iterator) {} + | ^^^^ ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`. From 609a37407f6fbaeae66500c840cedc81a50960be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 5 Feb 2020 10:59:14 -0800 Subject: [PATCH 0939/1253] Fix test --- src/test/ui/async-await/issues/issue-63388-2.nll.stderr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr index 7781af89deae2..6edb9e63d480a 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr @@ -1,6 +1,8 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-63388-2.rs:12:10 | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | -------- ----------- LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` | From c182461a20d1e81d9132d8ab1dd18db91908f3b8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 Feb 2020 23:03:03 +0100 Subject: [PATCH 0940/1253] clean E0271 explanation --- src/librustc_error_codes/error_codes/E0271.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0271.md b/src/librustc_error_codes/error_codes/E0271.md index 4078598b39415..31334069ed8a4 100644 --- a/src/librustc_error_codes/error_codes/E0271.md +++ b/src/librustc_error_codes/error_codes/E0271.md @@ -1,9 +1,6 @@ -This is because of a type mismatch between the associated type of some -trait (e.g., `T::Bar`, where `T` implements `trait Quux { type Bar; }`) -and another type `U` that is required to be equal to `T::Bar`, but is not. -Examples follow. +A type mismatched an associated type of a trait. -Here is a basic example: +Erroneous code example: ```compile_fail,E0271 trait Trait { type AssociatedType; } @@ -17,6 +14,11 @@ impl Trait for i8 { type AssociatedType = &'static str; } foo(3_i8); ``` +This is because of a type mismatch between the associated type of some +trait (e.g., `T::Bar`, where `T` implements `trait Quux { type Bar; }`) +and another type `U` that is required to be equal to `T::Bar`, but is not. +Examples follow. + Here is that same example again, with some explanatory comments: ```compile_fail,E0271 From b846b42c8dcf052eabda71d416a986a7891093f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 12 Jan 2020 00:00:00 +0000 Subject: [PATCH 0941/1253] Selectively disable sanitizer instrumentation Add `no_sanitize` attribute that allows to opt out from sanitizer instrumentation in an annotated function. --- .../src/language-features/no-sanitize.md | 29 ++++++++++++++ src/librustc/middle/codegen_fn_attrs.rs | 6 +++ src/librustc_codegen_llvm/attributes.rs | 20 ++++++++++ src/librustc_codegen_llvm/declare.rs | 16 -------- src/librustc_feature/active.rs | 3 ++ src/librustc_feature/builtin_attrs.rs | 5 +++ src/librustc_mir/transform/inline.rs | 23 +++++++++++ src/librustc_session/lint/builtin.rs | 7 ++++ src/librustc_span/symbol.rs | 4 ++ src/librustc_typeck/collect.rs | 39 ++++++++++++++++++- .../codegen/sanitizer-no-sanitize-inlining.rs | 32 +++++++++++++++ src/test/codegen/sanitizer-no-sanitize.rs | 29 ++++++++++++++ .../feature-gates/feature-gate-no_sanitize.rs | 4 ++ .../feature-gate-no_sanitize.stderr | 12 ++++++ src/test/ui/invalid/invalid-no-sanitize.rs | 5 +++ .../ui/invalid/invalid-no-sanitize.stderr | 10 +++++ src/test/ui/sanitize-inline-always.rs | 15 +++++++ src/test/ui/sanitize-inline-always.stderr | 13 +++++++ 18 files changed, 255 insertions(+), 17 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/no-sanitize.md create mode 100644 src/test/codegen/sanitizer-no-sanitize-inlining.rs create mode 100644 src/test/codegen/sanitizer-no-sanitize.rs create mode 100644 src/test/ui/feature-gates/feature-gate-no_sanitize.rs create mode 100644 src/test/ui/feature-gates/feature-gate-no_sanitize.stderr create mode 100644 src/test/ui/invalid/invalid-no-sanitize.rs create mode 100644 src/test/ui/invalid/invalid-no-sanitize.stderr create mode 100644 src/test/ui/sanitize-inline-always.rs create mode 100644 src/test/ui/sanitize-inline-always.stderr diff --git a/src/doc/unstable-book/src/language-features/no-sanitize.md b/src/doc/unstable-book/src/language-features/no-sanitize.md new file mode 100644 index 0000000000000..28c683934d4ed --- /dev/null +++ b/src/doc/unstable-book/src/language-features/no-sanitize.md @@ -0,0 +1,29 @@ +# `no_sanitize` + +The tracking issue for this feature is: [#39699] + +[#39699]: https://github.com/rust-lang/rust/issues/39699 + +------------------------ + +The `no_sanitize` attribute can be used to selectively disable sanitizer +instrumentation in an annotated function. This might be useful to: avoid +instrumentation overhead in a performance critical function, or avoid +instrumenting code that contains constructs unsupported by given sanitizer. + +The precise effect of this annotation depends on particular sanitizer in use. +For example, with `no_sanitize(thread)`, the thread sanitizer will no longer +instrument non-atomic store / load operations, but it will instrument atomic +operations to avoid reporting false positives and provide meaning full stack +traces. + +## Examples + +``` rust +#![feature(no_sanitize)] + +#[no_sanitize(address)] +fn foo() { + // ... +} +``` diff --git a/src/librustc/middle/codegen_fn_attrs.rs b/src/librustc/middle/codegen_fn_attrs.rs index 9f8c20208616b..5eef3fb3c5765 100644 --- a/src/librustc/middle/codegen_fn_attrs.rs +++ b/src/librustc/middle/codegen_fn_attrs.rs @@ -72,6 +72,12 @@ bitflags! { const FFI_RETURNS_TWICE = 1 << 10; /// `#[track_caller]`: allow access to the caller location const TRACK_CALLER = 1 << 11; + /// `#[no_sanitize(address)]`: disables address sanitizer instrumentation + const NO_SANITIZE_ADDRESS = 1 << 12; + /// `#[no_sanitize(memory)]`: disables memory sanitizer instrumentation + const NO_SANITIZE_MEMORY = 1 << 13; + /// `#[no_sanitize(thread)]`: disables thread sanitizer instrumentation + const NO_SANITIZE_THREAD = 1 << 14; } } diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index e3920d99c90bc..3e23df09c6684 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -288,6 +288,26 @@ pub fn from_fn_attrs( if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) { Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); } + if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer { + match *sanitizer { + Sanitizer::Address => { + if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) { + llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); + } + } + Sanitizer::Memory => { + if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) { + llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); + } + } + Sanitizer::Thread => { + if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) { + llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); + } + } + Sanitizer::Leak => {} + } + } unwind( llfn, diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index bb06b52162186..691f32dd85a05 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -19,7 +19,6 @@ use crate::llvm::AttributePlace::Function; use crate::type_::Type; use crate::value::Value; use log::debug; -use rustc::session::config::Sanitizer; use rustc::ty::Ty; use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; @@ -47,21 +46,6 @@ fn declare_raw_fn( llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); } - if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer { - match *sanitizer { - Sanitizer::Address => { - llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); - } - Sanitizer::Memory => { - llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); - } - Sanitizer::Thread => { - llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); - } - _ => {} - } - } - attributes::default_optimisation_attrs(cx.tcx.sess, llfn); attributes::non_lazy_bind(cx.sess(), llfn); llfn diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 4ae79f9ccaa6c..d7fd15a8a7b5f 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -541,6 +541,9 @@ declare_features! ( /// Allows `T: ?const Trait` syntax in bounds. (active, const_trait_bound_opt_out, "1.42.0", Some(67794), None), + /// Allows the use of `no_sanitize` attribute. + (active, no_sanitize, "1.42.0", Some(39699), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index a38726e3de81f..e2e061c185c03 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -261,6 +261,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(cold, Whitelisted, template!(Word)), ungated!(no_builtins, Whitelisted, template!(Word)), ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)), + gated!( + no_sanitize, Whitelisted, + template!(List: "address, memory, thread"), + experimental!(no_sanitize) + ), // FIXME: #14408 whitelist docs since rustdoc looks at them ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")), diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index a3cafcb576323..b6802505df73f 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -8,6 +8,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::mir::visit::*; use rustc::mir::*; +use rustc::session::config::Sanitizer; use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; @@ -228,6 +229,28 @@ impl Inliner<'tcx> { return false; } + // Avoid inlining functions marked as no_sanitize if sanitizer is enabled, + // since instrumentation might be enabled and performed on the caller. + match self.tcx.sess.opts.debugging_opts.sanitizer { + Some(Sanitizer::Address) => { + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) { + return false; + } + } + Some(Sanitizer::Memory) => { + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) { + return false; + } + } + Some(Sanitizer::Thread) => { + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) { + return false; + } + } + Some(Sanitizer::Leak) => {} + None => {} + } + let hinted = match codegen_fn_attrs.inline { // Just treat inline(always) as a hint for now, // there are cases that prevent inlining that we diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index c326061100b06..a61ab5b5e1755 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -474,6 +474,12 @@ declare_lint! { }; } +declare_lint! { + pub INLINE_NO_SANITIZE, + Warn, + "detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`", +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -537,5 +543,6 @@ declare_lint_pass! { MUTABLE_BORROW_RESERVATION_CONFLICT, INDIRECT_STRUCTURAL_MATCH, SOFT_UNSTABLE, + INLINE_NO_SANITIZE, ] } diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index e4f8b5a014389..31100cc573df1 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -120,6 +120,7 @@ symbols! { abi_vectorcall, abi_x86_interrupt, aborts, + address, add_with_overflow, advanced_slice_patterns, adx_target_feature, @@ -445,6 +446,7 @@ symbols! { mem_uninitialized, mem_zeroed, member_constraints, + memory, message, meta, min_align_of, @@ -487,6 +489,7 @@ symbols! { None, non_exhaustive, non_modrs_mods, + no_sanitize, no_stack_check, no_start, no_std, @@ -721,6 +724,7 @@ symbols! { test_removed_feature, test_runner, then_with, + thread, thread_local, tool_attributes, tool_lints, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4d812d2621c61..79cd769569e85 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2743,6 +2743,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { let mut inline_span = None; let mut link_ordinal_span = None; + let mut no_sanitize_span = None; for attr in attrs.iter() { if attr.check_name(sym::cold) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; @@ -2832,6 +2833,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) { codegen_fn_attrs.link_ordinal = ordinal; } + } else if attr.check_name(sym::no_sanitize) { + no_sanitize_span = Some(attr.span); + if let Some(list) = attr.meta_item_list() { + for item in list.iter() { + if item.check_name(sym::address) { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_ADDRESS; + } else if item.check_name(sym::memory) { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_MEMORY; + } else if item.check_name(sym::thread) { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_SANITIZE_THREAD; + } else { + tcx.sess + .struct_span_err(item.span(), "invalid argument for `no_sanitize`") + .note("expected one of: `address`, `memory` or `thread`") + .emit(); + } + } + } } } @@ -2911,7 +2930,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { // purpose functions as they wouldn't have the right target features // enabled. For that reason we also forbid #[inline(always)] as it can't be // respected. - if codegen_fn_attrs.target_features.len() > 0 { if codegen_fn_attrs.inline == InlineAttr::Always { if let Some(span) = inline_span { @@ -2924,6 +2942,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } } + let no_sanitize_flags = CodegenFnAttrFlags::NO_SANITIZE_ADDRESS + | CodegenFnAttrFlags::NO_SANITIZE_MEMORY + | CodegenFnAttrFlags::NO_SANITIZE_THREAD; + if codegen_fn_attrs.flags.intersects(no_sanitize_flags) { + if codegen_fn_attrs.inline == InlineAttr::Always { + if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) { + let hir_id = tcx.hir().as_local_hir_id(id).unwrap(); + tcx.struct_span_lint_hir( + lint::builtin::INLINE_NO_SANITIZE, + hir_id, + no_sanitize_span, + "`no_sanitize` will have no effect after inlining", + ) + .span_note(inline_span, "inlining requested here") + .emit(); + } + } + } + // Weak lang items have the same semantics as "std internal" symbols in the // sense that they're preserved through all our LTO passes and only // strippable by the linker. diff --git a/src/test/codegen/sanitizer-no-sanitize-inlining.rs b/src/test/codegen/sanitizer-no-sanitize-inlining.rs new file mode 100644 index 0000000000000..d96e76618d325 --- /dev/null +++ b/src/test/codegen/sanitizer-no-sanitize-inlining.rs @@ -0,0 +1,32 @@ +// Verifies that no_sanitize attribute prevents inlining when +// given sanitizer is enabled, but has no effect on inlining otherwise. +// +// needs-sanitizer-support +// only-x86_64 +// +// revisions: ASAN LSAN +// +//[ASAN] compile-flags: -Zsanitizer=address -C opt-level=3 -Z mir-opt-level=3 +//[LSAN] compile-flags: -Zsanitizer=leak -C opt-level=3 -Z mir-opt-level=3 + +#![crate_type="lib"] +#![feature(no_sanitize)] + +// ASAN-LABEL: define void @test +// ASAN: tail call fastcc void @random_inline +// ASAN: } +// +// LSAN-LABEL: define void @test +// LSAN-NO: call +// LSAN: } +#[no_mangle] +pub fn test(n: &mut u32) { + random_inline(n); +} + +#[no_sanitize(address)] +#[inline] +#[no_mangle] +pub fn random_inline(n: &mut u32) { + *n = 42; +} diff --git a/src/test/codegen/sanitizer-no-sanitize.rs b/src/test/codegen/sanitizer-no-sanitize.rs new file mode 100644 index 0000000000000..dfceb28c8dd10 --- /dev/null +++ b/src/test/codegen/sanitizer-no-sanitize.rs @@ -0,0 +1,29 @@ +// Verifies that no_sanitze attribute can be used to +// selectively disable sanitizer instrumentation. +// +// needs-sanitizer-support +// compile-flags: -Zsanitizer=address + +#![crate_type="lib"] +#![feature(no_sanitize)] + +// CHECK-LABEL: ; sanitizer_no_sanitize::unsanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK-NOT: sanitize_address +// CHECK: start: +// CHECK-NOT: call void @__asan_report_load +// CHECK: } +#[no_sanitize(address)] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK-LABEL: ; sanitizer_no_sanitize::sanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK: sanitize_address +// CHECK: start: +// CHECK: call void @__asan_report_load +// CHECK: } +pub fn sanitized(b: &mut u8) -> u8 { + *b +} diff --git a/src/test/ui/feature-gates/feature-gate-no_sanitize.rs b/src/test/ui/feature-gates/feature-gate-no_sanitize.rs new file mode 100644 index 0000000000000..66a9263e13a53 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-no_sanitize.rs @@ -0,0 +1,4 @@ +#[no_sanitize(address)] +//~^ the `#[no_sanitize]` attribute is an experimental feature +fn main() { +} diff --git a/src/test/ui/feature-gates/feature-gate-no_sanitize.stderr b/src/test/ui/feature-gates/feature-gate-no_sanitize.stderr new file mode 100644 index 0000000000000..7359cf03652bc --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-no_sanitize.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[no_sanitize]` attribute is an experimental feature + --> $DIR/feature-gate-no_sanitize.rs:1:1 + | +LL | #[no_sanitize(address)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/39699 + = help: add `#![feature(no_sanitize)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/invalid/invalid-no-sanitize.rs b/src/test/ui/invalid/invalid-no-sanitize.rs new file mode 100644 index 0000000000000..b52e3cc83fab2 --- /dev/null +++ b/src/test/ui/invalid/invalid-no-sanitize.rs @@ -0,0 +1,5 @@ +#![feature(no_sanitize)] + +#[no_sanitize(brontosaurus)] //~ ERROR invalid argument +fn main() { +} diff --git a/src/test/ui/invalid/invalid-no-sanitize.stderr b/src/test/ui/invalid/invalid-no-sanitize.stderr new file mode 100644 index 0000000000000..e9983e5fbd24d --- /dev/null +++ b/src/test/ui/invalid/invalid-no-sanitize.stderr @@ -0,0 +1,10 @@ +error: invalid argument for `no_sanitize` + --> $DIR/invalid-no-sanitize.rs:3:15 + | +LL | #[no_sanitize(brontosaurus)] + | ^^^^^^^^^^^^ + | + = note: expected one of: `address`, `memory` or `thread` + +error: aborting due to previous error + diff --git a/src/test/ui/sanitize-inline-always.rs b/src/test/ui/sanitize-inline-always.rs new file mode 100644 index 0000000000000..52dc557818039 --- /dev/null +++ b/src/test/ui/sanitize-inline-always.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(no_sanitize)] + +#[inline(always)] +//~^ NOTE inlining requested here +#[no_sanitize(address)] +//~^ WARN will have no effect after inlining +//~| NOTE on by default +fn x() { +} + +fn main() { + x() +} diff --git a/src/test/ui/sanitize-inline-always.stderr b/src/test/ui/sanitize-inline-always.stderr new file mode 100644 index 0000000000000..50b9474baa2d6 --- /dev/null +++ b/src/test/ui/sanitize-inline-always.stderr @@ -0,0 +1,13 @@ +warning: `no_sanitize` will have no effect after inlining + --> $DIR/sanitize-inline-always.rs:7:1 + | +LL | #[no_sanitize(address)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(inline_no_sanitize)]` on by default +note: inlining requested here + --> $DIR/sanitize-inline-always.rs:5:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + From 1caa8755e523d2c4d3d8d4cfd7be86f86cac3810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 16 Jan 2020 00:00:00 +0000 Subject: [PATCH 0942/1253] Apply LLVM sanitize attributes to generated entry wrapper --- src/librustc_codegen_llvm/attributes.rs | 46 ++++++++++++++----------- src/librustc_codegen_llvm/base.rs | 7 ++-- src/librustc_codegen_ssa/base.rs | 22 ++++++------ 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 3e23df09c6684..a9e4fdba03036 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -46,6 +46,31 @@ fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) { }; } +/// Apply LLVM sanitize attributes. +#[inline] +pub fn sanitize(cx: &CodegenCx<'ll, '_>, codegen_fn_flags: CodegenFnAttrFlags, llfn: &'ll Value) { + if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer { + match *sanitizer { + Sanitizer::Address => { + if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) { + llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); + } + } + Sanitizer::Memory => { + if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) { + llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); + } + } + Sanitizer::Thread => { + if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) { + llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); + } + } + Sanitizer::Leak => {} + } + } +} + /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] pub fn emit_uwtable(val: &'ll Value, emit: bool) { @@ -288,26 +313,7 @@ pub fn from_fn_attrs( if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) { Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); } - if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer { - match *sanitizer { - Sanitizer::Address => { - if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) { - llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); - } - } - Sanitizer::Memory => { - if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) { - llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); - } - } - Sanitizer::Thread => { - if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) { - llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); - } - } - Sanitizer::Leak => {} - } - } + sanitize(cx, codegen_fn_attrs.flags, llfn); unwind( llfn, diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index d3b524c1a1e70..04c084e459eab 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -15,6 +15,7 @@ use super::ModuleLlvm; +use crate::attributes; use crate::builder::Builder; use crate::common; use crate::context::CodegenCx; @@ -23,7 +24,7 @@ use crate::metadata; use crate::value::Value; use rustc::dep_graph; -use rustc::middle::codegen_fn_attrs::CodegenFnAttrs; +use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::exported_symbols; use rustc::mir::mono::{Linkage, Visibility}; @@ -131,7 +132,9 @@ pub fn compile_codegen_unit( // If this codegen unit contains the main function, also create the // wrapper here - maybe_create_entry_wrapper::>(&cx); + if let Some(entry) = maybe_create_entry_wrapper::>(&cx) { + attributes::sanitize(&cx, CodegenFnAttrFlags::empty(), entry); + } // Run replace-all-uses-with for statics that need it for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() { diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 1f43a4027c5ff..900150913842c 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -391,10 +391,12 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( /// Creates the `main` function which will initialize the rust runtime and call /// users main function. -pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'a Bx::CodegenCx) { +pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( + cx: &'a Bx::CodegenCx, +) -> Option { let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) { Some((def_id, _)) => (def_id, cx.tcx().def_span(def_id)), - None => return, + None => return None, }; let instance = Instance::mono(cx.tcx(), main_def_id); @@ -402,17 +404,15 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' if !cx.codegen_unit().contains_item(&MonoItem::Fn(instance)) { // We want to create the wrapper in the same codegen unit as Rust's main // function. - return; + return None; } let main_llfn = cx.get_fn_addr(instance); - let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1); - match et { - Some(EntryFnType::Main) => create_entry_fn::(cx, span, main_llfn, main_def_id, true), - Some(EntryFnType::Start) => create_entry_fn::(cx, span, main_llfn, main_def_id, false), - None => {} // Do nothing. - } + return cx.tcx().entry_fn(LOCAL_CRATE).map(|(_, et)| { + let use_start_lang_item = EntryFnType::Start != et; + create_entry_fn::(cx, span, main_llfn, main_def_id, use_start_lang_item) + }); fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, @@ -420,7 +420,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' rust_main: Bx::Value, rust_main_def_id: DefId, use_start_lang_item: bool, - ) { + ) -> Bx::Function { // The entry function is either `int main(void)` or `int main(int argc, char **argv)`, // depending on whether the target needs `argc` and `argv` to be passed in. let llfty = if cx.sess().target.target.options.main_needs_argc_argv { @@ -481,6 +481,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' let result = bx.call(start_fn, &args, None); let cast = bx.intcast(result, cx.type_int(), true); bx.ret(cast); + + llfn } } From 80adde2e337f4e0d784da401b2db37c5d4d3468b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 6 Feb 2020 00:00:00 +0000 Subject: [PATCH 0943/1253] Add CodegenFnAttrFlags::NO_SANITIZE_ANY --- src/librustc/middle/codegen_fn_attrs.rs | 2 ++ src/librustc_typeck/collect.rs | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/codegen_fn_attrs.rs b/src/librustc/middle/codegen_fn_attrs.rs index 5eef3fb3c5765..82adcfddc289e 100644 --- a/src/librustc/middle/codegen_fn_attrs.rs +++ b/src/librustc/middle/codegen_fn_attrs.rs @@ -78,6 +78,8 @@ bitflags! { const NO_SANITIZE_MEMORY = 1 << 13; /// `#[no_sanitize(thread)]`: disables thread sanitizer instrumentation const NO_SANITIZE_THREAD = 1 << 14; + /// All `#[no_sanitize(...)]` attributes. + const NO_SANITIZE_ANY = Self::NO_SANITIZE_ADDRESS.bits | Self::NO_SANITIZE_MEMORY.bits | Self::NO_SANITIZE_THREAD.bits; } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 79cd769569e85..5e916fc533584 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! "Collection" is the process of determining the type and other external //! details of each item in Rust. Collection is specifically concerned //! with *inter-procedural* things -- for example, for a function @@ -2942,10 +2944,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } } - let no_sanitize_flags = CodegenFnAttrFlags::NO_SANITIZE_ADDRESS - | CodegenFnAttrFlags::NO_SANITIZE_MEMORY - | CodegenFnAttrFlags::NO_SANITIZE_THREAD; - if codegen_fn_attrs.flags.intersects(no_sanitize_flags) { + if codegen_fn_attrs.flags.intersects(CodegenFnAttrFlags::NO_SANITIZE_ANY) { if codegen_fn_attrs.inline == InlineAttr::Always { if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) { let hir_id = tcx.hir().as_local_hir_id(id).unwrap(); From 6ad725e9f09f8ac1e577460ce31bc2928fe3531f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 31 Jan 2020 13:39:34 +1100 Subject: [PATCH 0944/1253] Remove `RefCell` usage from `ObligationForest`. It's not needed. --- src/librustc_data_structures/obligation_forest/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 974d9dcfae408..0384776e9fbc9 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -74,7 +74,7 @@ use crate::fx::{FxHashMap, FxHashSet}; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash; @@ -146,7 +146,7 @@ pub struct ObligationForest { active_cache: FxHashMap, /// A vector reused in compress(), to avoid allocating new vectors. - node_rewrites: RefCell>, + node_rewrites: Vec, obligation_tree_id_generator: ObligationTreeIdGenerator, @@ -285,7 +285,7 @@ impl ObligationForest { nodes: vec![], done_cache: Default::default(), active_cache: Default::default(), - node_rewrites: RefCell::new(vec![]), + node_rewrites: vec![], obligation_tree_id_generator: (0..).map(ObligationTreeId), error_cache: Default::default(), } @@ -590,7 +590,7 @@ impl ObligationForest { #[inline(never)] fn compress(&mut self, do_completed: DoCompleted) -> Option> { let orig_nodes_len = self.nodes.len(); - let mut node_rewrites: Vec<_> = self.node_rewrites.replace(vec![]); + let mut node_rewrites: Vec<_> = std::mem::take(&mut self.node_rewrites); debug_assert!(node_rewrites.is_empty()); node_rewrites.extend(0..orig_nodes_len); let mut dead_nodes = 0; @@ -651,7 +651,7 @@ impl ObligationForest { } node_rewrites.truncate(0); - self.node_rewrites.replace(node_rewrites); + self.node_rewrites = node_rewrites; if do_completed == DoCompleted::Yes { Some(removed_done_obligations) } else { None } } From d8cf95010f0f757d68712c7478b1008734791f66 Mon Sep 17 00:00:00 2001 From: Tyler Lanphear Date: Sat, 1 Feb 2020 18:30:52 -0500 Subject: [PATCH 0945/1253] unused-parens: implement for const/static items --- src/librustc_lint/unused.rs | 8 +++++ src/test/ui/lint/lint-unnecessary-parens.rs | 3 ++ .../ui/lint/lint-unnecessary-parens.stderr | 36 ++++++++++++------- src/test/ui/super-fast-paren-parsing.rs | 1 + 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 272c4f29203d8..5490e5e2b4d55 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -587,6 +587,14 @@ impl EarlyLintPass for UnusedParens { } } } + + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { + use ast::ItemKind::*; + + if let Const(.., ref expr) | Static(.., ref expr) = item.kind { + self.check_unused_parens_expr(cx, expr, "assigned value", false, None, None); + } + } } declare_lint! { diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs index 4e8339a8e6bf1..5ce1f57608132 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.rs +++ b/src/test/ui/lint/lint-unnecessary-parens.rs @@ -38,6 +38,9 @@ macro_rules! baz { } } +const CONST_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value +static STATIC_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value + fn main() { foo(); bar((true)); //~ ERROR unnecessary parentheses around function argument diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr index 3663f1d98bb9c..8858c95327322 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.stderr +++ b/src/test/ui/lint/lint-unnecessary-parens.stderr @@ -34,26 +34,38 @@ error: unnecessary parentheses around block return value LL | (5) | ^^^ help: remove these parentheses +error: unnecessary parentheses around assigned value + --> $DIR/lint-unnecessary-parens.rs:41:27 + | +LL | const CONST_ITEM: usize = (10); + | ^^^^ help: remove these parentheses + +error: unnecessary parentheses around assigned value + --> $DIR/lint-unnecessary-parens.rs:42:29 + | +LL | static STATIC_ITEM: usize = (10); + | ^^^^ help: remove these parentheses + error: unnecessary parentheses around function argument - --> $DIR/lint-unnecessary-parens.rs:43:9 + --> $DIR/lint-unnecessary-parens.rs:46:9 | LL | bar((true)); | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `if` condition - --> $DIR/lint-unnecessary-parens.rs:45:8 + --> $DIR/lint-unnecessary-parens.rs:48:8 | LL | if (true) {} | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `while` condition - --> $DIR/lint-unnecessary-parens.rs:46:11 + --> $DIR/lint-unnecessary-parens.rs:49:11 | LL | while (true) {} | ^^^^^^ help: remove these parentheses warning: denote infinite loops with `loop { ... }` - --> $DIR/lint-unnecessary-parens.rs:46:5 + --> $DIR/lint-unnecessary-parens.rs:49:5 | LL | while (true) {} | ^^^^^^^^^^^^ help: use `loop` @@ -61,46 +73,46 @@ LL | while (true) {} = note: `#[warn(while_true)]` on by default error: unnecessary parentheses around `match` head expression - --> $DIR/lint-unnecessary-parens.rs:48:11 + --> $DIR/lint-unnecessary-parens.rs:51:11 | LL | match (true) { | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:51:16 + --> $DIR/lint-unnecessary-parens.rs:54:16 | LL | if let 1 = (1) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:52:19 + --> $DIR/lint-unnecessary-parens.rs:55:19 | LL | while let 1 = (2) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around method argument - --> $DIR/lint-unnecessary-parens.rs:66:24 + --> $DIR/lint-unnecessary-parens.rs:69:24 | LL | X { y: false }.foo((true)); | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:68:18 + --> $DIR/lint-unnecessary-parens.rs:71:18 | LL | let mut _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:69:10 + --> $DIR/lint-unnecessary-parens.rs:72:10 | LL | _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:70:11 + --> $DIR/lint-unnecessary-parens.rs:73:11 | LL | _a += (1); | ^^^ help: remove these parentheses -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors diff --git a/src/test/ui/super-fast-paren-parsing.rs b/src/test/ui/super-fast-paren-parsing.rs index 60c8db53a8c3d..cb42ff2c6443a 100644 --- a/src/test/ui/super-fast-paren-parsing.rs +++ b/src/test/ui/super-fast-paren-parsing.rs @@ -1,5 +1,6 @@ // run-pass +#![allow(unused_parens)] #![allow(non_upper_case_globals)] #![allow(dead_code)] // exec-env:RUST_MIN_STACK=16000000 From 6bf2cc2229768faa8e86e0e8a9f5bd8ebfc817a2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Feb 2020 09:44:03 +1100 Subject: [PATCH 0946/1253] Avoid instantiating many `Parser` structs in `generic_extension`. Currently, every iteration of the main loop in `generic_extension` instantiates a `Parser`, which is expensive because `Parser` is a large type. Many of those instantiations are only used immutably, particularly for simple-but-repetitive macros of the sort seen in `html5ever` and PR 68836. This commit initializes a single "base" parser outside the loop, and then uses `Cow` to avoid cloning it except for the mutating iterations. This speeds up `html5ever` runs by up to 15%. --- src/librustc_expand/lib.rs | 1 + src/librustc_expand/mbe/macro_parser.rs | 38 ++++----------- src/librustc_expand/mbe/macro_rules.rs | 62 ++++++++++++++++++------- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs index 4fe7c268c4f0b..f119c956ced04 100644 --- a/src/librustc_expand/lib.rs +++ b/src/librustc_expand/lib.rs @@ -1,3 +1,4 @@ +#![feature(cow_is_borrowed)] #![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(proc_macro_diagnostic)] diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index b14725fd731b1..78f22f3e443b1 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -78,13 +78,11 @@ use crate::mbe::{self, TokenTree}; use rustc_ast_pretty::pprust; use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; -use rustc_parse::Directory; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{Ident, Name}; use syntax::ptr::P; use syntax::token::{self, DocComment, Nonterminal, Token}; -use syntax::tokenstream::TokenStream; use rustc_errors::{FatalError, PResult}; use rustc_span::Span; @@ -92,6 +90,7 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; +use std::borrow::Cow; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::mem; use std::ops::{Deref, DerefMut}; @@ -613,28 +612,9 @@ fn inner_parse_loop<'root, 'tt>( Success(()) } -/// Use the given sequence of token trees (`ms`) as a matcher. Match the given token stream `tts` -/// against it and return the match. -/// -/// # Parameters -/// -/// - `sess`: The session into which errors are emitted -/// - `tts`: The tokenstream we are matching against the pattern `ms` -/// - `ms`: A sequence of token trees representing a pattern against which we are matching -/// - `directory`: Information about the file locations (needed for the black-box parser) -/// - `recurse_into_modules`: Whether or not to recurse into modules (needed for the black-box -/// parser) -pub(super) fn parse( - sess: &ParseSess, - tts: TokenStream, - ms: &[TokenTree], - directory: Option>, - recurse_into_modules: bool, -) -> NamedParseResult { - // Create a parser that can be used for the "black box" parts. - let mut parser = - Parser::new(sess, tts, directory, recurse_into_modules, true, rustc_parse::MACRO_ARGUMENTS); - +/// Use the given sequence of token trees (`ms`) as a matcher. Match the token +/// stream from the given `parser` against it and return the match. +pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> NamedParseResult { // A queue of possible matcher positions. We initialize it with the matcher position in which // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop` then // processes all of these possible matcher positions and produces possible next positions into @@ -659,7 +639,7 @@ pub(super) fn parse( // parsing from the black-box parser done. The result is that `next_items` will contain a // bunch of possible next matcher positions in `next_items`. match inner_parse_loop( - sess, + parser.sess, &mut cur_items, &mut next_items, &mut eof_items, @@ -684,7 +664,7 @@ pub(super) fn parse( if eof_items.len() == 1 { let matches = eof_items[0].matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap()); - return nameize(sess, ms, matches); + return nameize(parser.sess, ms, matches); } else if eof_items.len() > 1 { return Error( parser.token.span, @@ -736,13 +716,13 @@ pub(super) fn parse( // If there are no possible next positions AND we aren't waiting for the black-box parser, // then there is a syntax error. else if bb_items.is_empty() && next_items.is_empty() { - return Failure(parser.token.take(), "no rules expected this token in macro call"); + return Failure(parser.token.clone(), "no rules expected this token in macro call"); } // Dump all possible `next_items` into `cur_items` for the next iteration. else if !next_items.is_empty() { // Now process the next token cur_items.extend(next_items.drain(..)); - parser.bump(); + parser.to_mut().bump(); } // Finally, we have the case where we need to call the black-box parser to get some // nonterminal. @@ -754,7 +734,7 @@ pub(super) fn parse( let match_cur = item.match_cur; item.push_match( match_cur, - MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, ident.name))), + MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))), ); item.idx += 1; item.match_cur += 1; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 29d41543fbf8c..9432790e78ced 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -1,11 +1,11 @@ -use crate::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; +use crate::base::{DummyResult, ExpansionData, ExtCtxt, MacResult, TTMacroExpander}; use crate::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind}; use crate::mbe; use crate::mbe::macro_check; -use crate::mbe::macro_parser::parse; +use crate::mbe::macro_parser::parse_tt; use crate::mbe::macro_parser::{Error, Failure, Success}; -use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; +use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; use crate::mbe::transcribe::transcribe; use rustc_ast_pretty::pprust; @@ -166,9 +166,9 @@ impl TTMacroExpander for MacroRulesMacroExpander { } } -fn trace_macros_note(cx: &mut ExtCtxt<'_>, sp: Span, message: String) { +fn trace_macros_note(cx_expansions: &mut FxHashMap>, sp: Span, message: String) { let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); - cx.expansions.entry(sp).or_default().push(message); + cx_expansions.entry(sp).or_default().push(message); } /// Given `lhses` and `rhses`, this is the new macro we create @@ -184,12 +184,36 @@ fn generic_extension<'cx>( ) -> Box { if cx.trace_macros() { let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone())); - trace_macros_note(cx, sp, msg); + trace_macros_note(&mut cx.expansions, sp, msg); } // Which arm's failure should we report? (the one furthest along) let mut best_failure: Option<(Token, &str)> = None; + + // We create a base parser that can be used for the "black box" parts. + // Every iteration needs a fresh copy of that base parser. However, the + // parser is not mutated on many of the iterations, particularly when + // dealing with macros like this: + // + // macro_rules! foo { + // ("a") => (A); + // ("b") => (B); + // ("c") => (C); + // // ... etc. (maybe hundreds more) + // } + // + // as seen in the `html5ever` benchmark. We use a `Cow` so that the base + // parser is only cloned when necessary (upon mutation). Furthermore, we + // reinitialize the `Cow` with the base parser at the start of every + // iteration, so that any mutated parsers are not reused. This is all quite + // hacky, but speeds up the `html5ever` benchmark significantly. (Issue + // 68836 suggests a more comprehensive but more complex change to deal with + // this situation.) + let base_parser = base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone()); + for (i, lhs) in lhses.iter().enumerate() { + let mut parser = Cow::Borrowed(&base_parser); + // try each arm's matchers let lhs_tt = match *lhs { mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], @@ -202,7 +226,7 @@ fn generic_extension<'cx>( // are not recorded. On the first `Success(..)`ful matcher, the spans are merged. let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut()); - match parse_tt(cx, lhs_tt, arg.clone()) { + match parse_tt(&mut parser, lhs_tt) { Success(named_matches) => { // The matcher was `Success(..)`ful. // Merge the gated spans from parsing the matcher with the pre-existing ones. @@ -232,7 +256,7 @@ fn generic_extension<'cx>( if cx.trace_macros() { let msg = format!("to `{}`", pprust::tts_to_string(tts.clone())); - trace_macros_note(cx, sp, msg); + trace_macros_note(&mut cx.expansions, sp, msg); } let directory = Directory { @@ -269,6 +293,7 @@ fn generic_extension<'cx>( // Restore to the state before snapshotting and maybe try again. mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut()); } + drop(base_parser); let (token, label) = best_failure.expect("ran no matchers"); let span = token.span.substitute_dummy(sp); @@ -286,7 +311,9 @@ fn generic_extension<'cx>( mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], _ => continue, }; - match parse_tt(cx, lhs_tt, arg.clone()) { + let base_parser = + base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone()); + match parse_tt(&mut Cow::Borrowed(&base_parser), lhs_tt) { Success(_) => { if comma_span.is_dummy() { err.note("you might be missing a comma"); @@ -368,7 +395,8 @@ pub fn compile_declarative_macro( ), ]; - let argument_map = match parse(sess, body, &argument_gram, None, true) { + let base_parser = Parser::new(sess, body, None, true, true, rustc_parse::MACRO_ARGUMENTS); + let argument_map = match parse_tt(&mut Cow::Borrowed(&base_parser), &argument_gram) { Success(m) => m, Failure(token, msg) => { let s = parse_failure_msg(&token); @@ -1184,14 +1212,16 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { } } -/// Use this token tree as a matcher to parse given tts. -fn parse_tt(cx: &ExtCtxt<'_>, mtch: &[mbe::TokenTree], tts: TokenStream) -> NamedParseResult { - // `None` is because we're not interpolating +fn base_parser_from_cx<'cx>( + current_expansion: &'cx ExpansionData, + sess: &'cx ParseSess, + tts: TokenStream, +) -> Parser<'cx> { let directory = Directory { - path: Cow::from(cx.current_expansion.module.directory.as_path()), - ownership: cx.current_expansion.directory_ownership, + path: Cow::from(current_expansion.module.directory.as_path()), + ownership: current_expansion.directory_ownership, }; - parse(cx.parse_sess(), tts, mtch, Some(directory), true) + Parser::new(sess, tts, Some(directory), true, true, rustc_parse::MACRO_ARGUMENTS) } /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For From f840a955bd449810e75d8320b4c46482d6dbdec1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Feb 2020 14:33:08 +1100 Subject: [PATCH 0947/1253] Remove the `Cow` from `Directory`. The previous commit wrapped `Parser` within a `Cow` for the hot macro parsing path. As a result, there's no need for the `Cow` within `Directory`, because it lies within `Parser`. --- src/librustc_expand/mbe/macro_rules.rs | 4 ++-- src/librustc_parse/lib.rs | 9 ++++----- src/librustc_parse/parser/mod.rs | 9 ++++----- src/librustc_parse/parser/module.rs | 6 +++--- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 9432790e78ced..9e6edee265c98 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -260,7 +260,7 @@ fn generic_extension<'cx>( } let directory = Directory { - path: Cow::from(cx.current_expansion.module.directory.as_path()), + path: cx.current_expansion.module.directory.clone(), ownership: cx.current_expansion.directory_ownership, }; let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None); @@ -1218,7 +1218,7 @@ fn base_parser_from_cx<'cx>( tts: TokenStream, ) -> Parser<'cx> { let directory = Directory { - path: Cow::from(current_expansion.module.directory.as_path()), + path: current_expansion.module.directory.clone(), ownership: current_expansion.directory_ownership, }; Parser::new(sess, tts, Some(directory), true, true, rustc_parse::MACRO_ARGUMENTS) diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index cd674e3c5ebef..4aad2c0f68a29 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -12,8 +12,7 @@ use syntax::ast; use syntax::token::{self, Nonterminal}; use syntax::tokenstream::{self, TokenStream, TokenTree}; -use std::borrow::Cow; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::str; use log::info; @@ -29,8 +28,8 @@ pub mod validate_attr; pub mod config; #[derive(Clone)] -pub struct Directory<'a> { - pub path: Cow<'a, Path>, +pub struct Directory { + pub path: PathBuf, pub ownership: DirectoryOwnership, } @@ -274,7 +273,7 @@ pub fn stream_to_parser<'a>( pub fn stream_to_parser_with_base_dir<'a>( sess: &'a ParseSess, stream: TokenStream, - base_dir: Directory<'a>, + base_dir: Directory, ) -> Parser<'a> { Parser::new(sess, stream, Some(base_dir), true, false, None) } diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 8c1839da1cb8f..cb95750d984e9 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -29,7 +29,6 @@ use syntax::token::{self, DelimToken, Token, TokenKind}; use syntax::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use syntax::util::comments::{doc_comment_style, strip_doc_comment_decoration}; -use std::borrow::Cow; use std::path::PathBuf; use std::{cmp, mem, slice}; @@ -114,7 +113,7 @@ pub struct Parser<'a> { prev_token_kind: PrevTokenKind, restrictions: Restrictions, /// Used to determine the path to externally loaded source files. - pub(super) directory: Directory<'a>, + pub(super) directory: Directory, /// `true` to parse sub-modules in other files. // Public for rustfmt usage. pub recurse_into_file_modules: bool, @@ -376,7 +375,7 @@ impl<'a> Parser<'a> { pub fn new( sess: &'a ParseSess, tokens: TokenStream, - directory: Option>, + directory: Option, recurse_into_file_modules: bool, desugar_doc_comments: bool, subparser_name: Option<&'static str>, @@ -390,7 +389,7 @@ impl<'a> Parser<'a> { restrictions: Restrictions::empty(), recurse_into_file_modules, directory: Directory { - path: Cow::from(PathBuf::new()), + path: PathBuf::new(), ownership: DirectoryOwnership::Owned { relative: None }, }, root_module_name: None, @@ -418,7 +417,7 @@ impl<'a> Parser<'a> { &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path { if let Some(directory_path) = path.parent() { - parser.directory.path = Cow::from(directory_path.to_path_buf()); + parser.directory.path = directory_path.to_path_buf(); } } } diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 6ce94d3c6793c..0c8fad03d8690 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -285,7 +285,7 @@ impl<'a> Parser<'a> { fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) { - self.directory.path.to_mut().push(&*path.as_str()); + self.directory.path.push(&*path.as_str()); self.directory.ownership = DirectoryOwnership::Owned { relative: None }; } else { // We have to push on the current module name in the case of relative @@ -297,10 +297,10 @@ impl<'a> Parser<'a> { if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership { if let Some(ident) = relative.take() { // remove the relative offset - self.directory.path.to_mut().push(&*ident.as_str()); + self.directory.path.push(&*ident.as_str()); } } - self.directory.path.to_mut().push(&*id.as_str()); + self.directory.path.push(&*id.as_str()); } } } From 2a13b24d369b8619f0197993cd5dc60f7217ed72 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Feb 2020 15:09:24 +1100 Subject: [PATCH 0948/1253] Change condition ordering in `parse_tt`. This is a small win, because `Failure` is much more common than `Success`. --- src/librustc_expand/mbe/macro_parser.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 78f22f3e443b1..5bf7602ea6e8f 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -689,9 +689,14 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na // unnecessary implicit clone later in Rc::make_mut. drop(eof_items); + // If there are no possible next positions AND we aren't waiting for the black-box parser, + // then there is a syntax error. + if bb_items.is_empty() && next_items.is_empty() { + return Failure(parser.token.clone(), "no rules expected this token in macro call"); + } // Another possibility is that we need to call out to parse some rust nonterminal // (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong. - if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 { + else if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 { let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { @@ -713,11 +718,6 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na ), ); } - // If there are no possible next positions AND we aren't waiting for the black-box parser, - // then there is a syntax error. - else if bb_items.is_empty() && next_items.is_empty() { - return Failure(parser.token.clone(), "no rules expected this token in macro call"); - } // Dump all possible `next_items` into `cur_items` for the next iteration. else if !next_items.is_empty() { // Now process the next token From bf269335d07b47e548277a02e4cda3c8519a9eec Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 6 Feb 2020 16:19:39 +0900 Subject: [PATCH 0949/1253] Forbid using `0` as issue number --- src/librustc_attr/builtin.rs | 39 +++++++++++-------- .../unstable-attribute-allow-issue-0.rs | 4 +- .../unstable-attribute-allow-issue-0.stderr | 12 +++++- .../stability-attribute-sanity-2.rs | 3 +- .../stability-attribute-sanity-2.stderr | 2 +- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs index be7c164395b0a..ab03297fffe84 100644 --- a/src/librustc_attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -396,26 +396,31 @@ where issue_num = match &*issue.unwrap().as_str() { "none" => None, issue => { + let emit_diag = |msg: &str| { + struct_span_err!( + diagnostic, + mi.span, + E0545, + "`issue` must be a non-zero numeric string \ + or \"none\"", + ) + .span_label( + mi.name_value_literal().unwrap().span, + msg, + ) + .emit(); + }; match issue.parse() { - Ok(num) => { - // FIXME(rossmacarthur): disallow 0 - // Disallowing this requires updates to - // some submodules - NonZeroU32::new(num) + Ok(num) if num == 0 => { + emit_diag( + "`issue` must not be \"0\", \ + use \"none\" instead", + ); + continue 'outer; } + Ok(num) => NonZeroU32::new(num), Err(err) => { - struct_span_err!( - diagnostic, - mi.span, - E0545, - "`issue` must be a numeric string \ - or \"none\"", - ) - .span_label( - mi.name_value_literal().unwrap().span, - &err.to_string(), - ) - .emit(); + emit_diag(&err.to_string()); continue 'outer; } } diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs index 7a2bf468f893a..bffe43262e096 100644 --- a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs +++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs @@ -4,10 +4,10 @@ #![stable(feature = "stable_test_feature", since = "1.0.0")] #[unstable(feature = "unstable_test_feature", issue = "0")] -fn unstable_issue_0() {} +fn unstable_issue_0() {} //~^ ERROR `issue` must be a non-zero numeric string or "none" #[unstable(feature = "unstable_test_feature", issue = "none")] fn unstable_issue_none() {} #[unstable(feature = "unstable_test_feature", issue = "something")] -fn unstable_issue_not_allowed() {} //~^ ERROR `issue` must be a numeric string or "none" +fn unstable_issue_not_allowed() {} //~^ ERROR `issue` must be a non-zero numeric string or "none" diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr index 21ff12185ec5f..7bbaf92fc68c1 100644 --- a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr +++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr @@ -1,4 +1,12 @@ -error[E0545]: `issue` must be a numeric string or "none" +error[E0545]: `issue` must be a non-zero numeric string or "none" + --> $DIR/unstable-attribute-allow-issue-0.rs:6:47 + | +LL | #[unstable(feature = "unstable_test_feature", issue = "0")] + | ^^^^^^^^--- + | | + | `issue` must not be "0", use "none" instead + +error[E0545]: `issue` must be a non-zero numeric string or "none" --> $DIR/unstable-attribute-allow-issue-0.rs:12:47 | LL | #[unstable(feature = "unstable_test_feature", issue = "something")] @@ -6,5 +14,5 @@ LL | #[unstable(feature = "unstable_test_feature", issue = "something")] | | | invalid digit found in string -error: aborting due to previous error +error: aborting due to 2 previous errors diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs b/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs index e74147ce900e8..de3ea4eaca967 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs @@ -10,7 +10,8 @@ fn f1() { } #[stable(feature = "a", sinse = "1.0.0")] //~ ERROR unknown meta item 'sinse' fn f2() { } -#[unstable(feature = "a", issue = "no")] //~ ERROR `issue` must be a numeric string or "none" +#[unstable(feature = "a", issue = "no")] +//~^ ERROR `issue` must be a non-zero numeric string or "none" fn f3() { } fn main() { } diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr index 541b94afe0f67..3b82619189919 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr @@ -10,7 +10,7 @@ error[E0541]: unknown meta item 'sinse' LL | #[stable(feature = "a", sinse = "1.0.0")] | ^^^^^^^^^^^^^^^ expected one of `since`, `note` -error[E0545]: `issue` must be a numeric string or "none" +error[E0545]: `issue` must be a non-zero numeric string or "none" --> $DIR/stability-attribute-sanity-2.rs:13:27 | LL | #[unstable(feature = "a", issue = "no")] From b82f6c575e53f06c3645f66a9d480b4f025ee39e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 6 Feb 2020 11:04:46 +0200 Subject: [PATCH 0950/1253] rustc_codegen_llvm: always set AlwaysPreserve on all debuginfo variables. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index c4a52a73e25d9..eb22d74ba3e47 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -569,7 +569,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { file_metadata, loc.line as c_uint, type_metadata, - self.sess().opts.optimize != config::OptLevel::No, + true, DIFlags::FlagZero, argument_index, align.bytes() as u32, From 63980cd0fb4b0993e71b482e0a14b72b0ca82fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 11:59:29 +0100 Subject: [PATCH 0951/1253] Add a Hir wrapper type --- src/librustc/hir/mod.rs | 32 ++++++++++++++++++++++++++ src/librustc/ty/context.rs | 7 +----- src/librustc_driver/pretty.rs | 10 ++++---- src/librustc_metadata/rmeta/encoder.rs | 4 ++-- src/librustc_passes/check_const.rs | 3 ++- src/librustc_passes/entry.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/pat.rs | 2 +- src/librustdoc/test.rs | 2 +- 9 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 6275c0aabe896..4a4d9cb81456d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -7,6 +7,38 @@ pub mod exports; pub mod map; use crate::ty::query::Providers; +use crate::ty::TyCtxt; +use rustc_hir::print; +use std::ops::Deref; + +/// A wrapper type which allows you to access HIR. +#[derive(Clone)] +pub struct Hir<'tcx> { + tcx: TyCtxt<'tcx>, + map: &'tcx map::Map<'tcx>, +} + +impl<'tcx> Deref for Hir<'tcx> { + type Target = &'tcx map::Map<'tcx>; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.map + } +} + +impl<'hir> print::PpAnn for Hir<'hir> { + fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) { + self.map.nested(state, nested) + } +} + +impl<'tcx> TyCtxt<'tcx> { + #[inline(always)] + pub fn hir(self) -> Hir<'tcx> { + Hir { tcx: self, map: &self.hir_map } + } +} pub fn provide(providers: &mut Providers<'_>) { map::provide(providers); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index f12032943f91f..5a0cb45d0bbe8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -966,7 +966,7 @@ pub struct GlobalCtxt<'tcx> { /// Export map produced by name resolution. export_map: FxHashMap>>, - hir_map: hir_map::Map<'tcx>, + pub(crate) hir_map: hir_map::Map<'tcx>, /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate /// as well as all upstream crates. Only populated in incremental mode. @@ -1019,11 +1019,6 @@ pub struct GlobalCtxt<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - #[inline(always)] - pub fn hir(self) -> &'tcx hir_map::Map<'tcx> { - &self.hir_map - } - pub fn alloc_steal_mir(self, mir: BodyAndCache<'tcx>) -> &'tcx Steal> { self.arena.alloc(Steal::new(mir)) } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 345b03e6db243..4606ef81a360e 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -143,7 +143,7 @@ impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { } fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { - self.tcx.map(|tcx| tcx.hir()) + self.tcx.map(|tcx| *tcx.hir()) } fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn { @@ -155,7 +155,7 @@ impl<'hir> pprust::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(tcx) = self.tcx { - pprust_hir::PpAnn::nested(tcx.hir(), state, nested) + pprust_hir::PpAnn::nested(*tcx.hir(), state, nested) } } } @@ -217,7 +217,7 @@ impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { } fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { - self.tcx.map(|tcx| tcx.hir()) + self.tcx.map(|tcx| *tcx.hir()) } fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn { @@ -228,7 +228,7 @@ impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(ref tcx) = self.tcx { - pprust_hir::PpAnn::nested(tcx.hir(), state, nested) + pprust_hir::PpAnn::nested(*tcx.hir(), state, nested) } } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { @@ -334,7 +334,7 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { if let pprust_hir::Nested::Body(id) = nested { self.tables.set(self.tcx.body_tables(id)); } - pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested); + pprust_hir::PpAnn::nested(*self.tcx.hir(), state, nested); self.tables.set(old_tables); } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 54fbdb14010c9..4133047af78fe 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -796,7 +796,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.kind[def_id] <- match trait_item.kind { ty::AssocKind::Const => { let rendered = - hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item)); + hir::print::to_string(&self.tcx.hir(), |s| s.print_trait_item(ast_item)); let rendered_const = self.lazy(RenderedConst(rendered)); EntryKind::AssocConst( @@ -1009,7 +1009,7 @@ impl EncodeContext<'tcx> { fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy { let body = self.tcx.hir().body(body_id); - let rendered = hir::print::to_string(self.tcx.hir(), |s| s.print_expr(&body.value)); + let rendered = hir::print::to_string(&self.tcx.hir(), |s| s.print_expr(&body.value)); let rendered_const = &RenderedConst(rendered); self.lazy(rendered_const) } diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index faa85f68fab86..b178110f4f954 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -8,6 +8,7 @@ //! through, but errors for structured control flow in a `const` should be emitted here. use rustc::hir::map::Map; +use rustc::hir::Hir; use rustc::session::config::nightly_options; use rustc::session::parse::feature_err; use rustc::ty::query::Providers; @@ -74,7 +75,7 @@ enum ConstKind { } impl ConstKind { - fn for_body(body: &hir::Body<'_>, hir_map: &Map<'_>) -> Option { + fn for_body(body: &hir::Body<'_>, hir_map: Hir<'_>) -> Option { let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const(); let owner = hir_map.body_owner(body.id()); diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs index d36114fd3b5b5..ebd93e9ab85b8 100644 --- a/src/librustc_passes/entry.rs +++ b/src/librustc_passes/entry.rs @@ -1,4 +1,4 @@ -use rustc::hir::map as hir_map; +use rustc::hir::Hir; use rustc::session::config::EntryFnType; use rustc::session::{config, Session}; use rustc::ty::query::Providers; @@ -15,7 +15,7 @@ use syntax::entry::EntryPointType; struct EntryContext<'a, 'tcx> { session: &'a Session, - map: &'a hir_map::Map<'tcx>, + map: Hir<'tcx>, /// The top-level function called `main`. main_fn: Option<(HirId, Span)>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d0275429747b6..62bc6724d0cfe 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2588,7 +2588,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: & E0533, "expected unit struct, unit variant or constant, found {} `{}`", res.descr(), - hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)) + hir::print::to_string(&tcx.hir(), |s| s.print_qpath(qpath, false)) ) .emit(); } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index f9dee0e477f79..47baae6860896 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -693,7 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = format!( "expected tuple struct or tuple variant, found {} `{}`", res.descr(), - hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)), + hir::print::to_string(&tcx.hir(), |s| s.print_qpath(qpath, false)), ); let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg); match (res, &pat.kind) { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 2892c4b153790..ca173fdeb66d4 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -107,7 +107,7 @@ pub fn run(options: Options) -> i32 { let mut hir_collector = HirCollector { sess: compiler.session(), collector: &mut collector, - map: tcx.hir(), + map: *tcx.hir(), codes: ErrorCodes::from( compiler.session().opts.unstable_features.is_nightly_build(), ), From 513e326f5b87a671540ab7959d9205f0cb743491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 12:16:51 +0100 Subject: [PATCH 0952/1253] Add a `hir_krate` query --- src/librustc/hir/mod.rs | 1 + src/librustc/query/mod.rs | 6 ++++++ src/librustc/ty/query/mod.rs | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4a4d9cb81456d..3a53c0cb28274 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -41,5 +41,6 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn provide(providers: &mut Providers<'_>) { + providers.hir_crate = |tcx, _| tcx.hir_map.forest.untracked_krate(); map::provide(providers); } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 37d5e23535b81..f0ea9ee7b196a 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -43,6 +43,12 @@ rustc_queries! { } Other { + query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> { + eval_always + no_hash + desc { "get the crate HIR" } + } + /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { cache_on_disk_if { key.is_local() } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 973cd81014616..e7b95af103cc9 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -45,7 +45,7 @@ use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex}; -use rustc_hir::{HirIdSet, ItemLocalId, TraitCandidate}; +use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate}; use rustc_index::vec::IndexVec; use rustc_target::spec::PanicStrategy; From 84dd07a2c46ed15bf72f4fb552fcf5d89885b13f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 6 Feb 2020 12:27:35 +0100 Subject: [PATCH 0953/1253] Simplify implicit resume argument --- src/librustc_mir_build/build/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index ccfee2d2bb2ee..28e6ae9e6db82 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -83,21 +83,15 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { abi = Abi::Rust; vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)] } - ty::Generator(def_id, _, _) => { + ty::Generator(..) => { let gen_ty = tcx.body_tables(body_id).node_type(id); // The resume argument may be missing, in that case we need to provide it here. + // It will always be `()` in this case. if body.params.is_empty() { - let resume_ty = match gen_ty.kind { - ty::Generator(_, substs, _) => { - substs.as_generator().resume_ty(def_id, tcx) - } - _ => bug!(), - }; - vec![ ArgInfo(gen_ty, None, None, None), - ArgInfo(resume_ty, None, None, None), + ArgInfo(tcx.mk_unit(), None, None, None), ] } else { vec![ArgInfo(gen_ty, None, None, None)] From 732913afcbc37a061dfdc3097cbdc90823386c11 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 6 Feb 2020 12:34:31 +0100 Subject: [PATCH 0954/1253] Clarify comment about `_2` living across a yield --- src/librustc_mir/transform/generator.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 267e77ba48128..a6fc65731780a 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1187,8 +1187,9 @@ impl<'tcx> MirPass<'tcx> for StateTransform { let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx); // We also replace the resume argument and insert an `Assign`. - // This is needed because the resume argument might be live across a `yield`, and the - // transform assumes that any local live across a `yield` is assigned to before that. + // This is needed because the resume argument `_2` might be live across a `yield`, in which + // case there is no `Assign` to it that the transform can turn into a store to the generator + // state. After the yield the slot in the generator state would then be uninitialized. let resume_local = Local::new(2); let new_resume_local = replace_local(resume_local, body.local_decls[resume_local].ty, body, tcx); From 20ce2f6038913058f548f56e1ff1fad29d4df07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 12:46:26 +0100 Subject: [PATCH 0955/1253] Move the `krate` method to Hir and remove the Krate dep node --- src/librustc/dep_graph/dep_node.rs | 15 +-------------- src/librustc/hir/map/collector.rs | 9 +++------ src/librustc/hir/map/hir_id_validator.rs | 2 +- src/librustc/hir/map/mod.rs | 9 --------- src/librustc/hir/mod.rs | 8 ++++++++ src/librustc/query/mod.rs | 6 ++++++ src/librustc/ty/query/plumbing.rs | 1 - src/librustc_driver/pretty.rs | 6 +++--- src/librustc_resolve/lifetimes.rs | 2 +- src/librustdoc/test.rs | 2 +- src/test/incremental/crate_hash_reorder.rs | 8 +++----- src/test/incremental/issue-38222.rs | 12 ++++-------- src/test/incremental/krate-inherent.rs | 8 ++++---- src/test/incremental/krate-inlined.rs | 4 ++-- src/test/ui/dep-graph/dep-graph-variance-alias.rs | 9 ++++----- .../ui/dep-graph/dep-graph-variance-alias.stderr | 2 +- 16 files changed, 42 insertions(+), 61 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 9df8e28254cf5..29b94986a5f3a 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -35,7 +35,7 @@ //! "infer" some properties for each kind of `DepNode`: //! //! * Whether a `DepNode` of a given kind has any parameters at all. Some -//! `DepNode`s, like `Krate`, represent global concepts with only one value. +//! `DepNode`s, like `AllLocalTraitImpls`, represent global concepts with only one value. //! * Whether it is possible, in principle, to reconstruct a query key from a //! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter, //! in which case it is possible to map the node's fingerprint back to the @@ -400,19 +400,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> // We use this for most things when incr. comp. is turned off. [] Null, - // Represents the `Krate` as a whole (the `hir::Krate` value) (as - // distinct from the krate module). This is basically a hash of - // the entire krate, so if you read from `Krate` (e.g., by calling - // `tcx.hir().krate()`), we will have to assume that any change - // means that you need to be recompiled. This is because the - // `Krate` value gives you access to all other items. To avoid - // this fate, do not call `tcx.hir().krate()`; instead, prefer - // wrappers like `tcx.visit_all_items_in_krate()`. If there is no - // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain - // access to the krate, but you must remember to add suitable - // edges yourself for the individual items that you read. - [eval_always] Krate, - // Represents the body of a function or method. The def-id is that of the // function/method. [eval_always] HirBody(DefId), diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index b6be4bb001996..4c922654e02d5 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -223,12 +223,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { (commandline_args_hash, crate_disambiguator.to_fingerprint()), ); - let (_, crate_hash) = input_dep_node_and_hash( - self.dep_graph, - &mut self.hcx, - DepNode::new_no_params(DepKind::Krate), - crate_hash_input, - ); + let mut stable_hasher = StableHasher::new(); + crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher); + let crate_hash: Fingerprint = stable_hasher.finish(); let svh = Svh::new(crate_hash.to_smaller_hash()); (self.map, svh) diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 76e42b8af2874..da9695ec08a79 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -12,7 +12,7 @@ pub fn check_crate(hir_map: &Map<'_>) { let errors = Lock::new(Vec::new()); - par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| { + par_iter(&hir_map.forest.krate.modules).for_each(|(module_id, _)| { let local_def_id = hir_map.local_def_id(*module_id); hir_map.visit_item_likes_in_module( local_def_id, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 6d7f53133a666..0e74ccc63b8c6 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -140,11 +140,6 @@ impl Forest<'hir> { Forest { krate, dep_graph: dep_graph.clone() } } - pub fn krate(&self) -> &Crate<'hir> { - self.dep_graph.read(DepNode::new_no_params(DepKind::Krate)); - &self.krate - } - /// This is used internally in the dependency tracking system. /// Use the `krate` method to ensure your dependency on the /// crate is tracked. @@ -401,10 +396,6 @@ impl<'hir> Map<'hir> { self.lookup(id).cloned() } - pub fn krate(&self) -> &'hir Crate<'hir> { - self.forest.krate() - } - pub fn item(&self, id: HirId) -> &'hir Item<'hir> { self.read(id); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3a53c0cb28274..259cee471603c 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -8,7 +8,9 @@ pub mod map; use crate::ty::query::Providers; use crate::ty::TyCtxt; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::print; +use rustc_hir::Crate; use std::ops::Deref; /// A wrapper type which allows you to access HIR. @@ -18,6 +20,12 @@ pub struct Hir<'tcx> { map: &'tcx map::Map<'tcx>, } +impl<'tcx> Hir<'tcx> { + pub fn krate(&self) -> &'tcx Crate<'tcx> { + self.tcx.hir_crate(LOCAL_CRATE) + } +} + impl<'tcx> Deref for Hir<'tcx> { type Target = &'tcx map::Map<'tcx>; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index f0ea9ee7b196a..82ff7da13aea8 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -43,6 +43,12 @@ rustc_queries! { } Other { + // Represents crate as a whole (as distinct from the to-level crate module). + // If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), + // we will have to assume that any change means that you need to be recompiled. + // This is because the `hir_crate` query gives you access to all other items. + // To avoid this fate, do not call `tcx.hir().krate()`; instead, + // prefer wrappers like `tcx.visit_all_items_in_krate()`. query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> { eval_always no_hash diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 117a38c655eaa..6d9fff351e9b8 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1177,7 +1177,6 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { // These are inputs that are expected to be pre-allocated and that // should therefore always be red or green already. DepKind::AllLocalTraitImpls | - DepKind::Krate | DepKind::CrateMetadata | DepKind::HirBody | DepKind::Hir | diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4606ef81a360e..d4f0149049941 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -69,19 +69,19 @@ where match *ppmode { PpmNormal => { let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) }; - f(&annotation, tcx.hir().forest.krate()) + f(&annotation, tcx.hir().krate()) } PpmIdentified => { let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) }; - f(&annotation, tcx.hir().forest.krate()) + f(&annotation, tcx.hir().krate()) } PpmTyped => { abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess); let empty_tables = ty::TypeckTables::empty(None); let annotation = TypedAnnotation { tcx, tables: Cell::new(&empty_tables) }; - tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().forest.krate())) + tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().krate())) } _ => panic!("Should use call_with_pp_support"), } diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 0ba9b4f17068e..87522d28d1e80 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -612,7 +612,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let parent_id = self.tcx.hir().get_parent_node(hir_id); let parent_impl_id = hir::ImplItemId { hir_id: parent_id }; let parent_trait_id = hir::TraitItemId { hir_id: parent_id }; - let krate = self.tcx.hir().forest.krate(); + let krate = self.tcx.hir().krate(); if !(krate.items.contains_key(&parent_id) || krate.impl_items.contains_key(&parent_impl_id) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index ca173fdeb66d4..80d3cc05fb7a7 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -87,7 +87,7 @@ pub fn run(options: Options) -> i32 { compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; - let mut opts = scrape_test_config(lower_to_hir.peek().0.krate()); + let mut opts = scrape_test_config(lower_to_hir.peek().0.untracked_krate()); opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( diff --git a/src/test/incremental/crate_hash_reorder.rs b/src/test/incremental/crate_hash_reorder.rs index 5aba2a670370c..6e06e67b6682d 100644 --- a/src/test/incremental/crate_hash_reorder.rs +++ b/src/test/incremental/crate_hash_reorder.rs @@ -7,11 +7,9 @@ // Check that reordering otherwise identical items is not considered a // change at all. -#[rustc_clean(label="Krate", cfg="rpass2")] - +#[rustc_clean(label = "hir_crate", cfg = "rpass2")] // But removing an item, naturally, is. -#[rustc_dirty(label="Krate", cfg="rpass3")] - +#[rustc_dirty(label = "hir_crate", cfg = "rpass3")] #[cfg(rpass1)] pub struct X { pub x: u32, @@ -26,4 +24,4 @@ pub struct X { pub x: u32, } -pub fn main() { } +pub fn main() {} diff --git a/src/test/incremental/issue-38222.rs b/src/test/incremental/issue-38222.rs index df08661c1500e..20d4d4200bc1e 100644 --- a/src/test/incremental/issue-38222.rs +++ b/src/test/incremental/issue-38222.rs @@ -1,18 +1,14 @@ -// Test that debuginfo does not introduce a dependency edge to the Krate +// Test that debuginfo does not introduce a dependency edge to the hir_crate // dep-node. // revisions:rpass1 rpass2 // compile-flags: -Z query-dep-graph - #![feature(rustc_attrs)] - - -#![rustc_partition_reused(module="issue_38222-mod1", cfg="rpass2")] - -// If codegen had added a dependency edge to the Krate dep-node, nothing would +#![rustc_partition_reused(module = "issue_38222-mod1", cfg = "rpass2")] +// If codegen had added a dependency edge to the hir_crate dep-node, nothing would // be re-used, so checking that this module was re-used is sufficient. -#![rustc_partition_reused(module="issue_38222", cfg="rpass2")] +#![rustc_partition_reused(module = "issue_38222", cfg = "rpass2")] //[rpass1] compile-flags: -C debuginfo=1 //[rpass2] compile-flags: -C debuginfo=1 diff --git a/src/test/incremental/krate-inherent.rs b/src/test/incremental/krate-inherent.rs index 6e791eacdf37a..2c04e110525a6 100644 --- a/src/test/incremental/krate-inherent.rs +++ b/src/test/incremental/krate-inherent.rs @@ -4,20 +4,20 @@ #![allow(warnings)] #![feature(rustc_attrs)] -#![rustc_partition_reused(module="krate_inherent-x", cfg="cfail2")] +#![rustc_partition_reused(module = "krate_inherent-x", cfg = "cfail2")] #![crate_type = "rlib"] pub mod x { pub struct Foo; impl Foo { - pub fn foo(&self) { } + pub fn foo(&self) {} } pub fn method() { let x: Foo = Foo; - x.foo(); // inherent methods used to add an edge from Krate + x.foo(); // inherent methods used to add an edge from hir_crate } } #[cfg(cfail1)] -pub fn bar() { } // remove this unrelated fn in cfail2, which should not affect `x::method` +pub fn bar() {} // remove this unrelated fn in cfail2, which should not affect `x::method` diff --git a/src/test/incremental/krate-inlined.rs b/src/test/incremental/krate-inlined.rs index dfb18166ae950..6b1db74a37c66 100644 --- a/src/test/incremental/krate-inlined.rs +++ b/src/test/incremental/krate-inlined.rs @@ -1,5 +1,5 @@ // Regr. test that using HIR inlined from another krate does *not* add -// a dependency from the local Krate node. We can't easily test that +// a dependency from the local hir_crate node. We can't easily test that // directly anymore, so now we test that we get reuse. // revisions: rpass1 rpass2 @@ -7,7 +7,7 @@ #![allow(warnings)] #![feature(rustc_attrs)] -#![rustc_partition_reused(module="krate_inlined-x", cfg="rpass2")] +#![rustc_partition_reused(module = "krate_inlined-x", cfg = "rpass2")] fn main() { x::method(); diff --git a/src/test/ui/dep-graph/dep-graph-variance-alias.rs b/src/test/ui/dep-graph/dep-graph-variance-alias.rs index 95645687307a3..927ea5597783a 100644 --- a/src/test/ui/dep-graph/dep-graph-variance-alias.rs +++ b/src/test/ui/dep-graph/dep-graph-variance-alias.rs @@ -6,17 +6,16 @@ #![feature(rustc_attrs)] #![allow(dead_code)] #![allow(unused_variables)] - -fn main() { } +#![rustc_if_this_changed(hir_crate)] +fn main() {} struct Foo { - f: T + f: T, } -#[rustc_if_this_changed(Krate)] type TypeAlias = Foo; #[rustc_then_this_would_need(variances_of)] //~ ERROR OK struct Use { - x: TypeAlias + x: TypeAlias, } diff --git a/src/test/ui/dep-graph/dep-graph-variance-alias.stderr b/src/test/ui/dep-graph/dep-graph-variance-alias.stderr index 554ff455a2073..2422cb9bb2f52 100644 --- a/src/test/ui/dep-graph/dep-graph-variance-alias.stderr +++ b/src/test/ui/dep-graph/dep-graph-variance-alias.stderr @@ -1,5 +1,5 @@ error: OK - --> $DIR/dep-graph-variance-alias.rs:19:1 + --> $DIR/dep-graph-variance-alias.rs:18:1 | LL | #[rustc_then_this_would_need(variances_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 623dcb02db0f23270ef4497739dff43ab6f7bcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 13:41:37 +0100 Subject: [PATCH 0956/1253] Remove the `Forest` type --- src/librustc/arena.rs | 2 +- src/librustc/hir/map/hir_id_validator.rs | 2 +- src/librustc/hir/map/mod.rs | 89 +++++++++--------------- src/librustc/hir/mod.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc_interface/passes.rs | 12 ++-- src/librustc_interface/queries.rs | 18 ++--- src/librustdoc/test.rs | 2 +- 8 files changed, 51 insertions(+), 78 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 92f5bf87535e6..dd242686d26f2 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -127,7 +127,7 @@ macro_rules! arena_types { [] tys: rustc::ty::TyS<$tcx>, // HIR types - [few] hir_forest: rustc::hir::map::Forest<$tcx>, + [few] hir_krate: rustc_hir::Crate<$tcx>, [] arm: rustc_hir::Arm<$tcx>, [] attribute: syntax::ast::Attribute, [] block: rustc_hir::Block<$tcx>, diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index da9695ec08a79..c721faafbecaf 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -12,7 +12,7 @@ pub fn check_crate(hir_map: &Map<'_>) { let errors = Lock::new(Vec::new()); - par_iter(&hir_map.forest.krate.modules).for_each(|(module_id, _)| { + par_iter(&hir_map.krate.modules).for_each(|(module_id, _)| { let local_def_id = hir_map.local_def_id(*module_id); hir_map.visit_item_likes_in_module( local_def_id, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 0e74ccc63b8c6..7e0e85ea5866f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -129,25 +129,6 @@ impl<'hir> Entry<'hir> { } } -/// Stores a crate and any number of inlined items from other crates. -pub struct Forest<'hir> { - krate: Crate<'hir>, - pub dep_graph: DepGraph, -} - -impl Forest<'hir> { - pub fn new(krate: Crate<'hir>, dep_graph: &DepGraph) -> Forest<'hir> { - Forest { krate, dep_graph: dep_graph.clone() } - } - - /// This is used internally in the dependency tracking system. - /// Use the `krate` method to ensure your dependency on the - /// crate is tracked. - pub fn untracked_krate(&self) -> &Crate<'hir> { - &self.krate - } -} - /// This type is effectively a `HashMap>`, /// but it is implemented as 2 layers of arrays. /// - first we have `A = IndexVec` mapping `DefIndex`s to an inner value @@ -157,11 +138,8 @@ pub(super) type HirEntryMap<'hir> = IndexVec { - /// The backing storage for all the AST nodes. - pub forest: &'hir Forest<'hir>, + pub krate: &'hir Crate<'hir>, - /// Same as the dep_graph in forest, just available with one fewer - /// deref. This is a gratuitous micro-optimization. pub dep_graph: DepGraph, /// The SVH of the local crate. @@ -212,6 +190,13 @@ impl<'hir> Iterator for ParentHirIterator<'_, 'hir> { } impl<'hir> Map<'hir> { + /// This is used internally in the dependency tracking system. + /// Use the `krate` method to ensure your dependency on the + /// crate is tracked. + pub fn untracked_krate(&self) -> &Crate<'hir> { + &self.krate + } + #[inline] fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> { let local_map = self.map.get(id.owner)?; @@ -399,33 +384,33 @@ impl<'hir> Map<'hir> { pub fn item(&self, id: HirId) -> &'hir Item<'hir> { self.read(id); - // N.B., intentionally bypass `self.forest.krate()` so that we + // N.B., intentionally bypass `self.krate()` so that we // do not trigger a read of the whole krate here - self.forest.krate.item(id) + self.krate.item(id) } pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> { self.read(id.hir_id); - // N.B., intentionally bypass `self.forest.krate()` so that we + // N.B., intentionally bypass `self.krate()` so that we // do not trigger a read of the whole krate here - self.forest.krate.trait_item(id) + self.krate.trait_item(id) } pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> { self.read(id.hir_id); - // N.B., intentionally bypass `self.forest.krate()` so that we + // N.B., intentionally bypass `self.krate()` so that we // do not trigger a read of the whole krate here - self.forest.krate.impl_item(id) + self.krate.impl_item(id) } pub fn body(&self, id: BodyId) -> &'hir Body<'hir> { self.read(id.hir_id); - // N.B., intentionally bypass `self.forest.krate()` so that we + // N.B., intentionally bypass `self.krate()` so that we // do not trigger a read of the whole krate here - self.forest.krate.body(id) + self.krate.body(id) } pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> { @@ -521,9 +506,9 @@ impl<'hir> Map<'hir> { pub fn trait_impls(&self, trait_did: DefId) -> &'hir [HirId] { self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls)); - // N.B., intentionally bypass `self.forest.krate()` so that we + // N.B., intentionally bypass `self.krate()` so that we // do not trigger a read of the whole krate here - self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..]) + self.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to @@ -533,7 +518,7 @@ impl<'hir> Map<'hir> { let def_path_hash = self.definitions.def_path_hash(CRATE_DEF_INDEX); self.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir)); - &self.forest.krate.attrs + &self.krate.attrs } pub fn get_module(&self, module: DefId) -> (&'hir Mod<'hir>, Span, HirId) { @@ -541,7 +526,7 @@ impl<'hir> Map<'hir> { self.read(hir_id); match self.find_entry(hir_id).unwrap().node { Node::Item(&Item { span, kind: ItemKind::Mod(ref m), .. }) => (m, span, hir_id), - Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id), + Node::Crate => (&self.krate.module, self.krate.span, hir_id), node => panic!("not a module: {:?}", node), } } @@ -558,7 +543,7 @@ impl<'hir> Map<'hir> { // in the expect_* calls the loops below self.read(hir_id); - let module = &self.forest.krate.modules[&hir_id]; + let module = &self.krate.modules[&hir_id]; for id in &module.items { visitor.visit_item(self.expect_item(*id)); @@ -975,7 +960,7 @@ impl<'hir> Map<'hir> { // Unit/tuple structs/variants take the attributes straight from // the struct/variant definition. Some(Node::Ctor(..)) => return self.attrs(self.get_parent_item(id)), - Some(Node::Crate) => Some(&self.forest.krate.attrs[..]), + Some(Node::Crate) => Some(&self.krate.attrs[..]), _ => None, }; attrs.unwrap_or(&[]) @@ -1054,7 +1039,7 @@ impl<'hir> Map<'hir> { Some(Node::Visibility(v)) => bug!("unexpected Visibility {:?}", v), Some(Node::Local(local)) => local.span, Some(Node::MacroDef(macro_def)) => macro_def.span, - Some(Node::Crate) => self.forest.krate.span, + Some(Node::Crate) => self.krate.span, None => bug!("hir::map::Map::span: id not in map: {:?}", hir_id), } } @@ -1222,7 +1207,8 @@ impl Named for ImplItem<'_> { pub fn map_crate<'hir>( sess: &rustc_session::Session, cstore: &CrateStoreDyn, - forest: &'hir Forest<'hir>, + krate: &'hir Crate<'hir>, + dep_graph: DepGraph, definitions: Definitions, ) -> Map<'hir> { let _prof_timer = sess.prof.generic_activity("build_hir_map"); @@ -1235,31 +1221,18 @@ pub fn map_crate<'hir>( .collect(); let (map, crate_hash) = { - let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, &definitions, cstore); - - let mut collector = NodeCollector::root( - sess, - &forest.krate, - &forest.dep_graph, - &definitions, - &hir_to_node_id, - hcx, - ); - intravisit::walk_crate(&mut collector, &forest.krate); + let hcx = crate::ich::StableHashingContext::new(sess, krate, &definitions, cstore); + + let mut collector = + NodeCollector::root(sess, krate, &dep_graph, &definitions, &hir_to_node_id, hcx); + intravisit::walk_crate(&mut collector, krate); let crate_disambiguator = sess.local_crate_disambiguator(); let cmdline_args = sess.opts.dep_tracking_hash(); collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, cmdline_args) }; - let map = Map { - forest, - dep_graph: forest.dep_graph.clone(), - crate_hash, - map, - hir_to_node_id, - definitions, - }; + let map = Map { krate, dep_graph, crate_hash, map, hir_to_node_id, definitions }; sess.time("validate_HIR_map", || { hir_id_validator::check_crate(&map); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 259cee471603c..2e7e8fdd72491 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -49,6 +49,6 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn provide(providers: &mut Providers<'_>) { - providers.hir_crate = |tcx, _| tcx.hir_map.forest.untracked_krate(); + providers.hir_crate = |tcx, _| tcx.hir_map.untracked_krate(); map::provide(providers); } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 5a0cb45d0bbe8..8979292c86d40 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1323,7 +1323,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(always)] pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> { - let krate = self.gcx.hir_map.forest.untracked_krate(); + let krate = self.gcx.hir_map.untracked_krate(); StableHashingContext::new(self.sess, krate, self.hir().definitions(), &*self.cstore) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index bf8bcd71efa41..6224c4654d695 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -25,6 +25,7 @@ use rustc_data_structures::{box_region_allow_access, declare_box_region_type, pa use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::Crate; use rustc_lint::LintStore; use rustc_mir as mir; use rustc_mir_build as mir_build; @@ -422,7 +423,7 @@ pub fn lower_to_hir<'res, 'tcx>( dep_graph: &'res DepGraph, krate: &'res ast::Crate, arena: &'tcx Arena<'tcx>, -) -> Result> { +) -> Crate<'tcx> { // Lower AST to HIR. let hir_crate = rustc_ast_lowering::lower_crate( sess, @@ -437,8 +438,6 @@ pub fn lower_to_hir<'res, 'tcx>( hir_stats::print_hir_stats(&hir_crate); } - let hir_forest = map::Forest::new(hir_crate, &dep_graph); - sess.time("early_lint_checks", || { rustc_lint::check_ast_crate( sess, @@ -455,7 +454,7 @@ pub fn lower_to_hir<'res, 'tcx>( rustc_span::hygiene::clear_syntax_context_map(); } - Ok(hir_forest) + hir_crate } // Returns all the paths that correspond to generated files. @@ -705,7 +704,8 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, - hir_forest: &'tcx map::Forest<'tcx>, + krate: &'tcx Crate<'tcx>, + dep_graph: DepGraph, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, @@ -716,7 +716,7 @@ pub fn create_global_ctxt<'tcx>( let defs = mem::take(&mut resolver_outputs.definitions); // Construct the HIR map. - let hir_map = map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs); + let hir_map = map::map_crate(sess, &*resolver_outputs.cstore, krate, dep_graph, defs); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 2ac2845be91b3..720d162ac819e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -3,7 +3,6 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc::arena::Arena; use rustc::dep_graph::DepGraph; -use rustc::hir::map; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::session::Session; use rustc::ty::steal::Steal; @@ -12,6 +11,7 @@ use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::Crate; use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use std::any::Any; @@ -74,7 +74,7 @@ pub struct Queries<'tcx> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(&'tcx map::Forest<'tcx>, Steal)>, + lower_to_hir: Query<(&'tcx Crate<'tcx>, Steal)>, prepare_outputs: Query, global_ctxt: Query>, ongoing_codegen: Query>, @@ -207,9 +207,7 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn lower_to_hir( - &'tcx self, - ) -> Result<&Query<(&'tcx map::Forest<'tcx>, Steal)>> { + pub fn lower_to_hir(&'tcx self) -> Result<&Query<(&'tcx Crate<'tcx>, Steal)>> { self.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); @@ -217,14 +215,14 @@ impl<'tcx> Queries<'tcx> { let resolver = peeked.1.steal(); let lint_store = &peeked.2; let hir = resolver.borrow_mut().access(|resolver| { - passes::lower_to_hir( + Ok(passes::lower_to_hir( self.session(), lint_store, resolver, &*self.dep_graph()?.peek(), &krate, &self.arena, - ) + )) })?; let hir = self.arena.alloc(hir); Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) @@ -253,12 +251,14 @@ impl<'tcx> Queries<'tcx> { let outputs = self.prepare_outputs()?.peek().clone(); let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?.peek(); - let (ref hir_forest, ref resolver_outputs) = &*hir; + let dep_graph = self.dep_graph()?.peek().clone(); + let (ref krate, ref resolver_outputs) = &*hir; let _timer = self.session().timer("create_global_ctxt"); Ok(passes::create_global_ctxt( self.compiler, lint_store, - hir_forest, + krate, + dep_graph, resolver_outputs.steal(), outputs, &crate_name, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 80d3cc05fb7a7..d3e53e1881276 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -87,7 +87,7 @@ pub fn run(options: Options) -> i32 { compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; - let mut opts = scrape_test_config(lower_to_hir.peek().0.untracked_krate()); + let mut opts = scrape_test_config(lower_to_hir.peek().0); opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( From dc4fd3d7240e50e6c4c42952c51db021c88a3575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 14:11:57 +0100 Subject: [PATCH 0957/1253] Comment tweaks --- src/librustc/query/mod.rs | 2 +- src/librustc/ty/context.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 82ff7da13aea8..4842719d804da 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -43,7 +43,7 @@ rustc_queries! { } Other { - // Represents crate as a whole (as distinct from the to-level crate module). + // Represents crate as a whole (as distinct from the top-level crate module). // If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), // we will have to assume that any change means that you need to be recompiled. // This is because the `hir_crate` query gives you access to all other items. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 8979292c86d40..8386058f72ac7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -966,6 +966,7 @@ pub struct GlobalCtxt<'tcx> { /// Export map produced by name resolution. export_map: FxHashMap>>, + /// This should usually be accessed with the `tcx.hir()` method. pub(crate) hir_map: hir_map::Map<'tcx>, /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate From 9d7b214ac6cb50a1b5454e0ae904a6479b54261c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 6 Feb 2020 14:59:51 +0100 Subject: [PATCH 0958/1253] Ignore panic-drops-resume.rs on wasm/emscripten It does not have unwinding support --- src/test/ui/generator/panic-drops-resume.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/generator/panic-drops-resume.rs b/src/test/ui/generator/panic-drops-resume.rs index 4a482d3f6df39..29f4788b2757f 100644 --- a/src/test/ui/generator/panic-drops-resume.rs +++ b/src/test/ui/generator/panic-drops-resume.rs @@ -1,6 +1,8 @@ //! Tests that panics inside a generator will correctly drop the initial resume argument. // run-pass +// ignore-wasm no unwind support +// ignore-emscripten no unwind support #![feature(generators, generator_trait)] From 534c3eaf286e612ef9196a2744a211285b2fff83 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Thu, 6 Feb 2020 15:31:21 +0100 Subject: [PATCH 0959/1253] error code examples: replace some more ignore with compile_fail Now that compile_fail attempts a full build rather than --emit=metadata, these errors should be caught by compile_fail and do not need to be ignored. --- src/librustc_error_codes/error_codes/E0511.md | 2 +- src/librustc_error_codes/error_codes/E0534.md | 2 +- src/librustc_error_codes/error_codes/E0535.md | 2 +- src/librustc_error_codes/error_codes/E0633.md | 4 +++- src/librustc_error_codes/error_codes/E0668.md | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0511.md b/src/librustc_error_codes/error_codes/E0511.md index 2d6ff8241e692..4f6644f358291 100644 --- a/src/librustc_error_codes/error_codes/E0511.md +++ b/src/librustc_error_codes/error_codes/E0511.md @@ -1,7 +1,7 @@ Invalid monomorphization of an intrinsic function was used. Erroneous code example: -```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) +```compile_fail,E0511 #![feature(platform_intrinsics)] extern "platform-intrinsic" { diff --git a/src/librustc_error_codes/error_codes/E0534.md b/src/librustc_error_codes/error_codes/E0534.md index e50b84764b4db..0afa4a8c95811 100644 --- a/src/librustc_error_codes/error_codes/E0534.md +++ b/src/librustc_error_codes/error_codes/E0534.md @@ -2,7 +2,7 @@ The `inline` attribute was malformed. Erroneous code example: -```ignore (compile_fail not working here; see Issue #43707) +```compile_fail,E0534 #[inline()] // error: expected one argument pub fn something() {} diff --git a/src/librustc_error_codes/error_codes/E0535.md b/src/librustc_error_codes/error_codes/E0535.md index e9abfe5dda1ba..035d395b76fe7 100644 --- a/src/librustc_error_codes/error_codes/E0535.md +++ b/src/librustc_error_codes/error_codes/E0535.md @@ -2,7 +2,7 @@ An unknown argument was given to the `inline` attribute. Erroneous code example: -```ignore (compile_fail not working here; see Issue #43707) +```compile_fail,E0535 #[inline(unknown)] // error: invalid argument pub fn something() {} diff --git a/src/librustc_error_codes/error_codes/E0633.md b/src/librustc_error_codes/error_codes/E0633.md index 65cdf90036ade..7f488cde664d9 100644 --- a/src/librustc_error_codes/error_codes/E0633.md +++ b/src/librustc_error_codes/error_codes/E0633.md @@ -2,7 +2,9 @@ The `unwind` attribute was malformed. Erroneous code example: -```ignore (compile_fail not working here; see Issue #43707) +```compile_fail,E0633 +#![feature(unwind_attributes)] + #[unwind()] // error: expected one argument pub extern fn something() {} diff --git a/src/librustc_error_codes/error_codes/E0668.md b/src/librustc_error_codes/error_codes/E0668.md index 2621a31a9e0f8..f5d26244fb961 100644 --- a/src/librustc_error_codes/error_codes/E0668.md +++ b/src/librustc_error_codes/error_codes/E0668.md @@ -6,7 +6,7 @@ assembly call. In particular, it can happen if you forgot the closing bracket of a register constraint (see issue #51430): -```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) +```compile_fail,E0668 #![feature(asm)] fn main() { From 64450ac765366759af9f0e2769e578e87474cfca Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 6 Feb 2020 23:55:45 +0900 Subject: [PATCH 0960/1253] Update E0565 examples --- src/librustc_error_codes/error_codes/E0565.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0565.md b/src/librustc_error_codes/error_codes/E0565.md index 1faedf4593271..d5bba941c1dd2 100644 --- a/src/librustc_error_codes/error_codes/E0565.md +++ b/src/librustc_error_codes/error_codes/E0565.md @@ -2,9 +2,11 @@ A literal was used in a built-in attribute that doesn't support literals. Erroneous code example: -```ignore (compile_fail not working here; see Issue #43707) -#[inline("always")] // error: unsupported literal -pub fn something() {} +```compile_fail,E0565 +#[repr("C")] // error: meta item in `repr` must be an identifier +struct Repr {} + +fn main() {} ``` Literals in attributes are new and largely unsupported in built-in attributes. @@ -12,6 +14,8 @@ Work to support literals where appropriate is ongoing. Try using an unquoted name instead: ``` -#[inline(always)] -pub fn something() {} +#[repr(C)] // ok! +struct Repr {} + +fn main() {} ``` From a575495accfe46384df0332be6d9c0a3fb151cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 17:14:38 +0100 Subject: [PATCH 0961/1253] Make `krate` private --- src/librustc/hir/map/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7e0e85ea5866f..1645420892a75 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -138,7 +138,7 @@ pub(super) type HirEntryMap<'hir> = IndexVec { - pub krate: &'hir Crate<'hir>, + krate: &'hir Crate<'hir>, pub dep_graph: DepGraph, From d646463a452d77dd7d5e1f8d0830d95bf867863f Mon Sep 17 00:00:00 2001 From: "Tom A. Wagner" Date: Thu, 6 Feb 2020 12:09:16 +0100 Subject: [PATCH 0962/1253] Mark fn map_or() as eagerly evaluated. In the docs for option.rs and result.rs, it is noted for all *_or() functions that they are eagerly evaluated, except for the map_or() function. This commit adds this missing documentation to the two files. --- src/libcore/option.rs | 6 ++++++ src/libcore/result.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index ad0491f888cc7..e35c91206b8d4 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -455,6 +455,12 @@ impl Option { /// Applies a function to the contained value (if any), /// or returns the provided default (if not). /// + /// Arguments passed to `map_or` are eagerly evaluated; if you are passing + /// the result of a function call, it is recommended to use [`map_or_else`], + /// which is lazily evaluated. + /// + /// [`map_or_else`]: #method.map_or_else + /// /// # Examples /// /// ``` diff --git a/src/libcore/result.rs b/src/libcore/result.rs index bc70dbd62eb52..809d4bace8e84 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -524,6 +524,12 @@ impl Result { /// Applies a function to the contained value (if any), /// or returns the provided default (if not). /// + /// Arguments passed to `map_or` are eagerly evaluated; if you are passing + /// the result of a function call, it is recommended to use [`map_or_else`], + /// which is lazily evaluated. + /// + /// [`map_or_else`]: #method.map_or_else + /// /// # Examples /// /// ``` From 8f286dbf27b61afdd96f632d0bc7f4c49fbb7d0f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 13 Dec 2019 23:21:14 +0200 Subject: [PATCH 0963/1253] rustc_errors: split macro backtrace rendering from <*macros> hacks. --- .../annotate_snippet_emitter_writer.rs | 2 +- src/librustc_errors/emitter.rs | 154 +++++++++++------- src/librustc_span/source_map.rs | 8 - 3 files changed, 97 insertions(+), 67 deletions(-) diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 009ab6ac5b12f..65d82f545e8f0 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -32,7 +32,7 @@ impl Emitter for AnnotateSnippetEmitterWriter { let mut children = diag.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); - self.fix_multispans_in_std_macros( + self.render_multispans_macro_backtrace_and_fix_extern_macros( &self.source_map, &mut primary_span, &mut children, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 1fcb36a2a3090..d32b8c689dc1d 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -280,10 +280,7 @@ pub trait Emitter { } } - // This does a small "fix" for multispans by looking to see if it can find any that - // point directly at <*macros>. Since these are often difficult to read, this - // will change the span to point at the use site. - fn fix_multispans_in_std_macros( + fn render_multispans_macro_backtrace_and_fix_extern_macros( &self, source_map: &Option>, span: &mut MultiSpan, @@ -291,61 +288,64 @@ pub trait Emitter { level: &Level, backtrace: bool, ) { - let mut spans_updated = self.fix_multispan_in_std_macros(source_map, span, backtrace); - for child in children.iter_mut() { - spans_updated |= - self.fix_multispan_in_std_macros(source_map, &mut child.span, backtrace); + self.render_multispans_macro_backtrace(source_map, span, children, backtrace); + + if !backtrace { + if self.fix_multispans_in_extern_macros(source_map, span, children) { + let msg = if level == &Error { + "this error originates in a macro outside of the current crate \ + (in Nightly builds, run with -Z external-macro-backtrace \ + for more info)" + .to_string() + } else { + "this warning originates in a macro outside of the current crate \ + (in Nightly builds, run with -Z external-macro-backtrace \ + for more info)" + .to_string() + }; + + children.push(SubDiagnostic { + level: Level::Note, + message: vec![(msg, Style::NoStyle)], + span: MultiSpan::new(), + render_span: None, + }); + } } - let msg = if level == &Error { - "this error originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z external-macro-backtrace \ - for more info)" - .to_string() - } else { - "this warning originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z external-macro-backtrace \ - for more info)" - .to_string() - }; + } - if spans_updated { - children.push(SubDiagnostic { - level: Level::Note, - message: vec![(msg, Style::NoStyle)], - span: MultiSpan::new(), - render_span: None, - }); + fn render_multispans_macro_backtrace( + &self, + source_map: &Option>, + span: &mut MultiSpan, + children: &mut Vec, + backtrace: bool, + ) { + self.render_multispan_macro_backtrace(source_map, span, backtrace); + for child in children.iter_mut() { + self.render_multispan_macro_backtrace(source_map, &mut child.span, backtrace); } } - // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of - // <*macros>. Since these locations are often difficult to read, we move these Spans from - // <*macros> to their corresponding use site. - fn fix_multispan_in_std_macros( + fn render_multispan_macro_backtrace( &self, source_map: &Option>, span: &mut MultiSpan, always_backtrace: bool, - ) -> bool { + ) { let sm = match source_map { Some(ref sm) => sm, - None => return false, + None => return, }; - let mut before_after: Vec<(Span, Span)> = vec![]; let mut new_labels: Vec<(Span, String)> = vec![]; // First, find all the spans in <*macros> and point instead at their use site - for sp in span.primary_spans() { + for &sp in span.primary_spans() { if sp.is_dummy() { continue; } - let call_sp = sm.call_span_if_macro(*sp); - if call_sp != *sp && !always_backtrace { - before_after.push((*sp, call_sp)); - } let macro_backtrace: Vec<_> = sp.macro_backtrace().collect(); - let backtrace_len = macro_backtrace.len(); for (i, trace) in macro_backtrace.iter().rev().enumerate() { // Only show macro locations that are local // and display them like a span_note @@ -358,13 +358,13 @@ pub trait Emitter { format!( "in this expansion of `{}`{}", trace.kind.descr(), - if backtrace_len > 2 { - // if backtrace_len == 1 it'll be pointed - // at by "in this macro invocation" + if macro_backtrace.len() > 2 { + // if macro_backtrace.len() == 1 it'll be + // pointed at by "in this macro invocation" format!(" (#{})", i + 1) } else { String::new() - } + }, ), )); } @@ -377,13 +377,13 @@ pub trait Emitter { trace.call_site, format!( "in this macro invocation{}", - if backtrace_len > 2 && always_backtrace { + if macro_backtrace.len() > 2 && always_backtrace { // only specify order when the macro // backtrace is multiple levels deep format!(" (#{})", i + 1) } else { String::new() - } + }, ), )); if !always_backtrace { @@ -395,20 +395,58 @@ pub trait Emitter { for (label_span, label_text) in new_labels { span.push_span_label(label_span, label_text); } - for sp_label in span.span_labels() { - if sp_label.span.is_dummy() { - continue; - } - if sm.span_to_filename(sp_label.span.clone()).is_macros() && !always_backtrace { - if let Some(use_site) = sp_label.span.macro_backtrace().last() { - before_after.push((sp_label.span, use_site.call_site)); - } - } + } + + // This does a small "fix" for multispans by looking to see if it can find any that + // point directly at <*macros>. Since these are often difficult to read, this + // will change the span to point at the use site. + fn fix_multispans_in_extern_macros( + &self, + source_map: &Option>, + span: &mut MultiSpan, + children: &mut Vec, + ) -> bool { + let mut spans_updated = self.fix_multispan_in_extern_macros(source_map, span); + for child in children.iter_mut() { + spans_updated |= self.fix_multispan_in_extern_macros(source_map, &mut child.span); } + spans_updated + } + + // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of + // <*macros>. Since these locations are often difficult to read, we move these Spans from + // <*macros> to their corresponding use site. + fn fix_multispan_in_extern_macros( + &self, + source_map: &Option>, + span: &mut MultiSpan, + ) -> bool { + let sm = match source_map { + Some(ref sm) => sm, + None => return false, + }; + + // First, find all the spans in <*macros> and point instead at their use site + let replacements: Vec<(Span, Span)> = span + .primary_spans() + .iter() + .copied() + .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) + .filter_map(|sp| { + if !sp.is_dummy() && sm.span_to_filename(sp).is_macros() { + let maybe_callsite = sp.source_callsite(); + if sp != maybe_callsite { + return Some((sp, maybe_callsite)); + } + } + None + }) + .collect(); + // After we have them, make sure we replace these 'bad' def sites with their use sites - let spans_updated = !before_after.is_empty(); - for (before, after) in before_after { - span.replace(before, after); + let spans_updated = !replacements.is_empty(); + for (from, to) in replacements { + span.replace(from, to); } spans_updated @@ -424,7 +462,7 @@ impl Emitter for EmitterWriter { let mut children = diag.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); - self.fix_multispans_in_std_macros( + self.render_multispans_macro_backtrace_and_fix_extern_macros( &self.sm, &mut primary_span, &mut children, diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index c250df43a2733..45c4d6dbc6cf4 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -945,14 +945,6 @@ impl SourceMap { _ => None, }) } - pub fn call_span_if_macro(&self, sp: Span) -> Span { - if self.span_to_filename(sp.clone()).is_macros() { - if let Some(use_site) = sp.macro_backtrace().last() { - return use_site.call_site; - } - } - sp - } } #[derive(Clone)] From f6fc80206e9600ae753cdfbd762fb982afca48b0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 15 Dec 2019 17:12:30 +0200 Subject: [PATCH 0964/1253] rustc: rename -Zexternal-macro-backtrace to -Zmacro-backtrace. --- src/bootstrap/builder.rs | 8 +++++- .../annotate_snippet_emitter_writer.rs | 8 +++--- src/librustc_errors/emitter.rs | 28 +++++++------------ src/librustc_errors/json.rs | 22 ++++++--------- src/librustc_errors/lib.rs | 8 +++--- src/librustc_session/config.rs | 2 +- src/librustc_session/options.rs | 4 +-- src/librustc_session/session.rs | 12 ++++---- .../borrowck-borrowed-uniq-rvalue-2.stderr | 2 +- src/test/ui/borrowck/issue-64453.stderr | 2 +- .../ui/codemap_tests/bad-format-args.stderr | 2 +- .../const-eval/const_fn_ptr_fail2.stderr | 4 +-- .../ui/consts/const-eval/const_panic.stderr | 6 ++-- .../const-eval/const_panic_libcore.stderr | 6 ++-- .../const_panic_libcore_main.stderr | 6 ++-- .../feature-gate-const_panic.stderr | 6 ++-- .../const-eval/panic-assoc-never-type.stderr | 2 +- .../consts/const-eval/panic-never-type.stderr | 2 +- .../const-external-macro-const-err.stderr | 2 +- .../ui/consts/control-flow/assert.both.stderr | 2 +- .../control-flow/assert.if_match.stderr | 4 +-- .../control-flow/issue-50577.if_match.stderr | 2 +- .../control-flow/issue-50577.stock.stderr | 8 +++--- .../control-flow/short-circuit.stock.stderr | 4 +-- .../min_const_fn/bad_const_fn_body_ice.stderr | 2 +- .../cross-crate-macro-backtrace/main.stderr | 2 +- .../ui/deprecation/deprecation-lint-2.stderr | 2 +- .../ui/deprecation/deprecation-lint-3.stderr | 2 +- src/test/ui/deref-suggestion.stderr | 2 +- .../ui/editions/edition-imports-2015.stderr | 2 +- .../ui/editions/edition-imports-2018.stderr | 2 +- .../edition-imports-virtual-2015-gated.stderr | 2 +- ...dition-keywords-2015-2018-expansion.stderr | 2 +- ...dition-keywords-2018-2018-expansion.stderr | 2 +- src/test/ui/hygiene/intercrate.stderr | 2 +- .../ui/hygiene/no_implicit_prelude.stderr | 2 +- src/test/ui/imports/import-crate-var.stderr | 2 +- .../internal/internal-unstable-noallow.stderr | 8 +++--- src/test/ui/issues/issue-13446.stderr | 2 +- src/test/ui/issues/issue-16966.stderr | 2 +- src/test/ui/issues/issue-2150.stderr | 2 +- src/test/ui/issues/issue-32829.stderr | 2 +- src/test/ui/issues/issue-34334.stderr | 2 +- src/test/ui/issues/issue-59488.stderr | 6 ++-- .../lifetimes/borrowck-let-suggestion.stderr | 2 +- src/test/ui/lint/lint-stability2.stderr | 2 +- src/test/ui/lint/lint-stability3.stderr | 2 +- src/test/ui/macro_backtrace/main.rs | 2 +- src/test/ui/macros/assert.stderr | 2 +- src/test/ui/macros/format-parse-errors.stderr | 2 +- .../macros/macro-local-data-key-priv.stderr | 2 +- .../ui/macros/must-use-in-macro-55516.stderr | 2 +- .../match/match-arm-resolving-to-never.stderr | 2 +- .../method-on-ambiguous-numeric-type.stderr | 2 +- .../feature-gate-never_type_fallback.stderr | 2 +- .../never_type/never-assign-dead-code.stderr | 2 +- src/test/ui/out-of-order-shadowing.stderr | 2 +- .../ui/privacy/private-inferred-type-3.stderr | 14 +++++----- src/test/ui/proc-macro/dollar-crate.stderr | 2 +- src/test/ui/reachable/expr_again.stderr | 2 +- src/test/ui/reachable/expr_block.stderr | 2 +- src/test/ui/reachable/expr_if.stderr | 2 +- src/test/ui/reachable/expr_loop.stderr | 6 ++-- src/test/ui/reachable/expr_match.stderr | 4 +-- .../regions-var-type-out-of-scope.stderr | 2 +- .../dbg-macro-move-semantics.stderr | 2 +- .../dbg-macro-requires-debug.stderr | 2 +- src/test/ui/span/coerce-suggestions.stderr | 2 +- src/test/ui/span/issue-33884.stderr | 2 +- src/test/ui/span/slice-borrow.stderr | 2 +- ...gest-deref-inside-macro-issue-58298.stderr | 2 +- .../dont-suggest-try_into-in-macros.stderr | 2 +- .../mut-borrow-needed-by-trait.stderr | 2 +- .../suggestions/vec-macro-in-pattern.stderr | 2 +- .../ui/try-block/try-block-opt-init.stderr | 2 +- .../ui/type/ascription/issue-47666.stderr | 2 +- .../cannot_infer_local_or_vec.stderr | 2 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- src/test/ui/unreachable-code-ret.stderr | 2 +- 79 files changed, 141 insertions(+), 149 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 18f6fda760846..d12ee2935ebf5 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -847,7 +847,13 @@ impl<'a> Builder<'a> { rustflags.arg("-Zforce-unstable-if-unmarked"); } - rustflags.arg("-Zexternal-macro-backtrace"); + // cfg(bootstrap): the flag was renamed from `-Zexternal-macro-backtrace` + // to `-Zmacro-backtrace`, keep only the latter after beta promotion. + if stage == 0 { + rustflags.arg("-Zexternal-macro-backtrace"); + } else { + rustflags.arg("-Zmacro-backtrace"); + } let want_rustdoc = self.doc_tests != DocTests::No; diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 65d82f545e8f0..1eda1c9200f6e 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -23,7 +23,7 @@ pub struct AnnotateSnippetEmitterWriter { /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs. ui_testing: bool, - external_macro_backtrace: bool, + macro_backtrace: bool, } impl Emitter for AnnotateSnippetEmitterWriter { @@ -37,7 +37,7 @@ impl Emitter for AnnotateSnippetEmitterWriter { &mut primary_span, &mut children, &diag.level, - self.external_macro_backtrace, + self.macro_backtrace, ); self.emit_messages_default( @@ -172,9 +172,9 @@ impl AnnotateSnippetEmitterWriter { pub fn new( source_map: Option>, short_message: bool, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> Self { - Self { source_map, short_message, ui_testing: false, external_macro_backtrace } + Self { source_map, short_message, ui_testing: false, macro_backtrace } } /// Allows to modify `Self` to enable or disable the `ui_testing` flag. diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index d32b8c689dc1d..59493b4a683b0 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -54,19 +54,11 @@ impl HumanReadableErrorType { source_map: Option>, teach: bool, terminal_width: Option, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); - EmitterWriter::new( - dst, - source_map, - short, - teach, - color, - terminal_width, - external_macro_backtrace, - ) + EmitterWriter::new(dst, source_map, short, teach, color, terminal_width, macro_backtrace) } } @@ -294,12 +286,12 @@ pub trait Emitter { if self.fix_multispans_in_extern_macros(source_map, span, children) { let msg = if level == &Error { "this error originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z external-macro-backtrace \ + (in Nightly builds, run with -Z macro-backtrace \ for more info)" .to_string() } else { "this warning originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z external-macro-backtrace \ + (in Nightly builds, run with -Z macro-backtrace \ for more info)" .to_string() }; @@ -467,7 +459,7 @@ impl Emitter for EmitterWriter { &mut primary_span, &mut children, &diag.level, - self.external_macro_backtrace, + self.macro_backtrace, ); self.emit_messages_default( @@ -546,7 +538,7 @@ pub struct EmitterWriter { ui_testing: bool, terminal_width: Option, - external_macro_backtrace: bool, + macro_backtrace: bool, } #[derive(Debug)] @@ -563,7 +555,7 @@ impl EmitterWriter { short_message: bool, teach: bool, terminal_width: Option, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> EmitterWriter { let dst = Destination::from_stderr(color_config); EmitterWriter { @@ -573,7 +565,7 @@ impl EmitterWriter { teach, ui_testing: false, terminal_width, - external_macro_backtrace, + macro_backtrace, } } @@ -584,7 +576,7 @@ impl EmitterWriter { teach: bool, colored: bool, terminal_width: Option, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> EmitterWriter { EmitterWriter { dst: Raw(dst, colored), @@ -593,7 +585,7 @@ impl EmitterWriter { teach, ui_testing: false, terminal_width, - external_macro_backtrace, + macro_backtrace, } } diff --git a/src/librustc_errors/json.rs b/src/librustc_errors/json.rs index 3ddf9b09893ba..ffdff6acec5de 100644 --- a/src/librustc_errors/json.rs +++ b/src/librustc_errors/json.rs @@ -36,7 +36,7 @@ pub struct JsonEmitter { pretty: bool, ui_testing: bool, json_rendered: HumanReadableErrorType, - external_macro_backtrace: bool, + macro_backtrace: bool, } impl JsonEmitter { @@ -45,7 +45,7 @@ impl JsonEmitter { source_map: Lrc, pretty: bool, json_rendered: HumanReadableErrorType, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> JsonEmitter { JsonEmitter { dst: Box::new(io::stderr()), @@ -54,14 +54,14 @@ impl JsonEmitter { pretty, ui_testing: false, json_rendered, - external_macro_backtrace, + macro_backtrace, } } pub fn basic( pretty: bool, json_rendered: HumanReadableErrorType, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); JsonEmitter::stderr( @@ -69,7 +69,7 @@ impl JsonEmitter { Lrc::new(SourceMap::new(file_path_mapping)), pretty, json_rendered, - external_macro_backtrace, + macro_backtrace, ) } @@ -79,7 +79,7 @@ impl JsonEmitter { source_map: Lrc, pretty: bool, json_rendered: HumanReadableErrorType, - external_macro_backtrace: bool, + macro_backtrace: bool, ) -> JsonEmitter { JsonEmitter { dst, @@ -88,7 +88,7 @@ impl JsonEmitter { pretty, ui_testing: false, json_rendered, - external_macro_backtrace, + macro_backtrace, } } @@ -245,13 +245,7 @@ impl Diagnostic { let buf = BufWriter::default(); let output = buf.clone(); je.json_rendered - .new_emitter( - Box::new(buf), - Some(je.sm.clone()), - false, - None, - je.external_macro_backtrace, - ) + .new_emitter(Box::new(buf), Some(je.sm.clone()), false, None, je.macro_backtrace) .ui_testing(je.ui_testing) .emit_diagnostic(diag); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 17b293401f89e..97667febc3ca2 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -336,9 +336,9 @@ pub struct HandlerFlags { /// If true, immediately print bugs registered with `delay_span_bug`. /// (rustc: see `-Z report-delayed-bugs`) pub report_delayed_bugs: bool, - /// show macro backtraces even for non-local macros. - /// (rustc: see `-Z external-macro-backtrace`) - pub external_macro_backtrace: bool, + /// Show macro backtraces. + /// (rustc: see `-Z macro-backtrace`) + pub macro_backtrace: bool, /// If true, identical diagnostics are reported only once. pub deduplicate_diagnostics: bool, } @@ -385,7 +385,7 @@ impl Handler { false, false, None, - flags.external_macro_backtrace, + flags.macro_backtrace, )); Self::with_emitter_and_flags(emitter, flags) } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index ad1a6c4906ea3..75b5e37b2df69 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -624,7 +624,7 @@ impl DebuggingOptions { treat_err_as_bug: self.treat_err_as_bug, dont_buffer_diagnostics: self.dont_buffer_diagnostics, report_delayed_bugs: self.report_delayed_bugs, - external_macro_backtrace: self.external_macro_backtrace, + macro_backtrace: self.macro_backtrace, deduplicate_diagnostics: self.deduplicate_diagnostics.unwrap_or(true), } } diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index d6b71641da52f..0250c40bcdcf1 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -776,8 +776,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "treat error number `val` that occurs as bug"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], "immediately print bugs registered with `delay_span_bug`"), - external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], - "show macro backtraces even for non-local macros"), + macro_backtrace: bool = (false, parse_bool, [UNTRACKED], + "show macro backtraces"), teach: bool = (false, parse_bool, [TRACKED], "show extended diagnostic help"), terminal_width: Option = (None, parse_opt_uint, [UNTRACKED], diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 70984917d7ca2..648dd6ad32a6b 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -858,7 +858,7 @@ fn default_emitter( source_map: &Lrc, emitter_dest: Option>, ) -> Box { - let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; + let macro_backtrace = sopts.debugging_opts.macro_backtrace; match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(kind), dst) => { let (short, color_config) = kind.unzip(); @@ -867,7 +867,7 @@ fn default_emitter( let emitter = AnnotateSnippetEmitterWriter::new( Some(source_map.clone()), short, - external_macro_backtrace, + macro_backtrace, ); Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing())) } else { @@ -878,7 +878,7 @@ fn default_emitter( short, sopts.debugging_opts.teach, sopts.debugging_opts.terminal_width, - external_macro_backtrace, + macro_backtrace, ), Some(dst) => EmitterWriter::new( dst, @@ -887,7 +887,7 @@ fn default_emitter( false, // no teach messages when writing to a buffer false, // no colors when writing to a buffer None, // no terminal width - external_macro_backtrace, + macro_backtrace, ), }; Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing())) @@ -899,7 +899,7 @@ fn default_emitter( source_map.clone(), pretty, json_rendered, - external_macro_backtrace, + macro_backtrace, ) .ui_testing(sopts.debugging_opts.ui_testing()), ), @@ -910,7 +910,7 @@ fn default_emitter( source_map.clone(), pretty, json_rendered, - external_macro_backtrace, + macro_backtrace, ) .ui_testing(sopts.debugging_opts.ui_testing()), ), diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr index 1dd18c12fc8de..d0250d862fcc4 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr @@ -9,7 +9,7 @@ LL | x.x[0]; | ------ borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr index 0b66426aa2a0f..3a7f13f5bba8c 100644 --- a/src/test/ui/borrowck/issue-64453.stderr +++ b/src/test/ui/borrowck/issue-64453.stderr @@ -6,7 +6,7 @@ LL | static settings_dir: String = format!(""); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index 17d4df2a22324..66ff9508db796 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -4,7 +4,7 @@ error: requires at least a format string argument LL | format!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: expected token: `,` --> $DIR/bad-format-args.rs:3:16 diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index f99505c30901d..15dd84fa7ed3f 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -12,7 +12,7 @@ LL | assert_eq!(Y, 4); | | | referenced constant has errors | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant expression failed --> $DIR/const_fn_ptr_fail2.rs:22:5 @@ -22,7 +22,7 @@ LL | assert_eq!(Z, 4); | | | referenced constant has errors | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index 1b006c69cfd6e..bbbe70510306e 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -7,7 +7,7 @@ LL | pub const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:4:19 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic.rs:7:19 @@ -17,7 +17,7 @@ LL | pub const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:7:19 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic.rs:10:19 @@ -27,7 +27,7 @@ LL | pub const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:10:19 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic_libcore.stderr b/src/test/ui/consts/const-eval/const_panic_libcore.stderr index abc844e984261..cedeabeadeb59 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore.stderr @@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore.rs:5:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore.rs:8:15 @@ -17,7 +17,7 @@ LL | const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore.rs:8:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore.rs:11:15 @@ -27,7 +27,7 @@ LL | const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore.rs:11:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr index 24ddefe01b5f9..3e8bea4d069ba 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr @@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:9:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore_main.rs:12:15 @@ -17,7 +17,7 @@ LL | const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:12:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore_main.rs:15:15 @@ -27,7 +27,7 @@ LL | const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_main.rs:15:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr index ac0ff7025d1c0..e3b20e4147ab3 100644 --- a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr +++ b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr @@ -6,7 +6,7 @@ LL | const Z: () = panic!("cheese"); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/feature-gate-const_panic.rs:9:15 @@ -16,7 +16,7 @@ LL | const X: () = unimplemented!(); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/feature-gate-const_panic.rs:6:15 @@ -26,7 +26,7 @@ LL | const Y: () = unreachable!(); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr index d09a295264c62..1cdbe6c887f6d 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![warn(const_err)] | ^^^^^^^^^ - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: erroneous constant used --> $DIR/panic-assoc-never-type.rs:16:13 diff --git a/src/test/ui/consts/const-eval/panic-never-type.stderr b/src/test/ui/consts/const-eval/panic-never-type.stderr index 3daad0a2fdd8c..ae142897b3704 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-never-type.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![warn(const_err)] | ^^^^^^^^^ - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: erroneous constant used --> $DIR/panic-never-type.rs:12:13 diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr index 237c4d792c9ea..c3808391c7822 100644 --- a/src/test/ui/consts/const-external-macro-const-err.stderr +++ b/src/test/ui/consts/const-external-macro-const-err.stderr @@ -5,7 +5,7 @@ LL | static_assert!(2 + 2 == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/assert.both.stderr b/src/test/ui/consts/control-flow/assert.both.stderr index 44769175f0ee9..e0e3df1193f55 100644 --- a/src/test/ui/consts/control-flow/assert.both.stderr +++ b/src/test/ui/consts/control-flow/assert.both.stderr @@ -7,7 +7,7 @@ LL | const _: () = assert!(false); | the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:12:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/assert.if_match.stderr b/src/test/ui/consts/control-flow/assert.if_match.stderr index 9c8963f6c7b28..3f4719b681cbd 100644 --- a/src/test/ui/consts/control-flow/assert.if_match.stderr +++ b/src/test/ui/consts/control-flow/assert.if_match.stderr @@ -6,7 +6,7 @@ LL | const _: () = assert!(true); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/assert.rs:12:15 @@ -16,7 +16,7 @@ LL | const _: () = assert!(false); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr index 6771224e6cf5e..5a7f10e2ee40a 100644 --- a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr +++ b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr @@ -9,7 +9,7 @@ LL | Drop = assert_eq!(1, 1) | = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/issue-50577.stock.stderr b/src/test/ui/consts/control-flow/issue-50577.stock.stderr index 7d637f5aa9671..1eeda43b41c30 100644 --- a/src/test/ui/consts/control-flow/issue-50577.stock.stderr +++ b/src/test/ui/consts/control-flow/issue-50577.stock.stderr @@ -6,7 +6,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `if` is not allowed in a `const` --> $DIR/issue-50577.rs:7:16 @@ -16,7 +16,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `match` is not allowed in a `const` --> $DIR/issue-50577.rs:7:16 @@ -26,7 +26,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0317]: `if` may be missing an `else` clause --> $DIR/issue-50577.rs:7:16 @@ -39,7 +39,7 @@ LL | Drop = assert_eq!(1, 1) | = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/control-flow/short-circuit.stock.stderr b/src/test/ui/consts/control-flow/short-circuit.stock.stderr index cf0de929593db..6fcb7cafff284 100644 --- a/src/test/ui/consts/control-flow/short-circuit.stock.stderr +++ b/src/test/ui/consts/control-flow/short-circuit.stock.stderr @@ -7,7 +7,7 @@ LL | const _: bool = true || panic!(); | the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:10:25 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/short-circuit.rs:11:26 @@ -17,7 +17,7 @@ LL | const _: bool = false && panic!(); | | | the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:11:26 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index ecfd30e7b4439..9786e2e353cca 100644 --- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -6,7 +6,7 @@ LL | vec![1, 2, 3] | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add `#![feature(const_fn)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr b/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr index b6ebe0ff1fc04..4421ce9c7d331 100644 --- a/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr +++ b/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr @@ -4,7 +4,7 @@ error: 1 positional argument in format string, but no arguments were given LL | myprintln!("{}"); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr index e8c2156742f0d..1f9c5e3d7690b 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.stderr +++ b/src/test/ui/deprecation/deprecation-lint-2.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr index 7cc06a23b0fe3..f675b6af958f5 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.stderr +++ b/src/test/ui/deprecation/deprecation-lint-3.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 226f6fb620fc2..f4843469ccefc 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types LL | assert_eq!(3i32, &3i32); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:39:17 diff --git a/src/test/ui/editions/edition-imports-2015.stderr b/src/test/ui/editions/edition-imports-2015.stderr index 4aba5323cc575..4b7be3cf98dfe 100644 --- a/src/test/ui/editions/edition-imports-2015.stderr +++ b/src/test/ui/editions/edition-imports-2015.stderr @@ -4,7 +4,7 @@ error: cannot glob-import all possible crates LL | gen_glob!(); | ^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-imports-2018.stderr b/src/test/ui/editions/edition-imports-2018.stderr index 6ef49b6256058..d83934ccc239e 100644 --- a/src/test/ui/editions/edition-imports-2018.stderr +++ b/src/test/ui/editions/edition-imports-2018.stderr @@ -4,7 +4,7 @@ error: cannot glob-import all possible crates LL | gen_glob!(); | ^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr index e6d0f18a67722..43a4c8a361fd9 100644 --- a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr +++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr @@ -4,7 +4,7 @@ error[E0432]: unresolved import `E` LL | gen_gated!(); | ^^^^^^^^^^^^^ could not find `E` in `{{root}}` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr index 04a70cf98302f..f4b41d3accc51 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr @@ -4,7 +4,7 @@ error: expected identifier, found keyword `async` LL | produces_async! {} | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | LL | () => (pub fn r#async () { }) diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr index fb12051eed409..d747b8232ebc3 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr @@ -4,7 +4,7 @@ error: expected identifier, found keyword `async` LL | produces_async! {} | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | LL | () => (pub fn r#async () { }) diff --git a/src/test/ui/hygiene/intercrate.stderr b/src/test/ui/hygiene/intercrate.stderr index 30a5570b2ad0e..75347d6e8c950 100644 --- a/src/test/ui/hygiene/intercrate.stderr +++ b/src/test/ui/hygiene/intercrate.stderr @@ -4,7 +4,7 @@ error: type `fn() -> u32 {intercrate::foo::bar::f}` is private LL | assert_eq!(intercrate::foo::m!(), 1); | ^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) 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 5d75f5034bc65..a466471d5e4ec 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -4,7 +4,7 @@ error: cannot find macro `panic` in this scope LL | assert_eq!(0, 0); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared type or module `Vec` --> $DIR/no_implicit_prelude.rs:11:9 diff --git a/src/test/ui/imports/import-crate-var.stderr b/src/test/ui/imports/import-crate-var.stderr index 85f15ad4648a7..11eca073f9558 100644 --- a/src/test/ui/imports/import-crate-var.stderr +++ b/src/test/ui/imports/import-crate-var.stderr @@ -4,7 +4,7 @@ error: `$crate` may not be imported LL | m!(); | ^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/internal/internal-unstable-noallow.stderr b/src/test/ui/internal/internal-unstable-noallow.stderr index 5a3a2356150dd..873d8f898811f 100644 --- a/src/test/ui/internal/internal-unstable-noallow.stderr +++ b/src/test/ui/internal/internal-unstable-noallow.stderr @@ -5,7 +5,7 @@ LL | call_unstable_noallow!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(function)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct_field' --> $DIR/internal-unstable-noallow.rs:18:5 @@ -14,7 +14,7 @@ LL | construct_unstable_noallow!(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(struct_field)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'method' --> $DIR/internal-unstable-noallow.rs:20:35 @@ -23,7 +23,7 @@ LL | |x: internal_unstable::Foo| { call_method_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(method)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct2_field' --> $DIR/internal-unstable-noallow.rs:22:35 @@ -32,7 +32,7 @@ LL | |x: internal_unstable::Bar| { access_field_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(struct2_field)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-13446.stderr b/src/test/ui/issues/issue-13446.stderr index 13c35dd84f7c5..fbafae5e6344c 100644 --- a/src/test/ui/issues/issue-13446.stderr +++ b/src/test/ui/issues/issue-13446.stderr @@ -6,7 +6,7 @@ LL | static VEC: [u32; 256] = vec![]; | = note: expected array `[u32; 256]` found struct `std::vec::Vec<_>` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr index 49a12cc200947..dc715e2858b47 100644 --- a/src/test/ui/issues/issue-16966.stderr +++ b/src/test/ui/issues/issue-16966.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | panic!(std::default::Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2150.stderr b/src/test/ui/issues/issue-2150.stderr index 3f3702551069f..f3de6941cfe94 100644 --- a/src/test/ui/issues/issue-2150.stderr +++ b/src/test/ui/issues/issue-2150.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32829.stderr b/src/test/ui/issues/issue-32829.stderr index b620abbf436d7..25da3f6a55065 100644 --- a/src/test/ui/issues/issue-32829.stderr +++ b/src/test/ui/issues/issue-32829.stderr @@ -6,7 +6,7 @@ LL | static S : u64 = { { panic!("foo"); 0 } }; | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index c52ea4ef9daa9..8d20377be576a 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -33,7 +33,7 @@ LL | let sr: Vec<(u32, _, _) = vec![]; | = note: expected type `bool` found struct `std::vec::Vec<_>` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0070]: invalid left-hand side of assignment --> $DIR/issue-34334.rs:2:29 diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 35ada71a1f128..4e5cf23afe143 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -80,7 +80,7 @@ LL | assert_eq!(Foo::Bar, i); | fn(usize) -> Foo {Foo::Bar} | = note: an implementation of `std::cmp::PartialEq` might be missing for `fn(usize) -> Foo {Foo::Bar}` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` --> $DIR/issue-59488.rs:30:5 @@ -91,7 +91,7 @@ LL | assert_eq!(Foo::Bar, i); = help: the trait `std::fmt::Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn(usize) -> Foo {Foo::Bar}` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` --> $DIR/issue-59488.rs:30:5 @@ -102,7 +102,7 @@ LL | assert_eq!(Foo::Bar, i); = help: the trait `std::fmt::Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn(usize) -> Foo {Foo::Bar}` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index 0e2fc0a0fe97e..10d05fd8f2b1b 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -10,7 +10,7 @@ LL | x.use_mut(); | - borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr index 5bac22594d665..bf737bcc0e347 100644 --- a/src/test/ui/lint/lint-stability2.stderr +++ b/src/test/ui/lint/lint-stability2.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr index 566734743caba..29b19577f440f 100644 --- a/src/test/ui/lint/lint-stability3.stderr +++ b/src/test/ui/lint/lint-stability3.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macro_backtrace/main.rs b/src/test/ui/macro_backtrace/main.rs index 8fcd497f87b78..05f35855861f5 100644 --- a/src/test/ui/macro_backtrace/main.rs +++ b/src/test/ui/macro_backtrace/main.rs @@ -1,6 +1,6 @@ // Test that the macro backtrace facility works // aux-build:ping.rs -// compile-flags: -Z external-macro-backtrace +// compile-flags: -Z macro-backtrace #[macro_use] extern crate ping; diff --git a/src/test/ui/macros/assert.stderr b/src/test/ui/macros/assert.stderr index fa604506b9464..4bbdf01150c4c 100644 --- a/src/test/ui/macros/assert.stderr +++ b/src/test/ui/macros/assert.stderr @@ -16,7 +16,7 @@ error: macro requires a boolean expression as an argument LL | debug_assert!(); | ^^^^^^^^^^^^^^^^ boolean expression required | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/assert.rs:5:19 diff --git a/src/test/ui/macros/format-parse-errors.stderr b/src/test/ui/macros/format-parse-errors.stderr index 02b704299ff05..0c10fb644b0f6 100644 --- a/src/test/ui/macros/format-parse-errors.stderr +++ b/src/test/ui/macros/format-parse-errors.stderr @@ -4,7 +4,7 @@ error: requires at least a format string argument LL | format!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/format-parse-errors.rs:5:13 diff --git a/src/test/ui/macros/macro-local-data-key-priv.stderr b/src/test/ui/macros/macro-local-data-key-priv.stderr index 72994d1652cd0..5519105ca9a54 100644 --- a/src/test/ui/macros/macro-local-data-key-priv.stderr +++ b/src/test/ui/macros/macro-local-data-key-priv.stderr @@ -9,7 +9,7 @@ note: the constant `baz` is defined here | LL | thread_local!(static baz: f64 = 0.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr index 302c8aa7e6a55..a8ee9cf255628 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.stderr +++ b/src/test/ui/macros/must-use-in-macro-55516.stderr @@ -6,5 +6,5 @@ LL | write!(&mut example, "{}", 42); | = note: `-W unused-must-use` implied by `-W unused` = note: this `Result` may be an `Err` variant, which should be handled - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr index 3a723de9f6b8a..a824e3565509d 100644 --- a/src/test/ui/match/match-arm-resolving-to-never.stderr +++ b/src/test/ui/match/match-arm-resolving-to-never.stderr @@ -13,7 +13,7 @@ LL | | E::F => "", LL | | }; | |_____- `match` arms have incompatible types | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr index d9e250882e1c1..277bcce6af9c5 100644 --- a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr +++ b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr @@ -47,7 +47,7 @@ LL | mac!(bar); LL | bar.pow(2); | ^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 08e16f4693645..8f7d68737bc09 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -8,7 +8,7 @@ LL | panic!() | -------- this returned value is of type `!` | = note: the return type of a function must have a statically known size - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/never_type/never-assign-dead-code.stderr b/src/test/ui/never_type/never-assign-dead-code.stderr index f0a11ae1bcc28..ef48083d67061 100644 --- a/src/test/ui/never_type/never-assign-dead-code.stderr +++ b/src/test/ui/never_type/never-assign-dead-code.stderr @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable call --> $DIR/never-assign-dead-code.rs:10:5 diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr index 2a120dee482df..eb93cfe774b9c 100644 --- a/src/test/ui/out-of-order-shadowing.stderr +++ b/src/test/ui/out-of-order-shadowing.stderr @@ -14,7 +14,7 @@ note: `bar` could also refer to the macro defined here | LL | macro_rules! bar { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr index 61cd84762978c..4f57b17660ee5 100644 --- a/src/test/ui/privacy/private-inferred-type-3.stderr +++ b/src/test/ui/privacy/private-inferred-type-3.stderr @@ -4,7 +4,7 @@ error: type `fn() {ext::priv_fn}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: static `PRIV_STATIC` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -12,7 +12,7 @@ error: static `PRIV_STATIC` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: type `ext::PrivEnum` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -20,7 +20,7 @@ error: type `ext::PrivEnum` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn() {::method}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -28,7 +28,7 @@ error: type `fn() {::method}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -36,7 +36,7 @@ error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -44,7 +44,7 @@ error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -52,7 +52,7 @@ error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is priv LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 7 previous errors diff --git a/src/test/ui/proc-macro/dollar-crate.stderr b/src/test/ui/proc-macro/dollar-crate.stderr index 5d78a8e198729..b9d9f9842bcee 100644 --- a/src/test/ui/proc-macro/dollar-crate.stderr +++ b/src/test/ui/proc-macro/dollar-crate.stderr @@ -22,7 +22,7 @@ LL | dollar_crate_external::external!(); | previous definition of the type `D` here | = note: `D` must be defined only once in the type namespace of this module - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr index a9b5832ba2c88..805c965a87903 100644 --- a/src/test/ui/reachable/expr_again.stderr +++ b/src/test/ui/reachable/expr_again.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index 8b696b7abcb72..bd0c926279632 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -20,7 +20,7 @@ LL | return; LL | println!("foo"); | ^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index 6ae635ae4b7e8..bfb4675df1186 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -24,7 +24,7 @@ LL | return; LL | println!("But I am."); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index e5d395254a06d..dd294ddccd970 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:21:5 @@ -21,7 +21,7 @@ LL | loop { return; } LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:32:5 @@ -31,7 +31,7 @@ LL | loop { 'middle: loop { loop { break 'middle; } } } LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index a8317192c2b32..796cbba12a2b1 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_match.rs:19:5 @@ -21,7 +21,7 @@ LL | match () { () if false => return, () => return } LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr index 146fb8fd81fc6..b15ed910a4feb 100644 --- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr +++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr @@ -9,7 +9,7 @@ LL | assert_eq!(*x, 3); | ------------------ borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr index 5f0b3a1d40b7e..58ba38d1304fa 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr @@ -8,7 +8,7 @@ LL | let _ = dbg!(a); LL | let _ = dbg!(a); | ^ value used here after move | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index ecab673953d6d..460561997e163 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -8,7 +8,7 @@ LL | let _: NotDebug = dbg!(NotDebug); = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&NotDebug` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 343644006b153..ee1f99e3b07b4 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types LL | s = format!("foo"); | ^^^^^^^^^^^^^^ expected `&mut std::string::String`, found struct `std::string::String` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index 4f46c4c739436..3d00ef29052e9 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | stream.write_fmt(format!("message received")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::fmt::Arguments`, found struct `std::string::String` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index 84d0c847b7bdc..b28e3cf8d666e 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -10,7 +10,7 @@ LL | y.use_ref(); | - borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index e37edc1dacafa..fe2583eafe505 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -9,7 +9,7 @@ LL | | }; | |______expected `&str`, found struct `std::string::String` | in this macro invocation | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr index 1f2252f4d4375..092503cdf8063 100644 --- a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr +++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | assert_eq!(10u64, 10usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 2c3c07c19e7bd..5d26366fe83c6 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -33,7 +33,7 @@ LL | writeln!(fp, "hello world").unwrap(); | = note: the method `write_fmt` exists but the following trait bounds were not satisfied: `std::io::BufWriter<&dyn std::io::Write> : std::io::Write` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr index 1634fdde7d295..a69502de786f0 100644 --- a/src/test/ui/suggestions/vec-macro-in-pattern.stderr +++ b/src/test/ui/suggestions/vec-macro-in-pattern.stderr @@ -10,7 +10,7 @@ LL | Some(vec![_x]) => (), | help: use a slice pattern here instead: `[_x]` | = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr index 308906477d914..d88397f398f88 100644 --- a/src/test/ui/try-block/try-block-opt-init.stderr +++ b/src/test/ui/try-block/try-block-opt-init.stderr @@ -4,7 +4,7 @@ error[E0381]: borrow of possibly-uninitialized variable: `cfg_res` LL | assert_eq!(cfg_res, 5); | ^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `cfg_res` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr index 648635f0c32fa..d6f4a8d761914 100644 --- a/src/test/ui/type/ascription/issue-47666.stderr +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -11,7 +11,7 @@ LL | let _ = Option:Some(vec![0, 1]); | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` = note: for more information, see https://github.com/rust-lang/rust/issues/23416 - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 53cc769bae3cf..7f0de3f1d70de 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -6,7 +6,7 @@ LL | let x = vec![]; | | | consider giving `x` the explicit type `std::vec::Vec`, where the type parameter `T` is specified | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index df7228ce9f2a8..1fa436c216b37 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -6,7 +6,7 @@ LL | let (x, ) = (vec![], ); | | | consider giving this pattern the explicit type `(std::vec::Vec,)`, where the type parameter `T` is specified | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/unreachable-code-ret.stderr b/src/test/ui/unreachable-code-ret.stderr index 3b93ef97f3206..021f8b03eab3a 100644 --- a/src/test/ui/unreachable-code-ret.stderr +++ b/src/test/ui/unreachable-code-ret.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error From 5eaa9a150d470019ac0924ece7a23a0d1cefe5f4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 15 Jan 2020 17:50:26 +0200 Subject: [PATCH 0965/1253] rustc_errors: deduplicate the -Zmacro-backtrace suggestion message. --- src/librustc_errors/emitter.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 59493b4a683b0..a57b59a196293 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -14,7 +14,6 @@ use rustc_span::{MultiSpan, SourceFile, Span}; use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString}; use crate::styled_buffer::StyledBuffer; -use crate::Level::Error; use crate::{ pluralize, CodeSuggestion, Diagnostic, DiagnosticId, Level, SubDiagnostic, SuggestionStyle, }; @@ -284,17 +283,11 @@ pub trait Emitter { if !backtrace { if self.fix_multispans_in_extern_macros(source_map, span, children) { - let msg = if level == &Error { - "this error originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z macro-backtrace \ - for more info)" - .to_string() - } else { - "this warning originates in a macro outside of the current crate \ - (in Nightly builds, run with -Z macro-backtrace \ - for more info)" - .to_string() - }; + let msg = format!( + "this {} originates in a macro outside of the current crate \ + (in Nightly builds, run with -Z macro-backtrace for more info)", + level, + ); children.push(SubDiagnostic { level: Level::Note, From ab080973cb3bfa96f71b7d29fc5c3e34893cf896 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 15 Dec 2019 17:47:51 +0200 Subject: [PATCH 0966/1253] rustc_errors: hide "in this macro invocation" when redundant, more explicitly. --- .../annotate_snippet_emitter_writer.rs | 2 +- src/librustc_errors/emitter.rs | 63 +++++++++++-------- src/test/ui/macros/same-sequence-span.stderr | 5 +- src/test/ui/proc-macro/generate-mod.stderr | 10 +-- .../proc-macro/invalid-punct-ident-4.stderr | 5 +- .../ui/proc-macro/lints_in_proc_macros.stderr | 5 +- src/test/ui/proc-macro/mixed-site-span.stderr | 10 +-- src/test/ui/proc-macro/subspan.stderr | 16 ++--- ...gest-deref-inside-macro-issue-58298.stderr | 5 +- 9 files changed, 53 insertions(+), 68 deletions(-) diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 1eda1c9200f6e..d83175694f407 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -32,7 +32,7 @@ impl Emitter for AnnotateSnippetEmitterWriter { let mut children = diag.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); - self.render_multispans_macro_backtrace_and_fix_extern_macros( + self.fix_multispans_in_extern_macros_and_render_macro_backtrace( &self.source_map, &mut primary_span, &mut children, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a57b59a196293..4857ff47462c8 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -271,7 +271,7 @@ pub trait Emitter { } } - fn render_multispans_macro_backtrace_and_fix_extern_macros( + fn fix_multispans_in_extern_macros_and_render_macro_backtrace( &self, source_map: &Option>, span: &mut MultiSpan, @@ -279,10 +279,16 @@ pub trait Emitter { level: &Level, backtrace: bool, ) { - self.render_multispans_macro_backtrace(source_map, span, children, backtrace); + let mut external_spans_updated = false; + if !backtrace { + external_spans_updated = + self.fix_multispans_in_extern_macros(source_map, span, children); + } + + self.render_multispans_macro_backtrace(span, children, backtrace); if !backtrace { - if self.fix_multispans_in_extern_macros(source_map, span, children) { + if external_spans_updated { let msg = format!( "this {} originates in a macro outside of the current crate \ (in Nightly builds, run with -Z macro-backtrace for more info)", @@ -301,42 +307,33 @@ pub trait Emitter { fn render_multispans_macro_backtrace( &self, - source_map: &Option>, span: &mut MultiSpan, children: &mut Vec, backtrace: bool, ) { - self.render_multispan_macro_backtrace(source_map, span, backtrace); + self.render_multispan_macro_backtrace(span, backtrace); for child in children.iter_mut() { - self.render_multispan_macro_backtrace(source_map, &mut child.span, backtrace); + self.render_multispan_macro_backtrace(&mut child.span, backtrace); } } - fn render_multispan_macro_backtrace( - &self, - source_map: &Option>, - span: &mut MultiSpan, - always_backtrace: bool, - ) { - let sm = match source_map { - Some(ref sm) => sm, - None => return, - }; - + fn render_multispan_macro_backtrace(&self, span: &mut MultiSpan, always_backtrace: bool) { let mut new_labels: Vec<(Span, String)> = vec![]; - // First, find all the spans in <*macros> and point instead at their use site for &sp in span.primary_spans() { if sp.is_dummy() { continue; } + + // FIXME(eddyb) use `retain` on `macro_backtrace` to remove all the + // entries we don't want to print, to make sure the indices being + // printed are contiguous (or omitted if there's only one entry). let macro_backtrace: Vec<_> = sp.macro_backtrace().collect(); for (i, trace) in macro_backtrace.iter().rev().enumerate() { - // Only show macro locations that are local - // and display them like a span_note if trace.def_site.is_dummy() { continue; } + if always_backtrace { new_labels.push(( trace.def_site, @@ -353,9 +350,21 @@ pub trait Emitter { ), )); } - // Check to make sure we're not in any <*macros> - if !sm.span_to_filename(trace.def_site).is_macros() - && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _)) + + // Don't add a label on the call site if the diagnostic itself + // already points to (a part of) that call site, as the label + // is meant for showing the relevant invocation when the actual + // diagnostic is pointing to some part of macro definition. + // + // This also handles the case where an external span got replaced + // with the call site span by `fix_multispans_in_extern_macros`. + // + // NB: `-Zmacro-backtrace` overrides this, for uniformity, as the + // "in this expansion of" label above is always added in that mode, + // and it needs an "in this macro invocation" label to match that. + let redundant_span = trace.call_site.contains(sp); + + if !redundant_span && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _)) || always_backtrace { new_labels.push(( @@ -371,9 +380,9 @@ pub trait Emitter { }, ), )); - if !always_backtrace { - break; - } + } + if !always_backtrace { + break; } } } @@ -447,7 +456,7 @@ impl Emitter for EmitterWriter { let mut children = diag.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); - self.render_multispans_macro_backtrace_and_fix_extern_macros( + self.fix_multispans_in_extern_macros_and_render_macro_backtrace( &self.sm, &mut primary_span, &mut children, diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr index 896f579765f95..0a7e019e59f33 100644 --- a/src/test/ui/macros/same-sequence-span.stderr +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -33,10 +33,7 @@ error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragmen --> $DIR/same-sequence-span.rs:19:1 | LL | proc_macro_sequence::make_foo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | not allowed after `expr` fragments - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index fe53fb242f49b..496bd86e9882e 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -2,10 +2,7 @@ error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | not found in this scope - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | = note: possible candidate is found in another module, you can import it into scope: FromOutside @@ -14,10 +11,7 @@ error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | not found in this scope - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | = note: possible candidate is found in another module, you can import it into scope: Outer diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr index e7764004e8de7..cf85974316abc 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr @@ -2,10 +2,7 @@ error: unexpected closing delimiter: `)` --> $DIR/invalid-punct-ident-4.rs:6:1 | LL | lexer_failure!(); - | ^^^^^^^^^^^^^^^^^ - | | - | unexpected closing delimiter - | in this macro invocation + | ^^^^^^^^^^^^^^^^^ unexpected closing delimiter error: proc macro panicked --> $DIR/invalid-punct-ident-4.rs:6:1 diff --git a/src/test/ui/proc-macro/lints_in_proc_macros.stderr b/src/test/ui/proc-macro/lints_in_proc_macros.stderr index f28b8c9fb73e9..2d97cd700be9f 100644 --- a/src/test/ui/proc-macro/lints_in_proc_macros.stderr +++ b/src/test/ui/proc-macro/lints_in_proc_macros.stderr @@ -2,10 +2,7 @@ error[E0425]: cannot find value `foobar2` in this scope --> $DIR/lints_in_proc_macros.rs:12:5 | LL | bang_proc_macro2!(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | help: a local variable with a similar name exists: `foobar` - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` error: aborting due to previous error diff --git a/src/test/ui/proc-macro/mixed-site-span.stderr b/src/test/ui/proc-macro/mixed-site-span.stderr index 54d10fe0d9011..b5ca6cb9b29e4 100644 --- a/src/test/ui/proc-macro/mixed-site-span.stderr +++ b/src/test/ui/proc-macro/mixed-site-span.stderr @@ -2,19 +2,13 @@ error[E0426]: use of undeclared label `'label_use` --> $DIR/mixed-site-span.rs:15:9 | LL | proc_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | undeclared label `'label_use` - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use` error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:15:9 | LL | proc_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | not found in this scope - | in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:19:9 diff --git a/src/test/ui/proc-macro/subspan.stderr b/src/test/ui/proc-macro/subspan.stderr index 06715c197bc59..5117dd6d32d49 100644 --- a/src/test/ui/proc-macro/subspan.stderr +++ b/src/test/ui/proc-macro/subspan.stderr @@ -2,7 +2,7 @@ error: found 'hi's --> $DIR/subspan.rs:11:1 | LL | subspan!("hi"); - | ^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:11:11 @@ -14,7 +14,7 @@ error: found 'hi's --> $DIR/subspan.rs:14:1 | LL | subspan!("hihi"); - | ^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:14:11 @@ -26,7 +26,7 @@ error: found 'hi's --> $DIR/subspan.rs:17:1 | LL | subspan!("hihihi"); - | ^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:17:11 @@ -38,7 +38,7 @@ error: found 'hi's --> $DIR/subspan.rs:20:1 | LL | subspan!("why I hide? hi!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:20:17 @@ -50,7 +50,7 @@ error: found 'hi's --> $DIR/subspan.rs:21:1 | LL | subspan!("hey, hi, hidy, hidy, hi hi"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:21:16 @@ -62,7 +62,7 @@ error: found 'hi's --> $DIR/subspan.rs:22:1 | LL | subspan!("this is a hi, and this is another hi"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:22:12 @@ -74,7 +74,7 @@ error: found 'hi's --> $DIR/subspan.rs:23:1 | LL | subspan!("how are you this evening"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:23:24 @@ -86,7 +86,7 @@ error: found 'hi's --> $DIR/subspan.rs:24:1 | LL | subspan!("this is highly eradic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: here --> $DIR/subspan.rs:24:12 diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index fe2583eafe505..f928510454ae3 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | / intrinsic_match! { LL | | "abc" LL | | }; - | | ^ - | | | - | |______expected `&str`, found struct `std::string::String` - | in this macro invocation + | |______^ expected `&str`, found struct `std::string::String` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) From 4c7eb59e8161fd7bd2da89fc8c8d73c32bcd789b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 16 Dec 2019 15:56:47 +0200 Subject: [PATCH 0967/1253] rustc_macros: don't limit the -Zmacro-backtrace suggestion to extern macros. --- src/librustc_errors/emitter.rs | 53 +++++++++----- .../rustdoc-ui/intra-links-warning.stderr | 1 + .../hash-stable-is-unstable.stderr | 1 + .../lint_pass_impl_without_macro.stderr | 1 + src/test/ui/allocator/not-an-allocator.stderr | 4 ++ src/test/ui/allocator/two-allocators.stderr | 2 + .../borrowck-borrowed-uniq-rvalue-2.stderr | 2 +- src/test/ui/borrowck/issue-64453.stderr | 2 +- .../ui/borrowck/move-error-snippets.stderr | 2 + .../ui/codemap_tests/bad-format-args.stderr | 2 +- src/test/ui/codemap_tests/issue-28308.stderr | 2 + .../cfg-attr-syntax-validation.stderr | 2 + ...r-unknown-attribute-macro-expansion.stderr | 2 + .../core-traits-no-impls-length-33.stderr | 1 + .../ui/const-generics/broken-mir-2.stderr | 1 + .../derive-debug-array-wrapper.stderr | 1 + .../const-eval/const_fn_ptr_fail2.stderr | 4 +- .../ui/consts/const-eval/const_panic.stderr | 6 +- .../const-eval/const_panic_libcore.stderr | 6 +- .../const_panic_libcore_main.stderr | 6 +- .../feature-gate-const_panic.stderr | 6 +- .../const-eval/panic-assoc-never-type.stderr | 2 +- .../consts/const-eval/panic-never-type.stderr | 2 +- .../const-external-macro-const-err.stderr | 2 +- .../ui/consts/control-flow/assert.both.stderr | 2 +- .../control-flow/assert.if_match.stderr | 4 +- .../consts/control-flow/assert.panic.stderr | 2 + .../consts/control-flow/assert.stock.stderr | 2 + .../control-flow/issue-50577.if_match.stderr | 2 +- .../control-flow/issue-50577.stock.stderr | 8 +-- .../control-flow/short-circuit.stock.stderr | 4 +- src/test/ui/consts/enum-discr-type-err.stderr | 2 + .../min_const_fn/bad_const_fn_body_ice.stderr | 2 +- .../cross-crate-macro-backtrace/main.stderr | 2 +- .../ui/cross/cross-file-errors/main.stderr | 2 + .../ui/custom_test_frameworks/mismatch.stderr | 1 + .../ui/deprecation/deprecation-lint-2.stderr | 2 +- .../ui/deprecation/deprecation-lint-3.stderr | 2 +- src/test/ui/deref-suggestion.stderr | 4 +- ...ives-span-Clone-enum-struct-variant.stderr | 1 + .../ui/derives/derives-span-Clone-enum.stderr | 1 + .../derives/derives-span-Clone-struct.stderr | 1 + .../derives-span-Clone-tuple-struct.stderr | 1 + ...ives-span-Debug-enum-struct-variant.stderr | 1 + .../ui/derives/derives-span-Debug-enum.stderr | 1 + .../derives/derives-span-Debug-struct.stderr | 1 + .../derives-span-Debug-tuple-struct.stderr | 1 + .../derives-span-Default-struct.stderr | 1 + .../derives-span-Default-tuple-struct.stderr | 1 + ...derives-span-Eq-enum-struct-variant.stderr | 1 + .../ui/derives/derives-span-Eq-enum.stderr | 1 + .../ui/derives/derives-span-Eq-struct.stderr | 1 + .../derives-span-Eq-tuple-struct.stderr | 1 + ...rives-span-Hash-enum-struct-variant.stderr | 2 + .../ui/derives/derives-span-Hash-enum.stderr | 2 + .../derives/derives-span-Hash-struct.stderr | 2 + .../derives-span-Hash-tuple-struct.stderr | 2 + ...erives-span-Ord-enum-struct-variant.stderr | 1 + .../ui/derives/derives-span-Ord-enum.stderr | 1 + .../ui/derives/derives-span-Ord-struct.stderr | 1 + .../derives-span-Ord-tuple-struct.stderr | 1 + ...-span-PartialEq-enum-struct-variant.stderr | 2 + .../derives-span-PartialEq-enum.stderr | 2 + .../derives-span-PartialEq-struct.stderr | 2 + ...derives-span-PartialEq-tuple-struct.stderr | 2 + ...span-PartialOrd-enum-struct-variant.stderr | 5 ++ .../derives-span-PartialOrd-enum.stderr | 5 ++ .../derives-span-PartialOrd-struct.stderr | 5 ++ ...erives-span-PartialOrd-tuple-struct.stderr | 5 ++ ...eriving-no-inner-impl-error-message.stderr | 3 + .../derives/deriving-with-repr-packed.stderr | 4 ++ .../ui/did_you_mean/bad-assoc-expr.stderr | 2 + src/test/ui/did_you_mean/bad-assoc-pat.stderr | 4 ++ src/test/ui/did_you_mean/bad-assoc-ty.stderr | 4 ++ .../did_you_mean/recursion_limit_macro.stderr | 1 + .../dollar-crate-is-keyword-2.stderr | 6 ++ .../dollar-crate-is-keyword.stderr | 8 +++ .../ui/editions/edition-imports-2015.stderr | 2 +- .../ui/editions/edition-imports-2018.stderr | 2 +- .../edition-imports-virtual-2015-gated.stderr | 2 +- ...dition-keywords-2015-2018-expansion.stderr | 2 +- ...dition-keywords-2018-2018-expansion.stderr | 2 +- src/test/ui/error-codes/E0184.stderr | 2 + src/test/ui/error-codes/E0665.stderr | 2 + src/test/ui/exclusive-drop-and-copy.stderr | 4 ++ ...-allow-internal-unsafe-nested-macro.stderr | 1 + ...llow-internal-unstable-nested-macro.stderr | 1 + .../feature-gate-concat_idents2.stderr | 2 + ...pats-inclusive-dotdotdot-bad-syntax.stderr | 2 + ...lf-open-range-pats-inclusive-no-end.stderr | 2 + ...pe.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 1 + .../hr-subtype.bound_a_b_vs_bound_a.stderr | 1 + .../hr-subtype.bound_a_vs_free_x.stderr | 1 + ...-subtype.bound_co_a_b_vs_bound_co_a.stderr | 1 + ...ubtype.bound_co_a_co_b_ret_contra_a.stderr | 1 + ...pe.bound_contra_a_contra_b_ret_co_a.stderr | 1 + ...ubtype.bound_inv_a_b_vs_bound_inv_a.stderr | 1 + ...ubtype.free_inv_x_vs_free_inv_y.nll.stderr | 2 + ...hr-subtype.free_inv_x_vs_free_inv_y.stderr | 2 + .../hr-subtype.free_x_vs_free_y.nll.stderr | 1 + .../hr-subtype.free_x_vs_free_y.stderr | 1 + src/test/ui/hygiene/assoc_item_ctxt.stderr | 4 ++ .../ui/hygiene/duplicate_lifetimes.stderr | 4 ++ .../extern-prelude-from-opaque-fail.stderr | 4 ++ src/test/ui/hygiene/fields-definition.stderr | 2 + src/test/ui/hygiene/fields-move.stderr | 1 + src/test/ui/hygiene/fields.stderr | 8 +++ src/test/ui/hygiene/generate-mod.stderr | 8 +++ src/test/ui/hygiene/globs.stderr | 3 + src/test/ui/hygiene/hygienic-label-1.stderr | 2 + src/test/ui/hygiene/hygienic-label-3.stderr | 2 + .../ui/hygiene/hygienic-labels-in-let.stderr | 32 +++++++++ src/test/ui/hygiene/hygienic-labels.stderr | 32 +++++++++ src/test/ui/hygiene/impl_items.stderr | 2 + src/test/ui/hygiene/intercrate.stderr | 2 +- .../ui/hygiene/no_implicit_prelude.stderr | 5 +- src/test/ui/hygiene/privacy-early.stderr | 1 + src/test/ui/hygiene/trait_items.stderr | 1 + src/test/ui/if/if-let.stderr | 3 + src/test/ui/if/ifmt-bad-arg.stderr | 2 + src/test/ui/if/ifmt-bad-format-args.stderr | 2 + src/test/ui/if/ifmt-unimpl.stderr | 1 + .../extern-prelude-extern-crate-fail.stderr | 2 + ...e-extern-crate-restricted-shadowing.stderr | 3 + src/test/ui/imports/import-crate-var.stderr | 2 +- .../ui/imports/import-prefix-macro-1.stderr | 2 + .../ui/imports/import-prefix-macro-2.stderr | 2 + .../local-modularized-tricky-fail-1.stderr | 4 ++ .../local-modularized-tricky-fail-2.stderr | 3 + .../local-modularized-tricky-fail-3.stderr | 2 + .../ui/imports/shadow_builtin_macros.stderr | 1 + .../in-band-lifetimes/elided-lifetimes.stderr | 4 ++ .../ui/include-macros/mismatched-types.stderr | 2 + .../infinite/infinite-macro-expansion.stderr | 1 + src/test/ui/inline-asm-bad-constraint.stderr | 6 ++ .../internal/internal-unstable-noallow.stderr | 8 +-- src/test/ui/internal/internal-unstable.stderr | 1 + src/test/ui/issues/issue-12997-2.stderr | 2 + src/test/ui/issues/issue-13446.stderr | 2 +- src/test/ui/issues/issue-14091-2.stderr | 1 + src/test/ui/issues/issue-15167.stderr | 8 +++ src/test/ui/issues/issue-16098.stderr | 1 + src/test/ui/issues/issue-16966.stderr | 2 +- src/test/ui/issues/issue-21160.stderr | 2 + src/test/ui/issues/issue-2150.stderr | 1 - src/test/ui/issues/issue-25385.stderr | 2 + src/test/ui/issues/issue-25386.stderr | 4 ++ src/test/ui/issues/issue-25793.stderr | 2 + src/test/ui/issues/issue-26093.stderr | 4 ++ src/test/ui/issues/issue-26094.stderr | 2 + src/test/ui/issues/issue-27340.stderr | 2 + src/test/ui/issues/issue-27592.stderr | 4 ++ src/test/ui/issues/issue-29084.stderr | 2 + src/test/ui/issues/issue-31011.stderr | 2 + src/test/ui/issues/issue-32655.stderr | 2 + src/test/ui/issues/issue-32782.stderr | 1 + src/test/ui/issues/issue-32829.stderr | 2 +- src/test/ui/issues/issue-32950.stderr | 2 + src/test/ui/issues/issue-34229.stderr | 5 ++ src/test/ui/issues/issue-34334.stderr | 2 +- src/test/ui/issues/issue-38821.stderr | 1 + src/test/ui/issues/issue-42954.stderr | 2 + src/test/ui/issues/issue-48364.stderr | 1 + src/test/ui/issues/issue-48728.stderr | 1 + src/test/ui/issues/issue-50480.stderr | 2 + src/test/ui/issues/issue-51848.stderr | 1 + src/test/ui/issues/issue-53251.stderr | 4 ++ src/test/ui/issues/issue-56411.stderr | 2 + src/test/ui/issues/issue-59488.stderr | 6 +- src/test/ui/issues/issue-6596-1.stderr | 2 + src/test/ui/issues/issue-6596-2.stderr | 2 + .../issue-68091-unicode-ident-after-if.stderr | 2 + .../lifetimes/borrowck-let-suggestion.stderr | 2 +- src/test/ui/lint/lint-stability2.stderr | 2 +- src/test/ui/lint/lint-stability3.stderr | 2 +- src/test/ui/lint/lint-unsafe-code.stderr | 2 + .../ui/lint/lints-in-foreign-macros.stderr | 1 + src/test/ui/lint/test-inner-fn.stderr | 3 + .../ui/lint/unreachable_pub-pub_crate.stderr | 1 + src/test/ui/lint/unreachable_pub.stderr | 1 + .../liveness-return-last-stmt-semi.stderr | 2 + src/test/ui/macros/assert.stderr | 2 +- src/test/ui/macros/cfg.stderr | 2 + .../derive-in-eager-expansion-hang.stderr | 1 + src/test/ui/macros/format-parse-errors.stderr | 2 +- src/test/ui/macros/issue-54441.stderr | 2 + .../macro-backtrace-invalid-internals.stderr | 14 ++++ .../ui/macros/macro-backtrace-nested.stderr | 4 ++ .../ui/macros/macro-backtrace-println.stderr | 2 + src/test/ui/macros/macro-context.stderr | 2 + .../macro-lifetime-used-with-labels.stderr | 2 + .../macros/macro-local-data-key-priv.stderr | 2 +- src/test/ui/macros/macro-shadowing.stderr | 2 + .../ui/macros/macros-nonfatal-errors.stderr | 6 ++ .../ui/macros/must-use-in-macro-55516.stderr | 2 +- .../ui/macros/nonterminal-matching.stderr | 2 + .../macros/restricted-shadowing-legacy.stderr | 8 +++ .../macros/restricted-shadowing-modern.stderr | 6 ++ src/test/ui/macros/same-sequence-span.stderr | 2 + .../ui/macros/span-covering-argument-1.stderr | 2 + src/test/ui/macros/trace_faulty_macros.stderr | 3 + .../malformed/malformed-derive-entry.stderr | 4 ++ .../malformed/malformed-interpolated.stderr | 4 ++ .../match/match-arm-resolving-to-never.stderr | 2 - .../method-on-ambiguous-numeric-type.stderr | 2 - .../ui/mismatched_types/issue-26480.stderr | 2 + .../missing/missing-semicolon-warning.stderr | 2 + .../feature-gate-never_type_fallback.stderr | 1 - .../never_type/never-assign-dead-code.stderr | 1 - src/test/ui/on-unimplemented/no-debug.stderr | 4 ++ src/test/ui/out-of-order-shadowing.stderr | 2 +- ...sue-65122-mac-invoc-in-mut-patterns.stderr | 4 ++ src/test/ui/parser/macro/issue-37113.stderr | 2 + src/test/ui/parser/macro/issue-37234.stderr | 2 + .../macro/macro-incomplete-parse.stderr | 2 + .../ui/parser/macro/pub-item-macro.stderr | 2 + .../parser/macro/trait-non-item-macros.stderr | 2 + src/test/ui/parser/mut-patterns.stderr | 2 + src/test/ui/parser/recover-range-pats.stderr | 6 ++ .../rest-pat-semantic-disallowed.stderr | 1 + .../associated-item-privacy-inherent.stderr | 42 +++++++++++ .../associated-item-privacy-trait.stderr | 70 +++++++++++++++++++ ...ssociated-item-privacy-type-binding.stderr | 32 +++++++++ .../ui/privacy/private-inferred-type-3.stderr | 14 ++-- .../ui/privacy/private-inferred-type.stderr | 12 ++++ src/test/ui/proc-macro/derive-bad.stderr | 2 + .../proc-macro/derive-helper-shadowing.stderr | 4 ++ src/test/ui/proc-macro/dollar-crate.stderr | 3 +- .../ui/proc-macro/expand-to-unstable-2.stderr | 1 + .../ui/proc-macro/expand-to-unstable.stderr | 1 + .../proc-macro/gen-macro-rules-hygiene.stderr | 4 ++ src/test/ui/proc-macro/generate-mod.stderr | 4 ++ .../proc-macro/invalid-punct-ident-4.stderr | 2 + src/test/ui/proc-macro/issue-38586.stderr | 2 + src/test/ui/proc-macro/issue-50493.stderr | 4 ++ .../issue-59191-replace-root-with-fn.stderr | 2 + .../ui/proc-macro/lints_in_proc_macros.stderr | 2 + src/test/ui/proc-macro/mixed-site-span.stderr | 5 ++ src/test/ui/proc-macro/multispan.stderr | 7 ++ .../ui/proc-macro/parent-source-spans.stderr | 18 +++++ src/test/ui/proc-macro/subspan.stderr | 8 +++ src/test/ui/proc-macro/three-equals.stderr | 1 + src/test/ui/range/range_traits-1.stderr | 36 ++++++++++ src/test/ui/range/range_traits-2.stderr | 2 + src/test/ui/range/range_traits-3.stderr | 2 + src/test/ui/range/range_traits-6.stderr | 2 + src/test/ui/reachable/expr_again.stderr | 2 +- src/test/ui/reachable/expr_block.stderr | 2 +- src/test/ui/reachable/expr_if.stderr | 2 +- src/test/ui/reachable/expr_loop.stderr | 6 +- src/test/ui/reachable/expr_match.stderr | 4 +- .../regions-var-type-out-of-scope.stderr | 1 - .../termination-trait-test-wrong-type.stderr | 1 + .../dbg-macro-move-semantics.stderr | 2 - .../dbg-macro-requires-debug.stderr | 2 +- .../suggestions-not-always-applicable.stderr | 2 + .../ambiguity-macros-nested.stderr | 1 + .../uniform-paths/ambiguity-macros.stderr | 1 + src/test/ui/span/E0204.stderr | 4 ++ src/test/ui/span/coerce-suggestions.stderr | 2 +- src/test/ui/span/issue-33884.stderr | 2 +- .../ui/span/macro-span-replacement.stderr | 1 + src/test/ui/span/slice-borrow.stderr | 2 +- ...gest-deref-inside-macro-issue-58298.stderr | 2 +- .../dont-suggest-try_into-in-macros.stderr | 2 +- .../mut-borrow-needed-by-trait.stderr | 2 +- src/test/ui/suggestions/path-display.stderr | 1 + .../suggestions/vec-macro-in-pattern.stderr | 2 +- src/test/ui/trace_macros-gate.stderr | 1 + .../ui/try-block/try-block-opt-init.stderr | 2 +- .../ui/tuple/tuple-struct-fields/test2.stderr | 2 + .../ui/tuple/tuple-struct-fields/test3.stderr | 2 + .../ui/type/ascription/issue-47666.stderr | 2 +- .../cannot_infer_local_or_vec.stderr | 2 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- src/test/ui/union/union-derive-clone.stderr | 1 + src/test/ui/union/union-derive-eq.stderr | 1 + src/test/ui/unreachable-code-ret.stderr | 2 +- src/test/ui/unused/unused-macro-rules.stderr | 2 + src/test/ui/while-let.stderr | 3 + 280 files changed, 888 insertions(+), 119 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 4857ff47462c8..f3653da4be666 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -26,6 +26,7 @@ use std::borrow::Cow; use std::cmp::{max, min, Reverse}; use std::io; use std::io::prelude::*; +use std::iter; use std::path::Path; use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream}; use termcolor::{Buffer, Color, WriteColor}; @@ -279,20 +280,41 @@ pub trait Emitter { level: &Level, backtrace: bool, ) { - let mut external_spans_updated = false; + // Check for spans in macros, before `fix_multispans_in_extern_macros` + // has a chance to replace them. + let has_macro_spans = iter::once(&*span) + .chain(children.iter().map(|child| &child.span)) + .flat_map(|span| span.primary_spans()) + .copied() + .flat_map(|sp| { + sp.macro_backtrace().filter_map(|expn_data| { + match expn_data.kind { + ExpnKind::Root => None, + + // Skip past non-macro entries, just in case there + // are some which do actually involve macros. + ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None, + + ExpnKind::Macro(macro_kind, _) => Some(macro_kind), + } + }) + }) + .next(); + if !backtrace { - external_spans_updated = - self.fix_multispans_in_extern_macros(source_map, span, children); + self.fix_multispans_in_extern_macros(source_map, span, children); } self.render_multispans_macro_backtrace(span, children, backtrace); if !backtrace { - if external_spans_updated { + if let Some(macro_kind) = has_macro_spans { let msg = format!( - "this {} originates in a macro outside of the current crate \ + "this {} originates in {} {} \ (in Nightly builds, run with -Z macro-backtrace for more info)", level, + macro_kind.article(), + macro_kind.descr(), ); children.push(SubDiagnostic { @@ -311,9 +333,8 @@ pub trait Emitter { children: &mut Vec, backtrace: bool, ) { - self.render_multispan_macro_backtrace(span, backtrace); - for child in children.iter_mut() { - self.render_multispan_macro_backtrace(&mut child.span, backtrace); + for span in iter::once(span).chain(children.iter_mut().map(|child| &mut child.span)) { + self.render_multispan_macro_backtrace(span, backtrace); } } @@ -386,6 +407,7 @@ pub trait Emitter { } } } + for (label_span, label_text) in new_labels { span.push_span_label(label_span, label_text); } @@ -399,12 +421,10 @@ pub trait Emitter { source_map: &Option>, span: &mut MultiSpan, children: &mut Vec, - ) -> bool { - let mut spans_updated = self.fix_multispan_in_extern_macros(source_map, span); - for child in children.iter_mut() { - spans_updated |= self.fix_multispan_in_extern_macros(source_map, &mut child.span); + ) { + for span in iter::once(span).chain(children.iter_mut().map(|child| &mut child.span)) { + self.fix_multispan_in_extern_macros(source_map, span); } - spans_updated } // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of @@ -414,10 +434,10 @@ pub trait Emitter { &self, source_map: &Option>, span: &mut MultiSpan, - ) -> bool { + ) { let sm = match source_map { Some(ref sm) => sm, - None => return false, + None => return, }; // First, find all the spans in <*macros> and point instead at their use site @@ -438,12 +458,9 @@ pub trait Emitter { .collect(); // After we have them, make sure we replace these 'bad' def sites with their use sites - let spans_updated = !replacements.is_empty(); for (from, to) in replacements { span.replace(from, to); } - - spans_updated } } diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 5f1c9cfbc367a..91b1fff5a3a07 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -175,4 +175,5 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr index e2dc0c3be725f..73b48013de665 100644 --- a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr +++ b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr @@ -42,6 +42,7 @@ LL | #[derive(HashStable)] | = note: for more information, see https://github.com/rust-lang/rust/issues/27812 = help: add `#![feature(rustc_private)]` to the crate attributes to enable + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index 966a747a1c9f4..fe920dba3978e 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -21,6 +21,7 @@ LL | custom_lint_pass_macro!(); | -------------------------- in this macro invocation | = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/allocator/not-an-allocator.stderr b/src/test/ui/allocator/not-an-allocator.stderr index dd2cf36ff1b83..0d52a23c1f398 100644 --- a/src/test/ui/allocator/not-an-allocator.stderr +++ b/src/test/ui/allocator/not-an-allocator.stderr @@ -5,6 +5,7 @@ LL | static A: usize = 0; | ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize` | = note: required by `std::alloc::GlobalAlloc::alloc` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:1 @@ -13,6 +14,7 @@ LL | static A: usize = 0; | ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize` | = note: required by `std::alloc::GlobalAlloc::dealloc` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:1 @@ -21,6 +23,7 @@ LL | static A: usize = 0; | ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize` | = note: required by `std::alloc::GlobalAlloc::realloc` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:1 @@ -29,6 +32,7 @@ LL | static A: usize = 0; | ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize` | = note: required by `std::alloc::GlobalAlloc::alloc_zeroed` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/allocator/two-allocators.stderr b/src/test/ui/allocator/two-allocators.stderr index da636a5a567f3..1b46825c5425c 100644 --- a/src/test/ui/allocator/two-allocators.stderr +++ b/src/test/ui/allocator/two-allocators.stderr @@ -6,6 +6,8 @@ LL | static A: System = System; LL | #[global_allocator] LL | static B: System = System; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr index d0250d862fcc4..bdb073cdcbcc9 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr @@ -9,7 +9,7 @@ LL | x.x[0]; | ------ borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr index 3a7f13f5bba8c..edc496aa2f81b 100644 --- a/src/test/ui/borrowck/issue-64453.stderr +++ b/src/test/ui/borrowck/issue-64453.stderr @@ -6,7 +6,7 @@ LL | static settings_dir: String = format!(""); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/borrowck/move-error-snippets.stderr b/src/test/ui/borrowck/move-error-snippets.stderr index 77463c48591bc..e0acd45957145 100644 --- a/src/test/ui/borrowck/move-error-snippets.stderr +++ b/src/test/ui/borrowck/move-error-snippets.stderr @@ -9,6 +9,8 @@ LL | aaa!(D); ... LL | sss!(); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index 66ff9508db796..96d7b07b0e253 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -4,7 +4,7 @@ error: requires at least a format string argument LL | format!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected token: `,` --> $DIR/bad-format-args.rs:3:16 diff --git a/src/test/ui/codemap_tests/issue-28308.stderr b/src/test/ui/codemap_tests/issue-28308.stderr index d44c157003dfb..f8820b9efedfc 100644 --- a/src/test/ui/codemap_tests/issue-28308.stderr +++ b/src/test/ui/codemap_tests/issue-28308.stderr @@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str` | LL | assert!("foo"); | ^^^^^^^^^^^^^^^ cannot apply unary operator `!` + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index 5bfe9e902dae8..44063dd1d65d7 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -60,6 +60,8 @@ LL | #[cfg(feature = $expr)] ... LL | generate_s10!(concat!("nonexistent")); | -------------------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index ef434ec82610e..330ce2bd2e1b5 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -6,6 +6,8 @@ LL | #[cfg_attr(all(), unknown)] ... LL | foo!(); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr index d885c98dcb287..cba71db86a964 100644 --- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr @@ -6,6 +6,7 @@ LL | println!("{:?}", [0_usize; 33]); | = note: required because of the requirements on the impl of `std::fmt::Debug` for `[usize; 33]` = note: required by `std::fmt::Debug::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: arrays only have std trait implementations for lengths 0..=32 --> $DIR/core-traits-no-impls-length-33.rs:10:16 diff --git a/src/test/ui/const-generics/broken-mir-2.stderr b/src/test/ui/const-generics/broken-mir-2.stderr index b72bc6a46a056..7d95b46790d65 100644 --- a/src/test/ui/const-generics/broken-mir-2.stderr +++ b/src/test/ui/const-generics/broken-mir-2.stderr @@ -15,6 +15,7 @@ LL | struct S([T; N]); = note: required because of the requirements on the impl of `std::fmt::Debug` for `[T; _]` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/const-generics/derive-debug-array-wrapper.stderr b/src/test/ui/const-generics/derive-debug-array-wrapper.stderr index 08a9037a207b3..c4aef4c9d4785 100644 --- a/src/test/ui/const-generics/derive-debug-array-wrapper.stderr +++ b/src/test/ui/const-generics/derive-debug-array-wrapper.stderr @@ -15,6 +15,7 @@ LL | a: [u32; N], = note: required because of the requirements on the impl of `std::fmt::Debug` for `[u32; _]` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[u32; _]` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 15dd84fa7ed3f..4c3ebece0a839 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -12,7 +12,7 @@ LL | assert_eq!(Y, 4); | | | referenced constant has errors | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant expression failed --> $DIR/const_fn_ptr_fail2.rs:22:5 @@ -22,7 +22,7 @@ LL | assert_eq!(Z, 4); | | | referenced constant has errors | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index bbbe70510306e..679d8f280cc60 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -7,7 +7,7 @@ LL | pub const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:4:19 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic.rs:7:19 @@ -17,7 +17,7 @@ LL | pub const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:7:19 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic.rs:10:19 @@ -27,7 +27,7 @@ LL | pub const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:10:19 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic_libcore.stderr b/src/test/ui/consts/const-eval/const_panic_libcore.stderr index cedeabeadeb59..2abf158aade54 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore.stderr @@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore.rs:5:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore.rs:8:15 @@ -17,7 +17,7 @@ LL | const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore.rs:8:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore.rs:11:15 @@ -27,7 +27,7 @@ LL | const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore.rs:11:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr index 3e8bea4d069ba..c5887ff8c5697 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr @@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese"); | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:9:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore_main.rs:12:15 @@ -17,7 +17,7 @@ LL | const Y: () = unreachable!(); | | | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:12:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/const_panic_libcore_main.rs:15:15 @@ -27,7 +27,7 @@ LL | const X: () = unimplemented!(); | | | the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_main.rs:15:15 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr index e3b20e4147ab3..82edcefb86e7f 100644 --- a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr +++ b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr @@ -6,7 +6,7 @@ LL | const Z: () = panic!("cheese"); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/feature-gate-const_panic.rs:9:15 @@ -16,7 +16,7 @@ LL | const X: () = unimplemented!(); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/feature-gate-const_panic.rs:6:15 @@ -26,7 +26,7 @@ LL | const Y: () = unreachable!(); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr index 1cdbe6c887f6d..ea4eba89eb7fc 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![warn(const_err)] | ^^^^^^^^^ - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: erroneous constant used --> $DIR/panic-assoc-never-type.rs:16:13 diff --git a/src/test/ui/consts/const-eval/panic-never-type.stderr b/src/test/ui/consts/const-eval/panic-never-type.stderr index ae142897b3704..28333c511dca4 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-never-type.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![warn(const_err)] | ^^^^^^^^^ - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: erroneous constant used --> $DIR/panic-never-type.rs:12:13 diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr index c3808391c7822..06a630d82d840 100644 --- a/src/test/ui/consts/const-external-macro-const-err.stderr +++ b/src/test/ui/consts/const-external-macro-const-err.stderr @@ -5,7 +5,7 @@ LL | static_assert!(2 + 2 == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/assert.both.stderr b/src/test/ui/consts/control-flow/assert.both.stderr index e0e3df1193f55..7dd60cfb5458f 100644 --- a/src/test/ui/consts/control-flow/assert.both.stderr +++ b/src/test/ui/consts/control-flow/assert.both.stderr @@ -7,7 +7,7 @@ LL | const _: () = assert!(false); | the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:12:15 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/assert.if_match.stderr b/src/test/ui/consts/control-flow/assert.if_match.stderr index 3f4719b681cbd..476cf89edf059 100644 --- a/src/test/ui/consts/control-flow/assert.if_match.stderr +++ b/src/test/ui/consts/control-flow/assert.if_match.stderr @@ -6,7 +6,7 @@ LL | const _: () = assert!(true); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable --> $DIR/assert.rs:12:15 @@ -16,7 +16,7 @@ LL | const _: () = assert!(false); | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/control-flow/assert.panic.stderr b/src/test/ui/consts/control-flow/assert.panic.stderr index 11550bf801ab0..043efa038aaa4 100644 --- a/src/test/ui/consts/control-flow/assert.panic.stderr +++ b/src/test/ui/consts/control-flow/assert.panic.stderr @@ -6,6 +6,7 @@ LL | const _: () = assert!(true); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `if` is not allowed in a `const` --> $DIR/assert.rs:12:15 @@ -15,6 +16,7 @@ LL | const _: () = assert!(false); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/control-flow/assert.stock.stderr b/src/test/ui/consts/control-flow/assert.stock.stderr index 11550bf801ab0..043efa038aaa4 100644 --- a/src/test/ui/consts/control-flow/assert.stock.stderr +++ b/src/test/ui/consts/control-flow/assert.stock.stderr @@ -6,6 +6,7 @@ LL | const _: () = assert!(true); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `if` is not allowed in a `const` --> $DIR/assert.rs:12:15 @@ -15,6 +16,7 @@ LL | const _: () = assert!(false); | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr index 5a7f10e2ee40a..831360d5652e8 100644 --- a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr +++ b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr @@ -9,7 +9,7 @@ LL | Drop = assert_eq!(1, 1) | = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/control-flow/issue-50577.stock.stderr b/src/test/ui/consts/control-flow/issue-50577.stock.stderr index 1eeda43b41c30..523bd23258f1e 100644 --- a/src/test/ui/consts/control-flow/issue-50577.stock.stderr +++ b/src/test/ui/consts/control-flow/issue-50577.stock.stderr @@ -6,7 +6,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `if` is not allowed in a `const` --> $DIR/issue-50577.rs:7:16 @@ -16,7 +16,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `match` is not allowed in a `const` --> $DIR/issue-50577.rs:7:16 @@ -26,7 +26,7 @@ LL | Drop = assert_eq!(1, 1) | = note: for more information, see https://github.com/rust-lang/rust/issues/49146 = help: add `#![feature(const_if_match)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0317]: `if` may be missing an `else` clause --> $DIR/issue-50577.rs:7:16 @@ -39,7 +39,7 @@ LL | Drop = assert_eq!(1, 1) | = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/control-flow/short-circuit.stock.stderr b/src/test/ui/consts/control-flow/short-circuit.stock.stderr index 6fcb7cafff284..f32f248af4557 100644 --- a/src/test/ui/consts/control-flow/short-circuit.stock.stderr +++ b/src/test/ui/consts/control-flow/short-circuit.stock.stderr @@ -7,7 +7,7 @@ LL | const _: bool = true || panic!(); | the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:10:25 | = note: `#[deny(const_err)]` on by default - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error --> $DIR/short-circuit.rs:11:26 @@ -17,7 +17,7 @@ LL | const _: bool = false && panic!(); | | | the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:11:26 | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/enum-discr-type-err.stderr b/src/test/ui/consts/enum-discr-type-err.stderr index 9935f88e5b577..492b79e2e6021 100644 --- a/src/test/ui/consts/enum-discr-type-err.stderr +++ b/src/test/ui/consts/enum-discr-type-err.stderr @@ -10,6 +10,7 @@ LL | | B = T, LL | | } | |_- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit | LL | $( $v = $s::V.try_into().unwrap(), )* @@ -27,6 +28,7 @@ LL | | B = T, LL | | } | |_- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit | LL | $( $v = $s::V.try_into().unwrap(), )* diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index 9786e2e353cca..2c68ddd8c9a4d 100644 --- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -6,7 +6,7 @@ LL | vec![1, 2, 3] | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add `#![feature(const_fn)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr b/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr index 4421ce9c7d331..9f58f16c1a02a 100644 --- a/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr +++ b/src/test/ui/cross/cross-crate-macro-backtrace/main.stderr @@ -4,7 +4,7 @@ error: 1 positional argument in format string, but no arguments were given LL | myprintln!("{}"); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/cross/cross-file-errors/main.stderr b/src/test/ui/cross/cross-file-errors/main.stderr index 7fd91eb1d6637..f9101d8a583d3 100644 --- a/src/test/ui/cross/cross-file-errors/main.stderr +++ b/src/test/ui/cross/cross-file-errors/main.stderr @@ -8,6 +8,8 @@ LL | _ | LL | underscore!(); | -------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/custom_test_frameworks/mismatch.stderr b/src/test/ui/custom_test_frameworks/mismatch.stderr index 9e2688c6393c1..420ddbc3def41 100644 --- a/src/test/ui/custom_test_frameworks/mismatch.stderr +++ b/src/test/ui/custom_test_frameworks/mismatch.stderr @@ -5,6 +5,7 @@ LL | fn wrong_kind(){} | ^^^^^^^^^^^^^^^^^ the trait `example_runner::Testable` is not implemented for `test::TestDescAndFn` | = note: required for the cast to the object type `dyn example_runner::Testable` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr index 1f9c5e3d7690b..65152a2f9ab6d 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.stderr +++ b/src/test/ui/deprecation/deprecation-lint-2.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr index f675b6af958f5..b450f74d7f367 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.stderr +++ b/src/test/ui/deprecation/deprecation-lint-3.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index f4843469ccefc..89fd7aae3bea0 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -42,6 +42,8 @@ LL | ($x:expr) => { &$x } ... LL | foo3(borrow!(0)); | ---------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:36:5 @@ -49,7 +51,7 @@ error[E0308]: mismatched types LL | assert_eq!(3i32, &3i32); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:39:17 diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr index 5ddc5b5708c18..8ef2d3d30238f 100644 --- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error` | = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Clone-enum.stderr b/src/test/ui/derives/derives-span-Clone-enum.stderr index 80ef9238f4775..8c740733e2fa4 100644 --- a/src/test/ui/derives/derives-span-Clone-enum.stderr +++ b/src/test/ui/derives/derives-span-Clone-enum.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::clone::Clone` is not implemented for `Error` | = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Clone-struct.stderr b/src/test/ui/derives/derives-span-Clone-struct.stderr index 17f3925107b8a..75a59fbf035d4 100644 --- a/src/test/ui/derives/derives-span-Clone-struct.stderr +++ b/src/test/ui/derives/derives-span-Clone-struct.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error` | = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr index e98212f361871..1860c5f2ff6ac 100644 --- a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::clone::Clone` is not implemented for `Error` | = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr index 233c4c5498320..ab3c5ef3c1d81 100644 --- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr @@ -8,6 +8,7 @@ LL | x: Error = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Debug-enum.stderr b/src/test/ui/derives/derives-span-Debug-enum.stderr index fbda3980cfc77..e0a76d5251594 100644 --- a/src/test/ui/derives/derives-span-Debug-enum.stderr +++ b/src/test/ui/derives/derives-span-Debug-enum.stderr @@ -8,6 +8,7 @@ LL | Error = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Debug-struct.stderr b/src/test/ui/derives/derives-span-Debug-struct.stderr index b56d223b34bc4..2f5cba09e4c2a 100644 --- a/src/test/ui/derives/derives-span-Debug-struct.stderr +++ b/src/test/ui/derives/derives-span-Debug-struct.stderr @@ -8,6 +8,7 @@ LL | x: Error = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr index 76dd6e31e604c..58ec131d54155 100644 --- a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr @@ -8,6 +8,7 @@ LL | Error = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error` = note: required for the cast to the object type `dyn std::fmt::Debug` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Default-struct.stderr b/src/test/ui/derives/derives-span-Default-struct.stderr index 784be7fede368..b97dda719ab78 100644 --- a/src/test/ui/derives/derives-span-Default-struct.stderr +++ b/src/test/ui/derives/derives-span-Default-struct.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::default::Default` is not implemented for `Error` | = note: required by `std::default::Default::default` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr index a93fa058f8dff..d976891f41fea 100644 --- a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::default::Default` is not implemented for `Error` | = note: required by `std::default::Default::default` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr index bad0ce31f7075..f886c29c4db9a 100644 --- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error` | = note: required by `std::cmp::AssertParamIsEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Eq-enum.stderr b/src/test/ui/derives/derives-span-Eq-enum.stderr index a7cc19d4c0f44..0b5470138a5b3 100644 --- a/src/test/ui/derives/derives-span-Eq-enum.stderr +++ b/src/test/ui/derives/derives-span-Eq-enum.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error` | = note: required by `std::cmp::AssertParamIsEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Eq-struct.stderr b/src/test/ui/derives/derives-span-Eq-struct.stderr index 10631cb12bff3..76904d6723587 100644 --- a/src/test/ui/derives/derives-span-Eq-struct.stderr +++ b/src/test/ui/derives/derives-span-Eq-struct.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error` | = note: required by `std::cmp::AssertParamIsEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr index 117ed62cf7ae0..ff94b989d26d5 100644 --- a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error` | = note: required by `std::cmp::AssertParamIsEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr index 00b033004ec8f..889c725c843e7 100644 --- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr @@ -8,6 +8,8 @@ LL | x: Error | LL | fn hash(&self, state: &mut H); | - required by this bound in `std::hash::Hash::hash` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr index 004cabf207ab9..70b8a85d107f1 100644 --- a/src/test/ui/derives/derives-span-Hash-enum.stderr +++ b/src/test/ui/derives/derives-span-Hash-enum.stderr @@ -8,6 +8,8 @@ LL | Error | LL | fn hash(&self, state: &mut H); | - required by this bound in `std::hash::Hash::hash` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr index 27b8ff3d11469..61897392a726a 100644 --- a/src/test/ui/derives/derives-span-Hash-struct.stderr +++ b/src/test/ui/derives/derives-span-Hash-struct.stderr @@ -8,6 +8,8 @@ LL | x: Error | LL | fn hash(&self, state: &mut H); | - required by this bound in `std::hash::Hash::hash` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr index f1142bc50332a..fb929ad985b5f 100644 --- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr @@ -8,6 +8,8 @@ LL | Error | LL | fn hash(&self, state: &mut H); | - required by this bound in `std::hash::Hash::hash` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr index 1d9d1332b57b8..7e73392fd51d5 100644 --- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Ord-enum.stderr b/src/test/ui/derives/derives-span-Ord-enum.stderr index acc8b0c69483e..68df309e0462f 100644 --- a/src/test/ui/derives/derives-span-Ord-enum.stderr +++ b/src/test/ui/derives/derives-span-Ord-enum.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Ord-struct.stderr b/src/test/ui/derives/derives-span-Ord-struct.stderr index e4dcf29545f12..5e1ed33509406 100644 --- a/src/test/ui/derives/derives-span-Ord-struct.stderr +++ b/src/test/ui/derives/derives-span-Ord-struct.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr index c21dfc26cb0d3..d9692e56431ef 100644 --- a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr index eb4b1c84a601d..c669636c85043 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:13:6 @@ -13,6 +14,7 @@ LL | x: Error | ^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr index b63e374d89bf1..ff98edea4dcff 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-enum.rs:13:6 @@ -13,6 +14,7 @@ LL | Error | ^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr index a147f409639a8..200b8e2d503c8 100644 --- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr @@ -5,6 +5,7 @@ LL | x: Error | ^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-struct.rs:12:5 @@ -13,6 +14,7 @@ LL | x: Error | ^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr index fefbf5f9ec9d1..9e3d1309c2258 100644 --- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr @@ -5,6 +5,7 @@ LL | Error | ^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-tuple-struct.rs:12:5 @@ -13,6 +14,7 @@ LL | Error | ^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr index 80b896f4f043e..6433d1f5e27a5 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr @@ -6,6 +6,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 @@ -15,6 +16,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 @@ -24,6 +26,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 @@ -33,6 +36,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6 @@ -42,6 +46,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr index f12038fb867a7..b1be7dd05f984 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr @@ -6,6 +6,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum.rs:13:6 @@ -15,6 +16,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum.rs:13:6 @@ -24,6 +26,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum.rs:13:6 @@ -33,6 +36,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-enum.rs:13:6 @@ -42,6 +46,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr index dbb014752ec01..064c91fd7ddc3 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr @@ -6,6 +6,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-struct.rs:12:5 @@ -15,6 +16,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-struct.rs:12:5 @@ -24,6 +26,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-struct.rs:12:5 @@ -33,6 +36,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-struct.rs:12:5 @@ -42,6 +46,7 @@ LL | x: Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr index f6f1694bbf01e..5b627022cca46 100644 --- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr @@ -6,6 +6,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 @@ -15,6 +16,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 @@ -24,6 +26,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 @@ -33,6 +36,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Error` with `Error` --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5 @@ -42,6 +46,7 @@ LL | Error | = help: the trait `std::cmp::PartialOrd` is not implemented for `Error` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr index 3b480f00df6ea..d4995c1d50c73 100644 --- a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr +++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr @@ -5,6 +5,7 @@ LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq` --> $DIR/deriving-no-inner-impl-error-message.rs:5:5 @@ -13,6 +14,7 @@ LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NoCloneOrEq: std::clone::Clone` is not satisfied --> $DIR/deriving-no-inner-impl-error-message.rs:10:5 @@ -21,6 +23,7 @@ LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NoCloneOrEq` | = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 8ab2e4cba7493..d739257c8de63 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -11,6 +11,7 @@ LL | #![deny(safe_packed_borrows)] | ^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) --> $DIR/deriving-with-repr-packed.rs:8:23 @@ -20,6 +21,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:16:10 @@ -29,6 +31,7 @@ LL | #[derive(PartialEq, Eq)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:25:10 @@ -38,6 +41,7 @@ LL | #[derive(PartialEq)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/did_you_mean/bad-assoc-expr.stderr b/src/test/ui/did_you_mean/bad-assoc-expr.stderr index 2024564b911f6..fe3fb43730a8c 100644 --- a/src/test/ui/did_you_mean/bad-assoc-expr.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-expr.stderr @@ -54,6 +54,8 @@ LL | ($ty: ty) => ($ty::clone(&0)) ... LL | expr!(u8); | ---------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 9 previous errors diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.stderr b/src/test/ui/did_you_mean/bad-assoc-pat.stderr index 3f1946b94f64b..924a5d756436d 100644 --- a/src/test/ui/did_you_mean/bad-assoc-pat.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-pat.stderr @@ -36,6 +36,8 @@ LL | ($ty: ty) => ($ty::AssocItem) ... LL | pat!(u8) => {} | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope --> $DIR/bad-assoc-pat.rs:3:15 @@ -69,6 +71,8 @@ LL | ($ty: ty) => ($ty::AssocItem) ... LL | pat!(u8) => {} | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope --> $DIR/bad-assoc-pat.rs:32:16 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 7d3c99bda6b6a..64e49934d8762 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -54,6 +54,8 @@ LL | ($ty: ty) => ($ty::AssocTy); ... LL | type J = ty!(u8); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 @@ -111,6 +113,8 @@ LL | ($ty: ty) => ($ty::AssocTy); ... LL | type J = ty!(u8); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:44:10 diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index 18d321c24d80c..4935c698f2056 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -8,6 +8,7 @@ LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); | -------------------------------------------------- in this macro invocation | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit_macro`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr b/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr index 55261a5e6aead..2aad57dee7daa 100644 --- a/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr +++ b/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr @@ -6,6 +6,8 @@ LL | use a::$crate::b; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `a::$crate` --> $DIR/dollar-crate-is-keyword-2.rs:5:13 @@ -15,6 +17,8 @@ LL | use a::$crate; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: `$crate` in paths can only be used in start position --> $DIR/dollar-crate-is-keyword-2.rs:7:21 @@ -24,6 +28,8 @@ LL | type A = a::$crate; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/dollar-crate/dollar-crate-is-keyword.stderr b/src/test/ui/dollar-crate/dollar-crate-is-keyword.stderr index f5a5f13f9121e..d424bd2f2858c 100644 --- a/src/test/ui/dollar-crate/dollar-crate-is-keyword.stderr +++ b/src/test/ui/dollar-crate/dollar-crate-is-keyword.stderr @@ -6,6 +6,8 @@ LL | struct $crate {} ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected identifier, found reserved identifier `$crate` --> $DIR/dollar-crate-is-keyword.rs:10:23 @@ -15,6 +17,8 @@ LL | use $crate as $crate; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `$crate` may not be imported --> $DIR/dollar-crate-is-keyword.rs:9:9 @@ -24,6 +28,8 @@ LL | use $crate; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `$crate` may not be imported --> $DIR/dollar-crate-is-keyword.rs:10:9 @@ -33,6 +39,8 @@ LL | use $crate as $crate; ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/editions/edition-imports-2015.stderr b/src/test/ui/editions/edition-imports-2015.stderr index 4b7be3cf98dfe..ec8b88ecba22b 100644 --- a/src/test/ui/editions/edition-imports-2015.stderr +++ b/src/test/ui/editions/edition-imports-2015.stderr @@ -4,7 +4,7 @@ error: cannot glob-import all possible crates LL | gen_glob!(); | ^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-imports-2018.stderr b/src/test/ui/editions/edition-imports-2018.stderr index d83934ccc239e..087d2e339548c 100644 --- a/src/test/ui/editions/edition-imports-2018.stderr +++ b/src/test/ui/editions/edition-imports-2018.stderr @@ -4,7 +4,7 @@ error: cannot glob-import all possible crates LL | gen_glob!(); | ^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr index 43a4c8a361fd9..56cbd882cca60 100644 --- a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr +++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr @@ -4,7 +4,7 @@ error[E0432]: unresolved import `E` LL | gen_gated!(); | ^^^^^^^^^^^^^ could not find `E` in `{{root}}` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr index f4b41d3accc51..f44f81fce7134 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr @@ -4,7 +4,7 @@ error: expected identifier, found keyword `async` LL | produces_async! {} | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | LL | () => (pub fn r#async () { }) diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr index d747b8232ebc3..a8fc58fc0cb8d 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr @@ -4,7 +4,7 @@ error: expected identifier, found keyword `async` LL | produces_async! {} | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | LL | () => (pub fn r#async () { }) diff --git a/src/test/ui/error-codes/E0184.stderr b/src/test/ui/error-codes/E0184.stderr index b4128b9560664..591ea29ff8c52 100644 --- a/src/test/ui/error-codes/E0184.stderr +++ b/src/test/ui/error-codes/E0184.stderr @@ -3,6 +3,8 @@ error[E0184]: the trait `Copy` may not be implemented for this type; the type ha | LL | #[derive(Copy)] | ^^^^ Copy not allowed on types with destructors + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0665.stderr b/src/test/ui/error-codes/E0665.stderr index 2c2b498e39a43..3cb69492eb76d 100644 --- a/src/test/ui/error-codes/E0665.stderr +++ b/src/test/ui/error-codes/E0665.stderr @@ -3,6 +3,8 @@ error[E0665]: `Default` cannot be derived for enums, only structs | LL | #[derive(Default)] | ^^^^^^^ + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/exclusive-drop-and-copy.stderr b/src/test/ui/exclusive-drop-and-copy.stderr index 9983aac4f9c06..f1e725ec34206 100644 --- a/src/test/ui/exclusive-drop-and-copy.stderr +++ b/src/test/ui/exclusive-drop-and-copy.stderr @@ -3,12 +3,16 @@ error[E0184]: the trait `Copy` may not be implemented for this type; the type ha | LL | #[derive(Copy, Clone)] | ^^^^ Copy not allowed on types with destructors + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor --> $DIR/exclusive-drop-and-copy.rs:10:10 | LL | #[derive(Copy, Clone)] | ^^^^ Copy not allowed on types with destructors + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr index 72f5642e72a2d..89c99b89ca804 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr @@ -8,6 +8,7 @@ LL | bar!(); | ------- in this macro invocation | = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr index 7100594336272..935b95668e82b 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr @@ -8,6 +8,7 @@ LL | bar!(); | ------- in this macro invocation | = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr index 14519622c05ad..1c319c6dad4c0 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -12,6 +12,8 @@ error[E0425]: cannot find value `ab` in this scope | LL | concat_idents!(a, b); | ^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr index ba2e7ea8b5354..3a9c918cd3720 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr @@ -30,6 +30,8 @@ LL | let ...$e; ... LL | mac!(0); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr index 2bdb8ea57668a..871c9b57e5444 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr @@ -40,6 +40,7 @@ LL | mac!(0); | -------- in this macro invocation | = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0586]: inclusive range with no end --> $DIR/half-open-range-pats-inclusive-no-end.rs:21:19 @@ -51,6 +52,7 @@ LL | mac!(0); | -------- in this macro invocation | = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr index c8521a54e6c75..b91798fa12379 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(&'a u32, &'a u3 | = note: expected enum `std::option::Option fn(&'a u32, &'b u32) -> &'a u32>` found enum `std::option::Option fn(&'a u32, &'a u32) -> &'a u32>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr index 3ad802c5450b3..45f53d4fe99db 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(&'a u32, &'a u32)) } | = note: expected enum `std::option::Option fn(&'a u32, &'b u32)>` found enum `std::option::Option fn(&'a u32, &'a u32)>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr index 3d09633367cda..c3e4f6d2ed0c1 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -10,6 +10,7 @@ LL | | fn(&'x u32)) } | = note: expected enum `std::option::Option fn(&'a u32)>` found enum `std::option::Option` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr index 8b623a4c0bea9..4d7b86027f564 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(Co<'a>, Co<'a>)) } | = note: expected enum `std::option::Option fn(Co<'a>, Co<'b>)>` found enum `std::option::Option fn(Co<'a>, Co<'a>)>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr index f12bff696913e..7f0a4197dd7fe 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(Co<'a>, Co<'a>) -> | = note: expected enum `std::option::Option fn(Co<'a>, Co<'b>) -> Contra<'a>>` found enum `std::option::Option fn(Co<'a>, Co<'a>) -> Contra<'a>>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr index 37ba44cf2e9ba..c12e543a44e79 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(Contra<'a>, Con | = note: expected enum `std::option::Option fn(Contra<'a>, Contra<'b>) -> Co<'a>>` found enum `std::option::Option fn(Contra<'a>, Contra<'a>) -> Co<'a>>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr index a00bbea6d1818..460356856bd56 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -10,6 +10,7 @@ LL | | for<'a> fn(Inv<'a>, Inv<'a>)) | = note: expected enum `std::option::Option fn(Inv<'a>, Inv<'b>)>` found enum `std::option::Option fn(Inv<'a>, Inv<'a>)>` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr index 9b0c987c0545d..6b5e7a5a6345a 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr @@ -13,6 +13,7 @@ LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation | = help: consider adding the following bound: `'x: 'y` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: lifetime may not live long enough --> $DIR/hr-subtype.rs:39:13 @@ -29,6 +30,7 @@ LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation | = help: consider adding the following bound: `'x: 'y` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr index 561f35191767e..fc3643306e628 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr @@ -28,6 +28,7 @@ LL | fn subtype<'x,'y:'x,'z:'y>() { LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 @@ -59,6 +60,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() { LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr index 48558fad0051e..7c0770924daaa 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr @@ -13,6 +13,7 @@ LL | | fn(&'y u32)) } | |__________________________________________- in this macro invocation | = help: consider adding the following bound: `'x: 'y` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr index 082627050b357..0dde27788f629 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr @@ -28,6 +28,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() { LL | / check! { free_x_vs_free_y: (fn(&'x u32), LL | | fn(&'y u32)) } | |__________________________________________- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/assoc_item_ctxt.stderr b/src/test/ui/hygiene/assoc_item_ctxt.stderr index 0d1c73eef0e23..dec1bd62ca936 100644 --- a/src/test/ui/hygiene/assoc_item_ctxt.stderr +++ b/src/test/ui/hygiene/assoc_item_ctxt.stderr @@ -6,6 +6,8 @@ LL | fn method() {} ... LL | mac_trait_impl!(); | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0046]: not all trait items implemented, missing: `method` --> $DIR/assoc_item_ctxt.rs:34:9 @@ -18,6 +20,8 @@ LL | impl Tr for u8 { ... LL | mac_trait_impl!(); | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/hygiene/duplicate_lifetimes.stderr b/src/test/ui/hygiene/duplicate_lifetimes.stderr index 7aaea6ff24e39..04f5bed5e05ea 100644 --- a/src/test/ui/hygiene/duplicate_lifetimes.stderr +++ b/src/test/ui/hygiene/duplicate_lifetimes.stderr @@ -9,6 +9,8 @@ LL | m!('a); | | | | | previous declaration here | in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0263]: lifetime name `'a` declared twice in the same scope --> $DIR/duplicate_lifetimes.rs:13:14 @@ -21,6 +23,8 @@ LL | n!('a); | | | | | previous declaration here | in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr index 65133eb1e1873..b9e05c84a8aea 100644 --- a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr +++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -15,6 +15,8 @@ LL | use my_core; ... LL | a!(); | ----- in this macro invocation + | + = 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 or module `my_core` --> $DIR/extern-prelude-from-opaque-fail.rs:11:18 @@ -24,6 +26,8 @@ LL | fn f() { my_core::mem::drop(0); } ... LL | a!(); | ----- in this macro invocation + | + = 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 or module `my_core` --> $DIR/extern-prelude-from-opaque-fail.rs:24:14 diff --git a/src/test/ui/hygiene/fields-definition.stderr b/src/test/ui/hygiene/fields-definition.stderr index a30650d88e28d..8070ffdfdeb89 100644 --- a/src/test/ui/hygiene/fields-definition.stderr +++ b/src/test/ui/hygiene/fields-definition.stderr @@ -8,6 +8,8 @@ LL | $a: u8, ... LL | legacy!(a); | ----------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/fields-move.stderr b/src/test/ui/hygiene/fields-move.stderr index 562f60e31b5d2..5ce786dce837c 100644 --- a/src/test/ui/hygiene/fields-move.stderr +++ b/src/test/ui/hygiene/fields-move.stderr @@ -10,6 +10,7 @@ LL | assert_two_copies(copy_legacy!(foo), foo.x); | ----------------- in this macro invocation | = note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0382]: use of moved value: `foo.x` --> $DIR/fields-move.rs:28:42 diff --git a/src/test/ui/hygiene/fields.stderr b/src/test/ui/hygiene/fields.stderr index 20ea4e91067be..89deef492020d 100644 --- a/src/test/ui/hygiene/fields.stderr +++ b/src/test/ui/hygiene/fields.stderr @@ -6,6 +6,8 @@ LL | let s = S { x: 0 }; ... LL | let s = foo::m!(S, x); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `foo::S` is private --> $DIR/fields.rs:16:17 @@ -15,6 +17,8 @@ LL | let _ = s.x; ... LL | let s = foo::m!(S, x); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `foo::T` is private --> $DIR/fields.rs:18:17 @@ -24,6 +28,8 @@ LL | let t = T(0); ... LL | let s = foo::m!(S, x); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `foo::T` is private --> $DIR/fields.rs:19:17 @@ -33,6 +39,8 @@ LL | let _ = t.0; ... LL | let s = foo::m!(S, x); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/hygiene/generate-mod.stderr b/src/test/ui/hygiene/generate-mod.stderr index 5e2c56d4bf4d4..073e1527b2e11 100644 --- a/src/test/ui/hygiene/generate-mod.stderr +++ b/src/test/ui/hygiene/generate-mod.stderr @@ -18,6 +18,8 @@ LL | type A = FromOutside; ... LL | genmod_transparent!(); | ---------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:20:22 @@ -27,6 +29,8 @@ LL | type Inner = Outer; ... LL | genmod_transparent!(); | ---------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:28:18 @@ -36,6 +40,8 @@ LL | type A = FromOutside; ... LL | genmod_legacy!(); | ----------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:29:22 @@ -45,6 +51,8 @@ LL | type Inner = Outer; ... LL | genmod_legacy!(); | ----------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr index f9fbf295aecc9..153ad8cbecfcd 100644 --- a/src/test/ui/hygiene/globs.stderr +++ b/src/test/ui/hygiene/globs.stderr @@ -22,6 +22,7 @@ LL | | f(); LL | | } | |_____- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: possible candidates are found in other modules, you can import them into scope | LL | use bar::g; @@ -42,6 +43,7 @@ LL | n!(f); | = note: possible candidate is found in another module, you can import it into scope: foo::f + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:65:17 @@ -54,6 +56,7 @@ LL | f | = note: possible candidate is found in another module, you can import it into scope: foo::f + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/hygiene/hygienic-label-1.stderr b/src/test/ui/hygiene/hygienic-label-1.stderr index d61c0687c1665..60df494e131c6 100644 --- a/src/test/ui/hygiene/hygienic-label-1.stderr +++ b/src/test/ui/hygiene/hygienic-label-1.stderr @@ -6,6 +6,8 @@ LL | () => { break 'x; } ... LL | 'x: loop { foo!() } | ------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/hygienic-label-3.stderr b/src/test/ui/hygiene/hygienic-label-3.stderr index 0c4173a61aac4..dbec71fcaa402 100644 --- a/src/test/ui/hygiene/hygienic-label-3.stderr +++ b/src/test/ui/hygiene/hygienic-label-3.stderr @@ -6,6 +6,8 @@ LL | () => { break 'x; } ... LL | foo!() | ------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr index 4acb34f2dcebe..7c82a08753aa2 100644 --- a/src/test/ui/hygiene/hygienic-labels-in-let.stderr +++ b/src/test/ui/hygiene/hygienic-labels-in-let.stderr @@ -9,6 +9,8 @@ LL | 'x: loop { LL | // this 'x should refer to the outer loop, lexically LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:64:9 @@ -39,6 +41,8 @@ LL | 'x: loop { ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:16:9 @@ -51,6 +55,8 @@ LL | 'x: loop { $e } ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:16:9 @@ -63,6 +69,8 @@ LL | 'x: for _ in 0..1 { ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:76:9 @@ -111,6 +119,8 @@ LL | 'x: loop { ... LL | while_true!(break 'x); | ---------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:27:9 @@ -123,6 +133,8 @@ LL | 'x: while 1 + 1 == 2 { $e } ... LL | while_true!(break 'x); | ---------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:27:9 @@ -135,6 +147,8 @@ LL | 'x: for _ in 0..1 { ... LL | while_true!(break 'x); | ---------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:27:9 @@ -147,6 +161,8 @@ LL | 'x: while 1 + 1 == 2 { $e } ... LL | while_true!(break 'x); | ---------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:27:9 @@ -159,6 +175,8 @@ LL | 'x: for _ in 0..1 { ... LL | while_true!(break 'x); | ---------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:90:9 @@ -225,6 +243,8 @@ LL | 'x: loop { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -237,6 +257,8 @@ LL | 'x: for _ in 0..1 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -249,6 +271,8 @@ LL | 'x: for _ in 0..1 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -261,6 +285,8 @@ LL | 'x: for _ in 0..1 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -273,6 +299,8 @@ LL | 'x: for _ in 0..1 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -285,6 +313,8 @@ LL | 'x: for _ in 0..1 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:39:9 @@ -297,4 +327,6 @@ LL | 'x: for _ in 0..1 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr index 0833825940a85..960da15ef3c97 100644 --- a/src/test/ui/hygiene/hygienic-labels.stderr +++ b/src/test/ui/hygiene/hygienic-labels.stderr @@ -9,6 +9,8 @@ LL | 'x: for _ in 0..1 { LL | // this 'x should refer to the outer loop, lexically LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:54:5 @@ -39,6 +41,8 @@ LL | 'x: for _ in 0..1 { ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:13:9 @@ -51,6 +55,8 @@ LL | 'x: loop { $e } ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:13:9 @@ -63,6 +69,8 @@ LL | 'x: loop { ... LL | loop_x!(break 'x); | ------------------ in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:63:5 @@ -111,6 +119,8 @@ LL | 'x: for _ in 0..1 { ... LL | while_x!(break 'x); | ------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:38:9 @@ -123,6 +133,8 @@ LL | 'x: while 1 + 1 == 2 { $e } ... LL | while_x!(break 'x); | ------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:38:9 @@ -135,6 +147,8 @@ LL | 'x: loop { ... LL | while_x!(break 'x); | ------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:38:9 @@ -147,6 +161,8 @@ LL | 'x: while 1 + 1 == 2 { $e } ... LL | while_x!(break 'x); | ------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:38:9 @@ -159,6 +175,8 @@ LL | 'x: while 1 + 1 == 2 { ... LL | while_x!(break 'x); | ------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:73:5 @@ -225,6 +243,8 @@ LL | 'x: for _ in 0..1 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -237,6 +257,8 @@ LL | 'x: for _ in 0..1 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -249,6 +271,8 @@ LL | 'x: loop { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -261,6 +285,8 @@ LL | 'x: for _ in 0..1 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -273,6 +299,8 @@ LL | 'x: while 1 + 1 == 2 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -285,6 +313,8 @@ LL | 'x: while 1 + 1 == 2 { $e } ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels.rs:24:9 @@ -297,4 +327,6 @@ LL | 'x: for _ in 0..1 { ... LL | run_once!(continue 'x); | ----------------------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/hygiene/impl_items.stderr b/src/test/ui/hygiene/impl_items.stderr index 418c2c73ba157..85ee9f4cbf3e6 100644 --- a/src/test/ui/hygiene/impl_items.stderr +++ b/src/test/ui/hygiene/impl_items.stderr @@ -6,6 +6,8 @@ LL | let _: () = S.f(); ... LL | foo::m!(); | ---------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/intercrate.stderr b/src/test/ui/hygiene/intercrate.stderr index 75347d6e8c950..3912ca337fbec 100644 --- a/src/test/ui/hygiene/intercrate.stderr +++ b/src/test/ui/hygiene/intercrate.stderr @@ -4,7 +4,7 @@ error: type `fn() -> u32 {intercrate::foo::bar::f}` is private LL | assert_eq!(intercrate::foo::m!(), 1); | ^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 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 a466471d5e4ec..986671c7810e7 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -4,7 +4,7 @@ error: cannot find macro `panic` in this scope LL | assert_eq!(0, 0); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = 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 or module `Vec` --> $DIR/no_implicit_prelude.rs:11:9 @@ -14,6 +14,8 @@ LL | fn f() { ::bar::m!(); } ... LL | Vec::new(); | ^^^ use of undeclared type or module `Vec` + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no method named `clone` found for unit type `()` in the current scope --> $DIR/no_implicit_prelude.rs:12:12 @@ -27,6 +29,7 @@ LL | ().clone() = help: items from traits can only be used if the trait is in scope = note: the following trait is implemented but not in scope; perhaps add a `use` for it: `use std::clone::Clone;` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/hygiene/privacy-early.stderr b/src/test/ui/hygiene/privacy-early.stderr index 60e50e05fc30e..afc94bf79f682 100644 --- a/src/test/ui/hygiene/privacy-early.stderr +++ b/src/test/ui/hygiene/privacy-early.stderr @@ -15,6 +15,7 @@ LL | use f as g; ... LL | foo::m!(); | ---------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/hygiene/trait_items.stderr b/src/test/ui/hygiene/trait_items.stderr index 8e3609292a7f9..d24336883e963 100644 --- a/src/test/ui/hygiene/trait_items.stderr +++ b/src/test/ui/hygiene/trait_items.stderr @@ -10,6 +10,7 @@ LL | pub macro m() { ().f() } = help: items from traits can only be used if the trait is in scope = note: the following trait is implemented but not in scope; perhaps add a `use` for it: `use foo::T;` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/if/if-let.stderr b/src/test/ui/if/if-let.stderr index 570a64e999cd0..ad4aefb6e58a7 100644 --- a/src/test/ui/if/if-let.stderr +++ b/src/test/ui/if/if-let.stderr @@ -10,6 +10,7 @@ LL | | }); | |_______- in this macro invocation | = note: `#[warn(irrefutable_let_patterns)]` on by default + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable if-let pattern --> $DIR/if-let.rs:6:13 @@ -21,6 +22,8 @@ LL | / bar!(a, 1, { LL | | println!("irrefutable pattern"); LL | | }); | |_______- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable if-let pattern --> $DIR/if-let.rs:26:5 diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr index c024094dd5610..3e5f5a6374216 100644 --- a/src/test/ui/if/ifmt-bad-arg.stderr +++ b/src/test/ui/if/ifmt-bad-arg.stderr @@ -300,6 +300,7 @@ LL | println!("{} {:.*} {}", 1, 3.2, 4); | = note: expected reference `&usize` found reference `&{float}` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:81:35 @@ -309,6 +310,7 @@ LL | println!("{} {:07$.*} {}", 1, 3.2, 4); | = note: expected reference `&usize` found reference `&{float}` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 36 previous errors diff --git a/src/test/ui/if/ifmt-bad-format-args.stderr b/src/test/ui/if/ifmt-bad-format-args.stderr index 23252b6b5f4fc..8bb0d40629f0a 100644 --- a/src/test/ui/if/ifmt-bad-format-args.stderr +++ b/src/test/ui/if/ifmt-bad-format-args.stderr @@ -3,6 +3,8 @@ error: requires at least a format string argument | LL | format_args!(); | ^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: format argument must be a string literal --> $DIR/ifmt-bad-format-args.rs:3:18 diff --git a/src/test/ui/if/ifmt-unimpl.stderr b/src/test/ui/if/ifmt-unimpl.stderr index 7a7e4b34d2595..a142896ada557 100644 --- a/src/test/ui/if/ifmt-unimpl.stderr +++ b/src/test/ui/if/ifmt-unimpl.stderr @@ -6,6 +6,7 @@ LL | format!("{:X}", "3"); | = note: required because of the requirements on the impl of `std::fmt::UpperHex` for `&str` = note: required by `std::fmt::UpperHex::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr index e067432b39237..f7544306d3434 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr @@ -6,6 +6,8 @@ LL | extern crate std as non_existent; ... LL | define_std_as_non_existent!(); | ------------------------------ in this macro invocation + | + = 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 or module `two_macros` --> $DIR/extern-prelude-extern-crate-fail.rs:10:9 diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 245013a4ea43e..e344d0591473d 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr @@ -6,6 +6,8 @@ LL | extern crate std as core; ... LL | define_other_core!(); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:17:9 @@ -26,6 +28,7 @@ note: `Vec` could also refer to the struct defined here | LL | pub use crate::vec::Vec; | ^^^^^^^^^^^^^^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/imports/import-crate-var.stderr b/src/test/ui/imports/import-crate-var.stderr index 11eca073f9558..6bc2d15b2ff1b 100644 --- a/src/test/ui/imports/import-crate-var.stderr +++ b/src/test/ui/imports/import-crate-var.stderr @@ -4,7 +4,7 @@ error: `$crate` may not be imported LL | m!(); | ^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/imports/import-prefix-macro-1.stderr b/src/test/ui/imports/import-prefix-macro-1.stderr index 6c12a366b7152..2ecc519e718f6 100644 --- a/src/test/ui/imports/import-prefix-macro-1.stderr +++ b/src/test/ui/imports/import-prefix-macro-1.stderr @@ -6,6 +6,8 @@ LL | ($p: path) => (use $p {S, Z}); ... LL | import! { a::b::c } | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/imports/import-prefix-macro-2.stderr b/src/test/ui/imports/import-prefix-macro-2.stderr index 8428dce2728af..80317a34944c6 100644 --- a/src/test/ui/imports/import-prefix-macro-2.stderr +++ b/src/test/ui/imports/import-prefix-macro-2.stderr @@ -6,6 +6,8 @@ LL | ($p: path) => (use ::$p {S, Z}); ... LL | import! { a::b::c } | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index c9498fed6a58e..ea720c8b8730d 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -20,6 +20,7 @@ note: `exported` could also refer to the macro imported here LL | use inner1::*; | ^^^^^^^^^ = help: consider adding an explicit import of `exported` to disambiguate + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `exported` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:28:1 @@ -43,6 +44,7 @@ note: `exported` could also refer to the macro imported here LL | use inner1::*; | ^^^^^^^^^ = help: consider adding an explicit import of `exported` to disambiguate + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:36:5 @@ -62,6 +64,7 @@ LL | | } LL | define_panic!(); | ---------------- in this macro invocation = help: use `crate::panic` to refer to this macro unambiguously + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:47:1 @@ -81,6 +84,7 @@ LL | | } LL | define_include!(); | ------------------ in this macro invocation = help: use `crate::include` to refer to this macro unambiguously + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr index 92a836cadfa7b..07b7ff942a658 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr @@ -9,6 +9,7 @@ LL | () => ( struct Б; ) | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: non-ascii idents are not fully supported --> $DIR/local-modularized-tricky-fail-2.rs:36:24 @@ -21,6 +22,7 @@ LL | () => ( struct Г; ) | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: non-ascii idents are not fully supported --> $DIR/local-modularized-tricky-fail-2.rs:46:24 @@ -33,6 +35,7 @@ LL | () => ( struct Д; ) | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/imports/local-modularized-tricky-fail-3.stderr b/src/test/ui/imports/local-modularized-tricky-fail-3.stderr index 5272d2a319faa..4494a88a5cf95 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-3.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-3.stderr @@ -17,6 +17,7 @@ LL | | } ... LL | define_exported!(); | ------------------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths --> $DIR/local-modularized-tricky-fail-3.rs:19:5 @@ -36,6 +37,7 @@ LL | | } ... LL | define_exported!(); | ------------------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 2f2ab20cdf077..413ead8c25edc 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -28,6 +28,7 @@ LL | macro_rules! panic { () => {} } LL | } } LL | m!(); | ----- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `n` is ambiguous (glob import vs any other name from outer scope during import/macro resolution) --> $DIR/shadow_builtin_macros.rs:49:5 diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr b/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr index 1184f51680a0e..6eddd9c411bc5 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.stderr @@ -36,6 +36,8 @@ LL | fn $fn_name(gift: &str) -> $type_name { ... LL | autowrapper!(Autowrapped, autowrap_gift, 'a); | --------------------------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hidden lifetime parameters in types are deprecated --> $DIR/elided-lifetimes.rs:78:18 @@ -51,6 +53,8 @@ LL | Ref<($($types),*)> ... LL | let yellow: anytuple_ref_ty!(bool, &str) = laughter.borrow(); | ---------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 7 previous errors diff --git a/src/test/ui/include-macros/mismatched-types.stderr b/src/test/ui/include-macros/mismatched-types.stderr index efe1f58a6f43d..d035df8e5d83a 100644 --- a/src/test/ui/include-macros/mismatched-types.stderr +++ b/src/test/ui/include-macros/mismatched-types.stderr @@ -8,6 +8,7 @@ LL | let b: &[u8] = include_str!("file.txt"); | = note: expected reference `&[u8]` found reference `&'static str` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/mismatched-types.rs:3:19 @@ -19,6 +20,7 @@ LL | let s: &str = include_bytes!("file.txt"); | = note: expected reference `&str` found reference `&'static [u8; 0]` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/infinite/infinite-macro-expansion.stderr b/src/test/ui/infinite/infinite-macro-expansion.stderr index ff67eea568866..c9254915d030d 100644 --- a/src/test/ui/infinite/infinite-macro-expansion.stderr +++ b/src/test/ui/infinite/infinite-macro-expansion.stderr @@ -8,6 +8,7 @@ LL | recursive!() | ------------ in this macro invocation | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`infinite_macro_expansion`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/inline-asm-bad-constraint.stderr b/src/test/ui/inline-asm-bad-constraint.stderr index f38bfb2af1d91..2647e337b9d53 100644 --- a/src/test/ui/inline-asm-bad-constraint.stderr +++ b/src/test/ui/inline-asm-bad-constraint.stderr @@ -3,18 +3,24 @@ error[E0668]: malformed inline assembly | LL | asm!("" :"={rax"(rax)) | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0668]: malformed inline assembly --> $DIR/inline-asm-bad-constraint.rs:30:9 | LL | asm!("callq $0" : : "0"(foo)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0668]: malformed inline assembly --> $DIR/inline-asm-bad-constraint.rs:37:9 | LL | asm!("addb $1, $0" : "={rax}"((0i32, rax))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/internal/internal-unstable-noallow.stderr b/src/test/ui/internal/internal-unstable-noallow.stderr index 873d8f898811f..ede8e5437ffbc 100644 --- a/src/test/ui/internal/internal-unstable-noallow.stderr +++ b/src/test/ui/internal/internal-unstable-noallow.stderr @@ -5,7 +5,7 @@ LL | call_unstable_noallow!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(function)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct_field' --> $DIR/internal-unstable-noallow.rs:18:5 @@ -14,7 +14,7 @@ LL | construct_unstable_noallow!(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(struct_field)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'method' --> $DIR/internal-unstable-noallow.rs:20:35 @@ -23,7 +23,7 @@ LL | |x: internal_unstable::Foo| { call_method_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(method)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct2_field' --> $DIR/internal-unstable-noallow.rs:22:35 @@ -32,7 +32,7 @@ LL | |x: internal_unstable::Bar| { access_field_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(struct2_field)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/internal/internal-unstable.stderr b/src/test/ui/internal/internal-unstable.stderr index 2c9d14692103f..2c6bf42ae86f0 100644 --- a/src/test/ui/internal/internal-unstable.stderr +++ b/src/test/ui/internal/internal-unstable.stderr @@ -40,6 +40,7 @@ LL | bar!(internal_unstable::unstable()); | ------------------------------------ in this macro invocation | = help: add `#![feature(function)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/issues/issue-12997-2.stderr b/src/test/ui/issues/issue-12997-2.stderr index 01f8e34883605..04464896e921e 100644 --- a/src/test/ui/issues/issue-12997-2.stderr +++ b/src/test/ui/issues/issue-12997-2.stderr @@ -3,6 +3,8 @@ error[E0308]: mismatched types | LL | fn bar(x: isize) { } | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&mut test::Bencher` + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13446.stderr b/src/test/ui/issues/issue-13446.stderr index fbafae5e6344c..71d3bfe3398a6 100644 --- a/src/test/ui/issues/issue-13446.stderr +++ b/src/test/ui/issues/issue-13446.stderr @@ -6,7 +6,7 @@ LL | static VEC: [u32; 256] = vec![]; | = note: expected array `[u32; 256]` found struct `std::vec::Vec<_>` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-14091-2.stderr b/src/test/ui/issues/issue-14091-2.stderr index 2d6e9567d265d..499ebe977edc4 100644 --- a/src/test/ui/issues/issue-14091-2.stderr +++ b/src/test/ui/issues/issue-14091-2.stderr @@ -5,6 +5,7 @@ LL | assert!(x, x); | ^^^^^^^^^^^^^^ cannot apply unary operator `!` | = note: an implementation of `std::ops::Not` might be missing for `BytePos` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-15167.stderr b/src/test/ui/issues/issue-15167.stderr index 1c488bf6fba8d..fff28b0c3afc4 100644 --- a/src/test/ui/issues/issue-15167.stderr +++ b/src/test/ui/issues/issue-15167.stderr @@ -6,6 +6,8 @@ LL | macro_rules! f { () => (n) } ... LL | println!("{}", f!()); | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 @@ -15,6 +17,8 @@ LL | macro_rules! f { () => (n) } ... LL | println!("{}", f!()); | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 @@ -24,6 +28,8 @@ LL | macro_rules! f { () => (n) } ... LL | println!("{}", f!()); | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 @@ -33,6 +39,8 @@ LL | macro_rules! f { () => (n) } ... LL | println!("{}", f!()); | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-16098.stderr b/src/test/ui/issues/issue-16098.stderr index a34039a6eec7d..077c720a9cdb4 100644 --- a/src/test/ui/issues/issue-16098.stderr +++ b/src/test/ui/issues/issue-16098.stderr @@ -8,6 +8,7 @@ LL | println!("Problem 1: {}", prob1!(1000)); | ------------ in this macro invocation | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_16098`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr index dc715e2858b47..30932a375b1f0 100644 --- a/src/test/ui/issues/issue-16966.stderr +++ b/src/test/ui/issues/issue-16966.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | panic!(std::default::Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr index a7bb4fc512874..a24dc8a259dfb 100644 --- a/src/test/ui/issues/issue-21160.stderr +++ b/src/test/ui/issues/issue-21160.stderr @@ -8,6 +8,8 @@ LL | struct Foo(Bar); | LL | fn hash(&self, state: &mut H); | - required by this bound in `std::hash::Hash::hash` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2150.stderr b/src/test/ui/issues/issue-2150.stderr index f3de6941cfe94..f1cb3890a72ef 100644 --- a/src/test/ui/issues/issue-2150.stderr +++ b/src/test/ui/issues/issue-2150.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25385.stderr b/src/test/ui/issues/issue-25385.stderr index ab4db7e42a4b9..2ed48356e9f56 100644 --- a/src/test/ui/issues/issue-25385.stderr +++ b/src/test/ui/issues/issue-25385.stderr @@ -6,6 +6,8 @@ LL | ($e:expr) => { $e.foo() } ... LL | foo!(a); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no method named `foo` found for type `i32` in the current scope --> $DIR/issue-25385.rs:10:15 diff --git a/src/test/ui/issues/issue-25386.stderr b/src/test/ui/issues/issue-25386.stderr index eabb139b97db5..76a4a5a493f59 100644 --- a/src/test/ui/issues/issue-25386.stderr +++ b/src/test/ui/issues/issue-25386.stderr @@ -6,6 +6,8 @@ LL | (*$var.c_object).$member.is_some() ... LL | println!("{}", check_ptr_exist!(item, name)); | ---------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0616]: field `name` of struct `stuff::CObj` is private --> $DIR/issue-25386.rs:19:9 @@ -15,6 +17,8 @@ LL | (*$var.c_object).$member.is_some() ... LL | println!("{}", check_ptr_exist!(item, name)); | ---------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-25793.stderr b/src/test/ui/issues/issue-25793.stderr index daea9cd8cd717..9d66ba3aae142 100644 --- a/src/test/ui/issues/issue-25793.stderr +++ b/src/test/ui/issues/issue-25793.stderr @@ -10,6 +10,8 @@ LL | r.get_size(width!(self)) | -------- ------------ in this macro invocation | | | borrow later used by call + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-26093.stderr b/src/test/ui/issues/issue-26093.stderr index c96228b518a85..204786c65c1d9 100644 --- a/src/test/ui/issues/issue-26093.stderr +++ b/src/test/ui/issues/issue-26093.stderr @@ -9,6 +9,8 @@ LL | not_a_place!(99); | | | | | cannot assign to this expression | in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0067]: invalid left-hand side of assignment --> $DIR/issue-26093.rs:5:16 @@ -21,6 +23,8 @@ LL | not_a_place!(99); | | | | | cannot assign to this expression | in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26094.stderr b/src/test/ui/issues/issue-26094.stderr index 36b2d3d074b0c..0b5b6d5a7504f 100644 --- a/src/test/ui/issues/issue-26094.stderr +++ b/src/test/ui/issues/issue-26094.stderr @@ -9,6 +9,8 @@ LL | fn some_function() {} ... LL | some_macro!(some_function); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-27340.stderr b/src/test/ui/issues/issue-27340.stderr index 05b213b293cbf..f2c659083f63c 100644 --- a/src/test/ui/issues/issue-27340.stderr +++ b/src/test/ui/issues/issue-27340.stderr @@ -6,6 +6,8 @@ LL | #[derive(Copy, Clone)] LL | LL | struct Bar(Foo); | --- this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-27592.stderr b/src/test/ui/issues/issue-27592.stderr index c8649d82d7451..cf59016ded4cf 100644 --- a/src/test/ui/issues/issue-27592.stderr +++ b/src/test/ui/issues/issue-27592.stderr @@ -6,12 +6,16 @@ LL | write(|| format_args!("{}", String::from("Hello world"))); | | | | | temporary value created here | returns a value referencing data owned by the current function + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0515]: cannot return reference to temporary value --> $DIR/issue-27592.rs:16:14 | LL | write(|| format_args!("{}", String::from("Hello world"))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-29084.stderr b/src/test/ui/issues/issue-29084.stderr index 3e7ea745ce49a..bc22e9371395f 100644 --- a/src/test/ui/issues/issue-29084.stderr +++ b/src/test/ui/issues/issue-29084.stderr @@ -6,6 +6,8 @@ LL | bar(&mut $d); ... LL | foo!(0u8); | ---------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-31011.stderr b/src/test/ui/issues/issue-31011.stderr index c7618e0835b8d..deaf490466cec 100644 --- a/src/test/ui/issues/issue-31011.stderr +++ b/src/test/ui/issues/issue-31011.stderr @@ -9,6 +9,8 @@ LL | fn wrap(context: &T) -> () LL | { LL | log!(context, "entered wrapper"); | --------------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr index ca085b25c2ddf..5d5ad8aed9855 100644 --- a/src/test/ui/issues/issue-32655.stderr +++ b/src/test/ui/issues/issue-32655.stderr @@ -6,6 +6,8 @@ LL | #[derive_Clone] ... LL | foo!(); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find attribute `derive_Clone` in this scope --> $DIR/issue-32655.rs:15:7 diff --git a/src/test/ui/issues/issue-32782.stderr b/src/test/ui/issues/issue-32782.stderr index 029826f09a2dc..3d74897aab28d 100644 --- a/src/test/ui/issues/issue-32782.stderr +++ b/src/test/ui/issues/issue-32782.stderr @@ -8,6 +8,7 @@ LL | foo!(); | ------- in this macro invocation | = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32829.stderr b/src/test/ui/issues/issue-32829.stderr index 25da3f6a55065..98201b050ecbe 100644 --- a/src/test/ui/issues/issue-32829.stderr +++ b/src/test/ui/issues/issue-32829.stderr @@ -6,7 +6,7 @@ LL | static S : u64 = { { panic!("foo"); 0 } }; | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 = help: add `#![feature(const_panic)]` to the crate attributes to enable - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32950.stderr b/src/test/ui/issues/issue-32950.stderr index 3cdf35af1d866..06a6ebd9704f1 100644 --- a/src/test/ui/issues/issue-32950.stderr +++ b/src/test/ui/issues/issue-32950.stderr @@ -9,6 +9,8 @@ error[E0412]: cannot find type `FooBar` in this scope | LL | concat_idents!(Foo, Bar) | ^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-34229.stderr b/src/test/ui/issues/issue-34229.stderr index 9e1734899bdd2..cd9be6ab72c89 100644 --- a/src/test/ui/issues/issue-34229.stderr +++ b/src/test/ui/issues/issue-34229.stderr @@ -6,6 +6,7 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); | = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Comparable` with `Comparable` --> $DIR/issue-34229.rs:2:46 @@ -15,6 +16,7 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); | = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Comparable` with `Comparable` --> $DIR/issue-34229.rs:2:46 @@ -24,6 +26,7 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); | = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Comparable` with `Comparable` --> $DIR/issue-34229.rs:2:46 @@ -33,6 +36,7 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); | = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `Comparable` with `Comparable` --> $DIR/issue-34229.rs:2:46 @@ -42,6 +46,7 @@ LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); | = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index 8d20377be576a..c68b271807b99 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -33,7 +33,7 @@ LL | let sr: Vec<(u32, _, _) = vec![]; | = note: expected type `bool` found struct `std::vec::Vec<_>` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0070]: invalid left-hand side of assignment --> $DIR/issue-34334.rs:2:29 diff --git a/src/test/ui/issues/issue-38821.stderr b/src/test/ui/issues/issue-38821.stderr index 0687fc940dec1..e355094261de1 100644 --- a/src/test/ui/issues/issue-38821.stderr +++ b/src/test/ui/issues/issue-38821.stderr @@ -5,6 +5,7 @@ LL | #[derive(Debug, Copy, Clone)] | ^^^^ the trait `NotNull` is not implemented for `::SqlType` | = note: required because of the requirements on the impl of `IntoNullable` for `::SqlType` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-42954.stderr b/src/test/ui/issues/issue-42954.stderr index 8c35088a1bbeb..840cceea7b0fd 100644 --- a/src/test/ui/issues/issue-42954.stderr +++ b/src/test/ui/issues/issue-42954.stderr @@ -9,6 +9,8 @@ LL | $i as u32 < 0 ... LL | is_plainly_printable!(c); | ------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-48364.stderr b/src/test/ui/issues/issue-48364.stderr index e5bb9298cd584..5ccede308a1c1 100644 --- a/src/test/ui/issues/issue-48364.stderr +++ b/src/test/ui/issues/issue-48364.stderr @@ -6,6 +6,7 @@ LL | b"".starts_with(stringify!(foo)) | = note: expected reference `&[u8]` found reference `&'static str` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-48728.stderr b/src/test/ui/issues/issue-48728.stderr index 84c10d8fbc477..a0698c2079835 100644 --- a/src/test/ui/issues/issue-48728.stderr +++ b/src/test/ui/issues/issue-48728.stderr @@ -8,6 +8,7 @@ LL | impl Clone for Node<[T]> { | ------------------------------------------- first implementation here | = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `[_]` in future versions + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-50480.stderr b/src/test/ui/issues/issue-50480.stderr index 2b92664d57772..dfcac1281730b 100644 --- a/src/test/ui/issues/issue-50480.stderr +++ b/src/test/ui/issues/issue-50480.stderr @@ -29,6 +29,8 @@ LL | struct Foo(NotDefined, ::Item, Vec, String); | -------- ------ this field does not implement `Copy` | | | this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-51848.stderr b/src/test/ui/issues/issue-51848.stderr index 31faaab6141c5..051c4d7f42793 100644 --- a/src/test/ui/issues/issue-51848.stderr +++ b/src/test/ui/issues/issue-51848.stderr @@ -10,6 +10,7 @@ LL | macro_with_error!(); | -------------------- in this macro invocation | = note: if you intended to print `{`, you can escape it using `{{` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found --> $DIR/issue-51848.rs:18:15 diff --git a/src/test/ui/issues/issue-53251.stderr b/src/test/ui/issues/issue-53251.stderr index 21e41574a4683..cd5030f761987 100644 --- a/src/test/ui/issues/issue-53251.stderr +++ b/src/test/ui/issues/issue-53251.stderr @@ -6,6 +6,8 @@ LL | S::f::(); ... LL | impl_add!(a b); | --------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0107]: wrong number of type arguments: expected 0, found 1 --> $DIR/issue-53251.rs:11:24 @@ -15,6 +17,8 @@ LL | S::f::(); ... LL | impl_add!(a b); | --------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr index 1f38c70a11938..3ac8dc548aeb9 100644 --- a/src/test/ui/issues/issue-56411.stderr +++ b/src/test/ui/issues/issue-56411.stderr @@ -13,6 +13,7 @@ LL | import!(("issue-56411-aux.rs", issue_56411_aux)); | ------------------------------------------------- in this macro invocation | = note: `issue_56411_aux` must be defined only once in the type namespace of this module + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0365]: `issue_56411_aux` is private, and cannot be re-exported --> $DIR/issue-56411.rs:6:21 @@ -24,6 +25,7 @@ LL | import!(("issue-56411-aux.rs", issue_56411_aux)); | ------------------------------------------------- in this macro invocation | = note: consider declaring type or module `issue_56411_aux` with `pub` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 4e5cf23afe143..2ac5577e0a0ec 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -80,7 +80,7 @@ LL | assert_eq!(Foo::Bar, i); | fn(usize) -> Foo {Foo::Bar} | = note: an implementation of `std::cmp::PartialEq` might be missing for `fn(usize) -> Foo {Foo::Bar}` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` --> $DIR/issue-59488.rs:30:5 @@ -91,7 +91,7 @@ LL | assert_eq!(Foo::Bar, i); = help: the trait `std::fmt::Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn(usize) -> Foo {Foo::Bar}` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` --> $DIR/issue-59488.rs:30:5 @@ -102,7 +102,7 @@ LL | assert_eq!(Foo::Bar, i); = help: the trait `std::fmt::Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn(usize) -> Foo {Foo::Bar}` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/src/test/ui/issues/issue-6596-1.stderr b/src/test/ui/issues/issue-6596-1.stderr index 2a4ece2f2425f..4f29d8a927456 100644 --- a/src/test/ui/issues/issue-6596-1.stderr +++ b/src/test/ui/issues/issue-6596-1.stderr @@ -6,6 +6,8 @@ LL | $nonexistent ... LL | e!(foo); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-6596-2.stderr b/src/test/ui/issues/issue-6596-2.stderr index 20fbe0fab0112..4fcb0176faafd 100644 --- a/src/test/ui/issues/issue-6596-2.stderr +++ b/src/test/ui/issues/issue-6596-2.stderr @@ -6,6 +6,8 @@ LL | { $inp $nonexistent } ... LL | g!(foo); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr index 8d1a03ac207e1..78760efd8d123 100644 --- a/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr +++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr @@ -12,6 +12,8 @@ LL | $($c)ö* {} ... LL | x!(if); | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index 10d05fd8f2b1b..2cb6e62e41294 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -10,7 +10,7 @@ LL | x.use_mut(); | - borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr index bf737bcc0e347..a14bf2ec8ca97 100644 --- a/src/test/ui/lint/lint-stability2.stderr +++ b/src/test/ui/lint/lint-stability2.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr index 29b19577f440f..858ac12612c69 100644 --- a/src/test/ui/lint/lint-stability3.stderr +++ b/src/test/ui/lint/lint-stability3.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index 8e56fd4139b1f..0b2b9fab3925e 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -90,6 +90,8 @@ LL | unsafe {} ... LL | unsafe_in_macro!() | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 14 previous errors diff --git a/src/test/ui/lint/lints-in-foreign-macros.stderr b/src/test/ui/lint/lints-in-foreign-macros.stderr index 0d2adb2ad0492..207d85a89c723 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.stderr +++ b/src/test/ui/lint/lints-in-foreign-macros.stderr @@ -12,6 +12,7 @@ note: the lint level is defined here | LL | #![warn(unused_imports)] | ^^^^^^^^^^^^^^ + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: unused import: `std::string::ToString` --> $DIR/lints-in-foreign-macros.rs:16:18 diff --git a/src/test/ui/lint/test-inner-fn.stderr b/src/test/ui/lint/test-inner-fn.stderr index bf476a45f772c..a8974e1cf96b7 100644 --- a/src/test/ui/lint/test-inner-fn.stderr +++ b/src/test/ui/lint/test-inner-fn.stderr @@ -5,12 +5,15 @@ LL | #[test] | ^^^^^^^ | = note: requested on the command line with `-D unnameable-test-items` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot test inner items --> $DIR/test-inner-fn.rs:13:9 | LL | #[test] | ^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr index abe07b1c6496c..fd3f2dbc07670 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr +++ b/src/test/ui/lint/unreachable_pub-pub_crate.stderr @@ -132,6 +132,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); | in this macro invocation | = help: or consider exporting it for use by other crates + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable `pub` item --> $DIR/unreachable_pub-pub_crate.rs:45:9 diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr index 6144d5bb6577c..ad687a4b54e6c 100644 --- a/src/test/ui/lint/unreachable_pub.stderr +++ b/src/test/ui/lint/unreachable_pub.stderr @@ -132,6 +132,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); | in this macro invocation | = help: or consider exporting it for use by other crates + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable `pub` item --> $DIR/unreachable_pub.rs:41:9 diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index 6b4de6618c51b..ae63bad841fa3 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -9,6 +9,8 @@ LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } ... LL | test!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:7:19 diff --git a/src/test/ui/macros/assert.stderr b/src/test/ui/macros/assert.stderr index 4bbdf01150c4c..8aa7c33185983 100644 --- a/src/test/ui/macros/assert.stderr +++ b/src/test/ui/macros/assert.stderr @@ -16,7 +16,7 @@ error: macro requires a boolean expression as an argument LL | debug_assert!(); | ^^^^^^^^^^^^^^^^ boolean expression required | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/assert.rs:5:19 diff --git a/src/test/ui/macros/cfg.stderr b/src/test/ui/macros/cfg.stderr index 0fdb62922a751..bbfc5e27fec04 100644 --- a/src/test/ui/macros/cfg.stderr +++ b/src/test/ui/macros/cfg.stderr @@ -3,6 +3,8 @@ error: macro requires a cfg-pattern as an argument | LL | cfg!(); | ^^^^^^^ cfg-pattern required + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected identifier, found `123` --> $DIR/cfg.rs:3:10 diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr index 0e2fb4c8af513..5943a252579ab 100644 --- a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr +++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr @@ -12,6 +12,7 @@ LL | | } LL | format_args!(hang!()); | ------- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with | LL | format_args!("{}", hang!()); diff --git a/src/test/ui/macros/format-parse-errors.stderr b/src/test/ui/macros/format-parse-errors.stderr index 0c10fb644b0f6..66cffbfa18170 100644 --- a/src/test/ui/macros/format-parse-errors.stderr +++ b/src/test/ui/macros/format-parse-errors.stderr @@ -4,7 +4,7 @@ error: requires at least a format string argument LL | format!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/format-parse-errors.rs:5:13 diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr index 92d1afe1b645a..c94355f47161c 100644 --- a/src/test/ui/macros/issue-54441.stderr +++ b/src/test/ui/macros/issue-54441.stderr @@ -6,6 +6,8 @@ LL | let ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr index 85dee9f24fe2f..2ce565936f2b5 100644 --- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr +++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr @@ -6,6 +6,8 @@ LL | 1.fake() ... LL | fake_method_stmt!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:11:13 @@ -15,6 +17,8 @@ LL | 1.fake ... LL | fake_field_stmt!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:17:15 @@ -24,6 +28,8 @@ LL | (1).0 ... LL | fake_anon_field_stmt!(); | ------------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0689]: can't call method `neg` on ambiguous numeric type `{float}` --> $DIR/macro-backtrace-invalid-internals.rs:41:15 @@ -34,6 +40,7 @@ LL | 2.0.neg() LL | real_method_stmt!(); | -------------------- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you must specify a concrete type for this numeric value, like `f32` | LL | 2.0_f32.neg() @@ -47,6 +54,8 @@ LL | 1.fake() ... LL | let _ = fake_method_expr!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:29:13 @@ -56,6 +65,8 @@ LL | 1.fake ... LL | let _ = fake_field_expr!(); | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:35:15 @@ -65,6 +76,8 @@ LL | (1).0 ... LL | let _ = fake_anon_field_expr!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0689]: can't call method `neg` on ambiguous numeric type `{float}` --> $DIR/macro-backtrace-invalid-internals.rs:47:15 @@ -75,6 +88,7 @@ LL | 2.0.neg() LL | let _ = real_method_expr!(); | ------------------- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you must specify a concrete type for this numeric value, like `f32` | LL | 2.0_f32.neg() diff --git a/src/test/ui/macros/macro-backtrace-nested.stderr b/src/test/ui/macros/macro-backtrace-nested.stderr index 501f525a05f77..8d3663833660c 100644 --- a/src/test/ui/macros/macro-backtrace-nested.stderr +++ b/src/test/ui/macros/macro-backtrace-nested.stderr @@ -6,6 +6,8 @@ LL | () => (fake) ... LL | 1 + call_nested_expr!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `fake` in this scope --> $DIR/macro-backtrace-nested.rs:5:12 @@ -15,6 +17,8 @@ LL | () => (fake) ... LL | call_nested_expr_sum!(); | ------------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/macro-backtrace-println.stderr b/src/test/ui/macros/macro-backtrace-println.stderr index 209ff09aea41b..b4194a833a4fa 100644 --- a/src/test/ui/macros/macro-backtrace-println.stderr +++ b/src/test/ui/macros/macro-backtrace-println.stderr @@ -6,6 +6,8 @@ LL | ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); ... LL | myprintln!("{}"); | ----------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 2a0779190f573..2e712110689f8 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -39,6 +39,8 @@ LL | () => ( i ; typeof ); ... LL | m!(); | ----- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/macros/macro-lifetime-used-with-labels.stderr b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr index 05418d9bddf3f..162b337bbef13 100644 --- a/src/test/ui/macros/macro-lifetime-used-with-labels.stderr +++ b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr @@ -8,4 +8,6 @@ LL | 'b: loop { | -- first declared here LL | br2!('b); | --------- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/macros/macro-local-data-key-priv.stderr b/src/test/ui/macros/macro-local-data-key-priv.stderr index 5519105ca9a54..c53a09aad5783 100644 --- a/src/test/ui/macros/macro-local-data-key-priv.stderr +++ b/src/test/ui/macros/macro-local-data-key-priv.stderr @@ -9,7 +9,7 @@ note: the constant `baz` is defined here | LL | thread_local!(static baz: f64 = 0.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr index 033e12a31ae00..461e71471fb3d 100644 --- a/src/test/ui/macros/macro-shadowing.stderr +++ b/src/test/ui/macros/macro-shadowing.stderr @@ -8,6 +8,7 @@ LL | m1!(); | ------ in this macro invocation | = note: macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `foo` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/macro-shadowing.rs:17:1 @@ -28,6 +29,7 @@ note: `foo` could also refer to the macro defined here | LL | macro_rules! foo { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr index d29e6b4d46f63..1ab6b79a61ecb 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.stderr +++ b/src/test/ui/macros/macros-nonfatal-errors.stderr @@ -3,6 +3,8 @@ error[E0665]: `Default` cannot be derived for enums, only structs | LL | #[derive(Default)] | ^^^^^^^ + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: inline assembly must be a string literal --> $DIR/macros-nonfatal-errors.rs:13:10 @@ -68,6 +70,8 @@ error: couldn't read $DIR/i'd be quite surprised if a file with this name existe | LL | include_str!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: argument must be a string literal --> $DIR/macros-nonfatal-errors.rs:28:20 @@ -80,6 +84,8 @@ error: couldn't read $DIR/i'd be quite surprised if a file with this name existe | LL | include_bytes!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trace_macros! accepts only `true` or `false` --> $DIR/macros-nonfatal-errors.rs:31:5 diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr index a8ee9cf255628..e3649e32d768d 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.stderr +++ b/src/test/ui/macros/must-use-in-macro-55516.stderr @@ -6,5 +6,5 @@ LL | write!(&mut example, "{}", 42); | = note: `-W unused-must-use` implied by `-W unused` = note: this `Result` may be an `Err` variant, which should be handled - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr index 93cc97d45830b..9521322f5c281 100644 --- a/src/test/ui/macros/nonterminal-matching.stderr +++ b/src/test/ui/macros/nonterminal-matching.stderr @@ -9,6 +9,8 @@ LL | n!(a $nt_item b); ... LL | complex_nonterminal!(enum E {}); | -------------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr index 8378286bdadf5..662266013d04a 100644 --- a/src/test/ui/macros/restricted-shadowing-legacy.stderr +++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr @@ -23,6 +23,7 @@ LL | macro_rules! m { () => {} } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:139:42 @@ -49,6 +50,7 @@ LL | macro_rules! m { () => {} } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:148:9 @@ -75,6 +77,7 @@ LL | macro_rules! m { () => {} } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:164:9 @@ -101,6 +104,7 @@ LL | macro_rules! m { () => { Wrong } } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:180:13 @@ -127,6 +131,7 @@ LL | macro_rules! m { () => { Wrong } } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:218:42 @@ -153,6 +158,7 @@ LL | macro_rules! m { () => { Wrong } } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:232:9 @@ -179,6 +185,7 @@ LL | macro_rules! m { () => {} } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-legacy.rs:262:42 @@ -205,6 +212,7 @@ LL | macro_rules! m { () => {} } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr index 12075d42b9a7c..609f0b6b18aaf 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.stderr +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -23,6 +23,7 @@ LL | macro m() {} ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-modern.rs:147:33 @@ -49,6 +50,7 @@ LL | macro m() {} ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-modern.rs:156:13 @@ -75,6 +77,7 @@ LL | macro m() {} ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-modern.rs:172:13 @@ -101,6 +104,7 @@ LL | macro m() { Wrong } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-modern.rs:190:17 @@ -127,6 +131,7 @@ LL | macro m() { Wrong } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/restricted-shadowing-modern.rs:233:33 @@ -153,6 +158,7 @@ LL | macro m() { Wrong } ... LL | include!(); | ----------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr index 0a7e019e59f33..65b67a9423876 100644 --- a/src/test/ui/macros/same-sequence-span.stderr +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -28,6 +28,7 @@ LL | | fn main() {} ... | | = note: allowed there are: `=>`, `,` or `;` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:19:1 @@ -36,6 +37,7 @@ LL | proc_macro_sequence::make_foo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/macros/span-covering-argument-1.stderr b/src/test/ui/macros/span-covering-argument-1.stderr index 2ac881107b96a..efb8f61e4621a 100644 --- a/src/test/ui/macros/span-covering-argument-1.stderr +++ b/src/test/ui/macros/span-covering-argument-1.stderr @@ -8,6 +8,8 @@ LL | *&mut $s = 0; ... LL | bad!(foo whatever); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 021c51fd726d3..a18e22e07f8bc 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -9,6 +9,8 @@ LL | my_faulty_macro!(bcd); ... LL | my_faulty_macro!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro --> $DIR/trace_faulty_macros.rs:33:5 @@ -30,6 +32,7 @@ LL | my_recursive_macro!(); | ---------------------- in this macro invocation | = help: consider adding a `#![recursion_limit="8"]` attribute to your crate (`trace_faulty_macros`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro --> $DIR/trace_faulty_macros.rs:34:5 diff --git a/src/test/ui/malformed/malformed-derive-entry.stderr b/src/test/ui/malformed/malformed-derive-entry.stderr index 1f1ee39b049e3..ddc75c905ac20 100644 --- a/src/test/ui/malformed/malformed-derive-entry.stderr +++ b/src/test/ui/malformed/malformed-derive-entry.stderr @@ -21,12 +21,16 @@ error[E0277]: the trait bound `Test1: std::clone::Clone` is not satisfied | LL | #[derive(Copy(Bad))] | ^^^^ the trait `std::clone::Clone` is not implemented for `Test1` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Test2: std::clone::Clone` is not satisfied --> $DIR/malformed-derive-entry.rs:6:10 | LL | #[derive(Copy="bad")] | ^^^^ the trait `std::clone::Clone` is not implemented for `Test2` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/malformed/malformed-interpolated.stderr b/src/test/ui/malformed/malformed-interpolated.stderr index 6f6ad4508be01..d1be82cf7b7d3 100644 --- a/src/test/ui/malformed/malformed-interpolated.stderr +++ b/src/test/ui/malformed/malformed-interpolated.stderr @@ -14,6 +14,8 @@ LL | #[rustc_dummy = $expr] ... LL | check!(-0); // ERROR, see above | ----------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected token: `0 + 0` --> $DIR/malformed-interpolated.rs:5:25 @@ -23,6 +25,8 @@ LL | #[rustc_dummy = $expr] ... LL | check!(0 + 0); // ERROR, see above | -------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr index a824e3565509d..686fbd0baa3ce 100644 --- a/src/test/ui/match/match-arm-resolving-to-never.stderr +++ b/src/test/ui/match/match-arm-resolving-to-never.stderr @@ -12,8 +12,6 @@ LL | | E::F => "", | | ^^ expected integer, found `&str` LL | | }; | |_____- `match` arms have incompatible types - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr index 277bcce6af9c5..10950834ad345 100644 --- a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr +++ b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr @@ -46,8 +46,6 @@ LL | mac!(bar); | ---------- you must specify a type for this binding, like `i32` LL | bar.pow(2); | ^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index d4dcb9a39a403..69a9d03e474ba 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -7,6 +7,7 @@ LL | $arr.len() * size_of($arr[0])); LL | write!(hello); | -------------- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit | LL | ($arr.len() * size_of($arr[0])).try_into().unwrap()); @@ -22,6 +23,7 @@ LL | cast!(2); | --------- in this macro invocation | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/missing/missing-semicolon-warning.stderr b/src/test/ui/missing/missing-semicolon-warning.stderr index b4001aba2882c..ecaefd47de0b4 100644 --- a/src/test/ui/missing/missing-semicolon-warning.stderr +++ b/src/test/ui/missing/missing-semicolon-warning.stderr @@ -8,6 +8,7 @@ LL | fn main() { m!(0, 0; 0, 0); } | --------------- in this macro invocation | = note: this was erroneously allowed and will become a hard error in a future release + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: expected `;`, found `println` --> $DIR/missing-semicolon-warning.rs:7:12 @@ -19,4 +20,5 @@ LL | fn main() { m!(0, 0; 0, 0); } | --------------- in this macro invocation | = note: this was erroneously allowed and will become a hard error in a future release + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 8f7d68737bc09..c652faafad461 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -8,7 +8,6 @@ LL | panic!() | -------- this returned value is of type `!` | = note: the return type of a function must have a statically known size - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/never_type/never-assign-dead-code.stderr b/src/test/ui/never_type/never-assign-dead-code.stderr index ef48083d67061..6002f8e1eb75e 100644 --- a/src/test/ui/never_type/never-assign-dead-code.stderr +++ b/src/test/ui/never_type/never-assign-dead-code.stderr @@ -12,7 +12,6 @@ note: the lint level is defined here LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable call --> $DIR/never-assign-dead-code.rs:10:5 diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr index cbb41263a83c4..4f9d428546bb1 100644 --- a/src/test/ui/on-unimplemented/no-debug.stderr +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -7,6 +7,7 @@ LL | println!("{:?} {:?}", Foo, Bar); = help: the trait `std::fmt::Debug` is not implemented for `Foo` = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required by `std::fmt::Debug::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug` --> $DIR/no-debug.rs:10:32 @@ -16,6 +17,7 @@ LL | println!("{:?} {:?}", Foo, Bar); | = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar` = note: required by `std::fmt::Debug::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Foo` doesn't implement `std::fmt::Display` --> $DIR/no-debug.rs:11:23 @@ -26,6 +28,7 @@ LL | println!("{} {}", Foo, Bar); = help: the trait `std::fmt::Display` is not implemented for `Foo` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: required by `std::fmt::Display::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display` --> $DIR/no-debug.rs:11:28 @@ -36,6 +39,7 @@ LL | println!("{} {}", Foo, Bar); = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: required by `std::fmt::Display::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr index eb93cfe774b9c..b414f9230b675 100644 --- a/src/test/ui/out-of-order-shadowing.stderr +++ b/src/test/ui/out-of-order-shadowing.stderr @@ -14,7 +14,7 @@ note: `bar` could also refer to the macro defined here | LL | macro_rules! bar { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr index dd193d6a86ebd..40599d228b27a 100644 --- a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr +++ b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -8,6 +8,7 @@ LL | mac1! { does_not_exist!() } | --------------------------- in this macro invocation | = note: `mut` may be followed by `variable` and `variable @ pattern` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected identifier, found `does_not_exist!()` --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:17 @@ -17,6 +18,8 @@ LL | let mut $eval = (); ... LL | mac2! { does_not_exist!() } | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `mut` must be followed by a named binding --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:13 @@ -28,6 +31,7 @@ LL | mac2! { does_not_exist!() } | --------------------------- in this macro invocation | = note: `mut` may be followed by `variable` and `variable @ pattern` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find macro `does_not_exist` in this scope --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13 diff --git a/src/test/ui/parser/macro/issue-37113.stderr b/src/test/ui/parser/macro/issue-37113.stderr index 7aadc0aa4b5c1..20ee9d35ec7e1 100644 --- a/src/test/ui/parser/macro/issue-37113.stderr +++ b/src/test/ui/parser/macro/issue-37113.stderr @@ -6,6 +6,8 @@ LL | $( $t, )* ... LL | test_macro!(String,); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/macro/issue-37234.stderr b/src/test/ui/parser/macro/issue-37234.stderr index 8cef5ae375853..2db0f848f75f1 100644 --- a/src/test/ui/parser/macro/issue-37234.stderr +++ b/src/test/ui/parser/macro/issue-37234.stderr @@ -6,6 +6,8 @@ LL | let x = 5 ""; ... LL | failed!(); | ---------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.stderr b/src/test/ui/parser/macro/macro-incomplete-parse.stderr index 46cccba74c0b6..c9d220b1a2743 100644 --- a/src/test/ui/parser/macro/macro-incomplete-parse.stderr +++ b/src/test/ui/parser/macro/macro-incomplete-parse.stderr @@ -17,6 +17,8 @@ LL | () => ( 1, ... LL | ignored_expr!(); | ---------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: macro expansion ignores token `,` and any following --> $DIR/macro-incomplete-parse.rs:16:14 diff --git a/src/test/ui/parser/macro/pub-item-macro.stderr b/src/test/ui/parser/macro/pub-item-macro.stderr index ae981ac4cbee3..49644cf6a0e64 100644 --- a/src/test/ui/parser/macro/pub-item-macro.stderr +++ b/src/test/ui/parser/macro/pub-item-macro.stderr @@ -8,6 +8,7 @@ LL | pub_x!(); | --------- in this macro invocation | = help: try adjusting the macro to put `pub` inside the invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0603]: static `x` is private --> $DIR/pub-item-macro.rs:17:23 @@ -23,6 +24,7 @@ LL | static x: u32 = 0; ... LL | pub_x!(); | --------- in this macro invocation + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr index 7647ba500e03a..5a89b5b936f5b 100644 --- a/src/test/ui/parser/macro/trait-non-item-macros.stderr +++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr @@ -6,6 +6,8 @@ LL | ($a:expr) => ($a) ... LL | bah!(2); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr index a0e290a834dfe..5f4c349d7d659 100644 --- a/src/test/ui/parser/mut-patterns.stderr +++ b/src/test/ui/parser/mut-patterns.stderr @@ -99,6 +99,8 @@ LL | let mut $p = 0; ... LL | foo!(x); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 12 previous errors diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index 50bfbcec2475e..0d4db74f9f4fd 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -166,6 +166,8 @@ LL | let ...$e; ... LL | mac!(0); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:141:19 @@ -177,6 +179,7 @@ LL | mac!(0); | -------- in this macro invocation | = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0586]: inclusive range with no end --> $DIR/recover-range-pats.rs:142:19 @@ -188,6 +191,7 @@ LL | mac!(0); | -------- in this macro invocation | = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `...` range patterns are deprecated --> $DIR/recover-range-pats.rs:42:13 @@ -251,6 +255,8 @@ LL | let $e1...$e2; ... LL | mac2!(0, 1); | ------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:20:12 diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index be484e3a4d417..95f6d53a9d40d 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -8,6 +8,7 @@ LL | let mk_pat!(); | --------- in this macro invocation | = note: only allowed in tuple, tuple struct, and slice patterns + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `..` patterns are not allowed here --> $DIR/rest-pat-semantic-disallowed.rs:18:9 diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.stderr b/src/test/ui/privacy/associated-item-privacy-inherent.stderr index 6471a7914e103..88561568ea5a4 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.stderr +++ b/src/test/ui/privacy/associated-item-privacy-inherent.stderr @@ -6,6 +6,8 @@ LL | let value = Pub::method; ... LL | priv_nominal::mac!(); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private --> $DIR/associated-item-privacy-inherent.rs:15:9 @@ -15,6 +17,8 @@ LL | value; ... LL | priv_nominal::mac!(); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private --> $DIR/associated-item-privacy-inherent.rs:17:13 @@ -24,6 +28,8 @@ LL | Pub.method(); ... LL | priv_nominal::mac!(); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: associated constant `CONST` is private --> $DIR/associated-item-privacy-inherent.rs:19:9 @@ -33,6 +39,8 @@ LL | Pub::CONST; ... LL | priv_nominal::mac!(); | --------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:37:21 @@ -42,6 +50,8 @@ LL | let value = Pub::method; ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:39:9 @@ -51,6 +61,8 @@ LL | value; ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:41:13 @@ -60,6 +72,8 @@ LL | Pub.method(loop {}); ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:57:21 @@ -69,6 +83,8 @@ LL | let value = Pub::method::; ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:59:9 @@ -78,6 +94,8 @@ LL | value; ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:61:9 @@ -87,6 +105,8 @@ LL | Pub.method::(); ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:80:21 @@ -96,6 +116,8 @@ LL | let value = ::method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:82:9 @@ -105,6 +127,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:84:21 @@ -114,6 +138,8 @@ LL | let value = Pub::method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:86:9 @@ -123,6 +149,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:88:21 @@ -132,6 +160,8 @@ LL | let value = ::static_method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:90:9 @@ -141,6 +171,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:92:21 @@ -150,6 +182,8 @@ LL | let value = Pub::static_method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:94:9 @@ -159,6 +193,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:96:19 @@ -168,6 +204,8 @@ LL | Pub(Priv).method(); ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:99:10 @@ -177,6 +215,8 @@ LL | ::CONST; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:101:9 @@ -186,6 +226,8 @@ LL | Pub::CONST; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 21 previous errors diff --git a/src/test/ui/privacy/associated-item-privacy-trait.stderr b/src/test/ui/privacy/associated-item-privacy-trait.stderr index 5cf1be82937f8..ac422e99855be 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.stderr +++ b/src/test/ui/privacy/associated-item-privacy-trait.stderr @@ -6,6 +6,8 @@ LL | let value = ::method; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r priv_trait::Pub) {::method}` is private --> $DIR/associated-item-privacy-trait.rs:19:9 @@ -15,6 +17,8 @@ LL | value; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r Self) {::method}` is private --> $DIR/associated-item-privacy-trait.rs:21:13 @@ -24,6 +28,8 @@ LL | Pub.method(); ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: associated constant `PrivTr::CONST` is private --> $DIR/associated-item-privacy-trait.rs:23:9 @@ -33,6 +39,8 @@ LL | ::CONST; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-trait.rs:25:13 @@ -42,6 +50,8 @@ LL | let _: ::AssocTy; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-trait.rs:25:16 @@ -51,6 +61,8 @@ LL | let _: ::AssocTy; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-trait.rs:28:34 @@ -60,6 +72,8 @@ LL | pub type InSignatureTy = ::AssocTy; ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-trait.rs:30:34 @@ -69,6 +83,8 @@ LL | pub trait InSignatureTr: PrivTr {} ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-trait.rs:32:14 @@ -78,6 +94,8 @@ LL | impl PrivTr for u8 {} ... LL | priv_trait::mac!(); | ------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-trait.rs:49:21 @@ -87,6 +105,8 @@ LL | let value = ::method; ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-trait.rs:51:9 @@ -96,6 +116,8 @@ LL | value; ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private --> $DIR/associated-item-privacy-trait.rs:53:13 @@ -105,6 +127,8 @@ LL | Pub.method(loop {}); ... LL | priv_signature::mac!(); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:70:21 @@ -114,6 +138,8 @@ LL | let value = ::method::; ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:72:9 @@ -123,6 +149,8 @@ LL | value; ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:74:9 @@ -132,6 +160,8 @@ LL | Pub.method::(); ... LL | priv_substs::mac!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:94:21 @@ -141,6 +171,8 @@ LL | let value = ::method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:96:9 @@ -150,6 +182,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:98:21 @@ -159,6 +193,8 @@ LL | let value = >::method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:100:9 @@ -168,6 +204,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:102:9 @@ -177,6 +215,8 @@ LL | Pub.method(); ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:105:21 @@ -186,6 +226,8 @@ LL | let value = >::method; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:107:9 @@ -195,6 +237,8 @@ LL | value; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:109:9 @@ -204,6 +248,8 @@ LL | Priv.method(); ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:112:9 @@ -213,6 +259,8 @@ LL | ::CONST; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:114:9 @@ -222,6 +270,8 @@ LL | >::CONST; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:116:9 @@ -231,6 +281,8 @@ LL | >::CONST; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:119:13 @@ -240,6 +292,8 @@ LL | let _: ::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:119:16 @@ -249,6 +303,8 @@ LL | let _: ::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:122:13 @@ -258,6 +314,8 @@ LL | let _: >::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:122:16 @@ -267,6 +325,8 @@ LL | let _: >::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:125:13 @@ -276,6 +336,8 @@ LL | let _: >::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:125:16 @@ -285,6 +347,8 @@ LL | let _: >::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:129:35 @@ -294,6 +358,8 @@ LL | pub type InSignatureTy1 = ::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:131:35 @@ -303,6 +369,8 @@ LL | pub type InSignatureTy2 = >::AssocTy; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-trait.rs:133:14 @@ -312,6 +380,8 @@ LL | impl PubTr for u8 {} ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 35 previous errors diff --git a/src/test/ui/privacy/associated-item-privacy-type-binding.stderr b/src/test/ui/privacy/associated-item-privacy-type-binding.stderr index 7f6886d7f9ad4..5afa286b85f27 100644 --- a/src/test/ui/privacy/associated-item-privacy-type-binding.stderr +++ b/src/test/ui/privacy/associated-item-privacy-type-binding.stderr @@ -6,6 +6,8 @@ LL | let _: Box>; ... LL | priv_trait::mac1!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:11:16 @@ -15,6 +17,8 @@ LL | let _: Box>; ... LL | priv_trait::mac1!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:14:31 @@ -24,6 +28,8 @@ LL | type InSignatureTy2 = Box>; ... LL | priv_trait::mac1!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:16:31 @@ -33,6 +39,8 @@ LL | trait InSignatureTr2: PubTr {} ... LL | priv_trait::mac1!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:20:13 @@ -42,6 +50,8 @@ LL | let _: Box>; ... LL | priv_trait::mac2!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:20:16 @@ -51,6 +61,8 @@ LL | let _: Box>; ... LL | priv_trait::mac2!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:23:31 @@ -60,6 +72,8 @@ LL | type InSignatureTy1 = Box>; ... LL | priv_trait::mac2!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `priv_trait::PrivTr` is private --> $DIR/associated-item-privacy-type-binding.rs:25:31 @@ -69,6 +83,8 @@ LL | trait InSignatureTr1: PrivTr {} ... LL | priv_trait::mac2!(); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:44:13 @@ -78,6 +94,8 @@ LL | let _: Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:44:16 @@ -87,6 +105,8 @@ LL | let _: Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:47:13 @@ -96,6 +116,8 @@ LL | let _: Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:47:16 @@ -105,6 +127,8 @@ LL | let _: Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:50:35 @@ -114,6 +138,8 @@ LL | pub type InSignatureTy1 = Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:52:35 @@ -123,6 +149,8 @@ LL | pub type InSignatureTy2 = Box>; ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:54:31 @@ -132,6 +160,8 @@ LL | trait InSignatureTr1: PubTrWithParam {} ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-type-binding.rs:56:31 @@ -141,6 +171,8 @@ LL | trait InSignatureTr2: PubTr {} ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 16 previous errors diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr index 4f57b17660ee5..376f1334ff806 100644 --- a/src/test/ui/privacy/private-inferred-type-3.stderr +++ b/src/test/ui/privacy/private-inferred-type-3.stderr @@ -4,7 +4,7 @@ error: type `fn() {ext::priv_fn}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: static `PRIV_STATIC` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -12,7 +12,7 @@ error: static `PRIV_STATIC` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `ext::PrivEnum` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -20,7 +20,7 @@ error: type `ext::PrivEnum` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn() {::method}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -28,7 +28,7 @@ error: type `fn() {::method}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -36,7 +36,7 @@ error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -44,7 +44,7 @@ error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private --> $DIR/private-inferred-type-3.rs:16:5 @@ -52,7 +52,7 @@ error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is priv LL | ext::m!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 7 previous errors diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr index 4d40b6b7cab32..48c83c2186591 100644 --- a/src/test/ui/privacy/private-inferred-type.stderr +++ b/src/test/ui/privacy/private-inferred-type.stderr @@ -114,6 +114,8 @@ LL | priv_fn; ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `m::PrivEnum` is private --> $DIR/private-inferred-type.rs:41:9 @@ -123,6 +125,8 @@ LL | PrivEnum::Variant; ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn() {::method}` is private --> $DIR/private-inferred-type.rs:43:9 @@ -132,6 +136,8 @@ LL | ::method; ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct}` is private --> $DIR/private-inferred-type.rs:45:9 @@ -141,6 +147,8 @@ LL | PrivTupleStruct; ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private --> $DIR/private-inferred-type.rs:47:9 @@ -150,6 +158,8 @@ LL | PubTupleStruct; ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r m::Pub) {m::Pub::::priv_method}` is private --> $DIR/private-inferred-type.rs:49:18 @@ -159,6 +169,8 @@ LL | Pub(0u8).priv_method(); ... LL | m::m!(); | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `m::Trait` is private --> $DIR/private-inferred-type.rs:118:5 diff --git a/src/test/ui/proc-macro/derive-bad.stderr b/src/test/ui/proc-macro/derive-bad.stderr index 93908150b6cfe..8667396c98989 100644 --- a/src/test/ui/proc-macro/derive-bad.stderr +++ b/src/test/ui/proc-macro/derive-bad.stderr @@ -3,6 +3,8 @@ error: expected `:`, found `}` | LL | A | ^ expected `:` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: proc-macro derive produced unparseable tokens --> $DIR/derive-bad.rs:7:5 diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index 76434860a4956..f82f49aa77526 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -15,6 +15,8 @@ error: cannot find attribute `empty_helper` in this scope | LL | #[derive(GenHelperUse)] | ^^^^^^^^^^^^ + | + = 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 --> $DIR/derive-helper-shadowing.rs:14:11 @@ -24,6 +26,8 @@ LL | #[empty_helper] ... LL | gen_helper_use!(); | ------------------ in this macro invocation + | + = 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) --> $DIR/derive-helper-shadowing.rs:24:13 diff --git a/src/test/ui/proc-macro/dollar-crate.stderr b/src/test/ui/proc-macro/dollar-crate.stderr index b9d9f9842bcee..465f242580dfb 100644 --- a/src/test/ui/proc-macro/dollar-crate.stderr +++ b/src/test/ui/proc-macro/dollar-crate.stderr @@ -11,6 +11,7 @@ LL | local!(); | --------- in this macro invocation | = note: `D` must be defined only once in the type namespace of this module + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0428]: the name `D` is defined multiple times --> $DIR/dollar-crate.rs:36:5 @@ -22,7 +23,7 @@ LL | dollar_crate_external::external!(); | previous definition of the type `D` here | = note: `D` must be defined only once in the type namespace of this module - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr index 5b6184afacdd0..ac75367d7ff3b 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr @@ -6,6 +6,7 @@ LL | #[derive(Unstable)] | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/proc-macro/expand-to-unstable.stderr b/src/test/ui/proc-macro/expand-to-unstable.stderr index 6df00765866a6..fdbf80f9b33ac 100644 --- a/src/test/ui/proc-macro/expand-to-unstable.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable.stderr @@ -5,6 +5,7 @@ LL | #[derive(Unstable)] | ^^^^^^^^ | = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr index ecebdfa965666..b65fc739e09cb 100644 --- a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -6,6 +6,8 @@ LL | gen_macro_rules!(); ... LL | generated!(); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_use` in this scope --> $DIR/gen-macro-rules-hygiene.rs:12:1 @@ -15,6 +17,8 @@ LL | gen_macro_rules!(); ... LL | generated!(); | ------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope --> $DIR/gen-macro-rules-hygiene.rs:21:9 diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index 496bd86e9882e..d239097263428 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -6,6 +6,7 @@ LL | generate_mod::check!(); | = note: possible candidate is found in another module, you can import it into scope: FromOutside + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:9:1 @@ -15,6 +16,7 @@ LL | generate_mod::check!(); | = note: possible candidate is found in another module, you can import it into scope: Outer + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:12:1 @@ -24,6 +26,7 @@ LL | #[generate_mod::check_attr] | = note: possible candidate is found in another module, you can import it into scope: FromOutside + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `OuterAttr` in this scope --> $DIR/generate-mod.rs:12:1 @@ -33,6 +36,7 @@ LL | #[generate_mod::check_attr] | = note: possible candidate is found in another module, you can import it into scope: OuterAttr + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:16:10 diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr index cf85974316abc..fe3e55b31be5d 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr @@ -3,6 +3,8 @@ error: unexpected closing delimiter: `)` | LL | lexer_failure!(); | ^^^^^^^^^^^^^^^^^ unexpected closing delimiter + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: proc macro panicked --> $DIR/invalid-punct-ident-4.rs:6:1 diff --git a/src/test/ui/proc-macro/issue-38586.stderr b/src/test/ui/proc-macro/issue-38586.stderr index 2584e0c62eece..4cdca5c8e01b0 100644 --- a/src/test/ui/proc-macro/issue-38586.stderr +++ b/src/test/ui/proc-macro/issue-38586.stderr @@ -3,6 +3,8 @@ error[E0425]: cannot find value `foo` in this scope | LL | #[derive(A)] | ^ not found in this scope + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/proc-macro/issue-50493.stderr b/src/test/ui/proc-macro/issue-50493.stderr index 56c7800102176..7997786b50bc9 100644 --- a/src/test/ui/proc-macro/issue-50493.stderr +++ b/src/test/ui/proc-macro/issue-50493.stderr @@ -9,12 +9,16 @@ error[E0616]: field `field` of struct `Restricted` is private | LL | #[derive(Derive)] | ^^^^^^ + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0616]: field `field` of struct `Restricted` is private --> $DIR/issue-50493.rs:6:10 | LL | #[derive(Derive)] | ^^^^^^ + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr index e0a3caef9db88..5995a4891f37d 100644 --- a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr +++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr @@ -3,6 +3,8 @@ error: expected crate top-level item to be a module after macro expansion, found | LL | #![issue_59191::no_main] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0601]: `main` function not found in crate `issue_59191_replace_root_with_fn` --> $DIR/issue-59191-replace-root-with-fn.rs:5:1 diff --git a/src/test/ui/proc-macro/lints_in_proc_macros.stderr b/src/test/ui/proc-macro/lints_in_proc_macros.stderr index 2d97cd700be9f..df9d7e1efe3de 100644 --- a/src/test/ui/proc-macro/lints_in_proc_macros.stderr +++ b/src/test/ui/proc-macro/lints_in_proc_macros.stderr @@ -3,6 +3,8 @@ error[E0425]: cannot find value `foobar2` in this scope | LL | bang_proc_macro2!(); | ^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/proc-macro/mixed-site-span.stderr b/src/test/ui/proc-macro/mixed-site-span.stderr index b5ca6cb9b29e4..c344147ed93ca 100644 --- a/src/test/ui/proc-macro/mixed-site-span.stderr +++ b/src/test/ui/proc-macro/mixed-site-span.stderr @@ -3,12 +3,16 @@ error[E0426]: use of undeclared label `'label_use` | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use` + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:15:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^^ not found in this scope + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:19:9 @@ -33,6 +37,7 @@ LL | | } LL | pass_dollar_crate!(); | --------------------- in this macro invocation | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: possible candidate is found in another module, you can import it into scope | LL | use ItemUse; diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr index e7f705c7feb67..c9390a04b9e24 100644 --- a/src/test/ui/proc-macro/multispan.stderr +++ b/src/test/ui/proc-macro/multispan.stderr @@ -20,6 +20,7 @@ note: found these 'hi's | LL | hello!(hi); | ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -43,6 +44,7 @@ note: found these 'hi's | LL | hello!(hi hi); | ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -66,6 +68,7 @@ note: found these 'hi's | LL | hello!(hi hi hi); | ^^ ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -89,6 +92,7 @@ note: found these 'hi's | LL | hello!(hi hey hi yo hi beep beep hi hi); | ^^ ^^ ^^ ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -112,6 +116,7 @@ note: found these 'hi's | LL | hello!(hi there, hi how are you? hi... hi.); | ^^ ^^ ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -135,6 +140,7 @@ note: found these 'hi's | LL | hello!(whoah. hi di hi di ho); | ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: hello to you, too! --> $DIR/auxiliary/multispan.rs:31:1 @@ -158,6 +164,7 @@ note: found these 'hi's | LL | hello!(hi good hi and good bye); | ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 7 previous errors diff --git a/src/test/ui/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr index 9f0fefcfe6c03..254f87751fd8e 100644 --- a/src/test/ui/proc-macro/parent-source-spans.stderr +++ b/src/test/ui/proc-macro/parent-source-spans.stderr @@ -6,6 +6,8 @@ LL | three!($a, $b); ... LL | one!("hello", "world"); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: second final: "world" --> $DIR/parent-source-spans.rs:19:16 @@ -15,6 +17,8 @@ LL | three!($a, $b); ... LL | one!("hello", "world"); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: first parent: "hello" --> $DIR/parent-source-spans.rs:13:5 @@ -24,6 +28,8 @@ LL | two!($a, $b); ... LL | one!("hello", "world"); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: second parent: "world" --> $DIR/parent-source-spans.rs:13:5 @@ -33,6 +39,8 @@ LL | two!($a, $b); ... LL | one!("hello", "world"); | ----------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: first grandparent: "hello" --> $DIR/parent-source-spans.rs:39:5 @@ -66,6 +74,8 @@ LL | three!($a, $b); ... LL | two!("yay", "rust"); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: second final: "rust" --> $DIR/parent-source-spans.rs:19:16 @@ -75,6 +85,8 @@ LL | three!($a, $b); ... LL | two!("yay", "rust"); | -------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: first parent: "yay" --> $DIR/parent-source-spans.rs:45:5 @@ -137,6 +149,8 @@ LL | one!("hello", "world"); | LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), | --------------------------------------------------- similarly named tuple variant `Ok` defined here + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:32:5 @@ -151,6 +165,8 @@ LL | two!("yay", "rust"); | LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), | --------------------------------------------------- similarly named tuple variant `Ok` defined here + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:32:5 @@ -165,6 +181,8 @@ LL | three!("hip", "hop"); | LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), | --------------------------------------------------- similarly named tuple variant `Ok` defined here + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 21 previous errors diff --git a/src/test/ui/proc-macro/subspan.stderr b/src/test/ui/proc-macro/subspan.stderr index 5117dd6d32d49..c82c2dee67673 100644 --- a/src/test/ui/proc-macro/subspan.stderr +++ b/src/test/ui/proc-macro/subspan.stderr @@ -9,6 +9,7 @@ note: here | LL | subspan!("hi"); | ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:14:1 @@ -21,6 +22,7 @@ note: here | LL | subspan!("hihi"); | ^^^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:17:1 @@ -33,6 +35,7 @@ note: here | LL | subspan!("hihihi"); | ^^^^^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:20:1 @@ -45,6 +48,7 @@ note: here | LL | subspan!("why I hide? hi!"); | ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:21:1 @@ -57,6 +61,7 @@ note: here | LL | subspan!("hey, hi, hidy, hidy, hi hi"); | ^^ ^^ ^^ ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:22:1 @@ -69,6 +74,7 @@ note: here | LL | subspan!("this is a hi, and this is another hi"); | ^^ ^^ ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:23:1 @@ -81,6 +87,7 @@ note: here | LL | subspan!("how are you this evening"); | ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: found 'hi's --> $DIR/subspan.rs:24:1 @@ -93,6 +100,7 @@ note: here | LL | subspan!("this is highly eradic"); | ^^ ^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr index 0698b0f475424..82c4167262fdd 100644 --- a/src/test/ui/proc-macro/three-equals.stderr +++ b/src/test/ui/proc-macro/three-equals.stderr @@ -16,6 +16,7 @@ LL | three_equals!(==); | ------------------ in this macro invocation | = help: input must be: `===` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: expected EOF, found `=`. --> $DIR/three-equals.rs:18:21 diff --git a/src/test/ui/range/range_traits-1.stderr b/src/test/ui/range/range_traits-1.stderr index f60ec23bdb0da..0e1da3d3f76fa 100644 --- a/src/test/ui/range/range_traits-1.stderr +++ b/src/test/ui/range/range_traits-1.stderr @@ -6,6 +6,7 @@ LL | a: Range, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` --> $DIR/range_traits-1.rs:12:5 @@ -15,6 +16,7 @@ LL | b: RangeTo, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` --> $DIR/range_traits-1.rs:19:5 @@ -24,6 +26,7 @@ LL | c: RangeFrom, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` --> $DIR/range_traits-1.rs:26:5 @@ -33,6 +36,7 @@ LL | d: RangeFull, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` --> $DIR/range_traits-1.rs:33:5 @@ -42,6 +46,7 @@ LL | e: RangeInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` --> $DIR/range_traits-1.rs:40:5 @@ -51,6 +56,7 @@ LL | f: RangeToInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` --> $DIR/range_traits-1.rs:5:5 @@ -60,6 +66,7 @@ LL | a: Range, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` --> $DIR/range_traits-1.rs:12:5 @@ -69,6 +76,7 @@ LL | b: RangeTo, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` --> $DIR/range_traits-1.rs:19:5 @@ -78,6 +86,7 @@ LL | c: RangeFrom, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` --> $DIR/range_traits-1.rs:26:5 @@ -87,6 +96,7 @@ LL | d: RangeFull, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` --> $DIR/range_traits-1.rs:33:5 @@ -96,6 +106,7 @@ LL | e: RangeInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` --> $DIR/range_traits-1.rs:40:5 @@ -105,6 +116,7 @@ LL | f: RangeToInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` --> $DIR/range_traits-1.rs:5:5 @@ -114,6 +126,7 @@ LL | a: Range, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` --> $DIR/range_traits-1.rs:12:5 @@ -123,6 +136,7 @@ LL | b: RangeTo, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` --> $DIR/range_traits-1.rs:19:5 @@ -132,6 +146,7 @@ LL | c: RangeFrom, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` --> $DIR/range_traits-1.rs:26:5 @@ -141,6 +156,7 @@ LL | d: RangeFull, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` --> $DIR/range_traits-1.rs:33:5 @@ -150,6 +166,7 @@ LL | e: RangeInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` --> $DIR/range_traits-1.rs:40:5 @@ -159,6 +176,7 @@ LL | f: RangeToInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` --> $DIR/range_traits-1.rs:5:5 @@ -168,6 +186,7 @@ LL | a: Range, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` --> $DIR/range_traits-1.rs:12:5 @@ -177,6 +196,7 @@ LL | b: RangeTo, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` --> $DIR/range_traits-1.rs:19:5 @@ -186,6 +206,7 @@ LL | c: RangeFrom, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` --> $DIR/range_traits-1.rs:26:5 @@ -195,6 +216,7 @@ LL | d: RangeFull, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` --> $DIR/range_traits-1.rs:33:5 @@ -204,6 +226,7 @@ LL | e: RangeInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` --> $DIR/range_traits-1.rs:40:5 @@ -213,6 +236,7 @@ LL | f: RangeToInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::Range` with `std::ops::Range` --> $DIR/range_traits-1.rs:5:5 @@ -222,6 +246,7 @@ LL | a: Range, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::Range` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeTo` with `std::ops::RangeTo` --> $DIR/range_traits-1.rs:12:5 @@ -231,6 +256,7 @@ LL | b: RangeTo, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeTo` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFrom` with `std::ops::RangeFrom` --> $DIR/range_traits-1.rs:19:5 @@ -240,6 +266,7 @@ LL | c: RangeFrom, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFrom` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull` --> $DIR/range_traits-1.rs:26:5 @@ -249,6 +276,7 @@ LL | d: RangeFull, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeFull` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeInclusive` with `std::ops::RangeInclusive` --> $DIR/range_traits-1.rs:33:5 @@ -258,6 +286,7 @@ LL | e: RangeInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `std::ops::RangeToInclusive` with `std::ops::RangeToInclusive` --> $DIR/range_traits-1.rs:40:5 @@ -267,6 +296,7 @@ LL | f: RangeToInclusive, | = help: the trait `std::cmp::PartialOrd` is not implemented for `std::ops::RangeToInclusive` = note: required by `std::cmp::PartialOrd::partial_cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::Range: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:5:5 @@ -275,6 +305,7 @@ LL | a: Range, | ^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::Range` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::RangeTo: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:12:5 @@ -283,6 +314,7 @@ LL | b: RangeTo, | ^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeTo` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::RangeFrom: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:19:5 @@ -291,6 +323,7 @@ LL | c: RangeFrom, | ^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeFrom` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::RangeFull: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:26:5 @@ -299,6 +332,7 @@ LL | d: RangeFull, | ^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeFull` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::RangeInclusive: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:33:5 @@ -307,6 +341,7 @@ LL | e: RangeInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeInclusive` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::ops::RangeToInclusive: std::cmp::Ord` is not satisfied --> $DIR/range_traits-1.rs:40:5 @@ -315,6 +350,7 @@ LL | f: RangeToInclusive, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `std::ops::RangeToInclusive` | = note: required by `std::cmp::Ord::cmp` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 36 previous errors diff --git a/src/test/ui/range/range_traits-2.stderr b/src/test/ui/range/range_traits-2.stderr index 598a0b3ed0374..8a9d15f09996b 100644 --- a/src/test/ui/range/range_traits-2.stderr +++ b/src/test/ui/range/range_traits-2.stderr @@ -5,6 +5,8 @@ LL | #[derive(Copy, Clone)] | ^^^^ LL | struct R(Range); | ------------ this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/range/range_traits-3.stderr b/src/test/ui/range/range_traits-3.stderr index e2713a2bd5ed8..14fda58e1f813 100644 --- a/src/test/ui/range/range_traits-3.stderr +++ b/src/test/ui/range/range_traits-3.stderr @@ -5,6 +5,8 @@ LL | #[derive(Copy, Clone)] | ^^^^ LL | struct R(RangeFrom); | ---------------- this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/range/range_traits-6.stderr b/src/test/ui/range/range_traits-6.stderr index 226d72ce0262e..693600cdce4d1 100644 --- a/src/test/ui/range/range_traits-6.stderr +++ b/src/test/ui/range/range_traits-6.stderr @@ -5,6 +5,8 @@ LL | #[derive(Copy, Clone)] | ^^^^ LL | struct R(RangeInclusive); | --------------------- this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr index 805c965a87903..130fd8535e0ff 100644 --- a/src/test/ui/reachable/expr_again.stderr +++ b/src/test/ui/reachable/expr_again.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index bd0c926279632..154734b0f696c 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -20,7 +20,7 @@ LL | return; LL | println!("foo"); | ^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index bfb4675df1186..850570d05646d 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -24,7 +24,7 @@ LL | return; LL | println!("But I am."); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index dd294ddccd970..fe7d7782edf55 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:21:5 @@ -21,7 +21,7 @@ LL | loop { return; } LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:32:5 @@ -31,7 +31,7 @@ LL | loop { 'middle: loop { loop { break 'middle; } } } LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index 796cbba12a2b1..a1c396e0c6116 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_match.rs:19:5 @@ -21,7 +21,7 @@ LL | match () { () if false => return, () => return } LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr index b15ed910a4feb..d95717676855e 100644 --- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr +++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr @@ -9,7 +9,6 @@ LL | assert_eq!(*x, 3); | ------------------ borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr index ed4f34b527fcb..d4bd760770d5f 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr @@ -12,6 +12,7 @@ LL | pub fn assert_test_result(result: T) { | ----------- required by this bound in `test::assert_test_result` | = help: the trait `std::process::Termination` is not implemented for `std::result::Result` + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr index 58ba38d1304fa..5611b5f4ece5f 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr @@ -7,8 +7,6 @@ LL | let _ = dbg!(a); | ------- value moved here LL | let _ = dbg!(a); | ^ value used here after move - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index 460561997e163..799a05bf7e898 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -8,7 +8,7 @@ LL | let _: NotDebug = dbg!(NotDebug); = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&NotDebug` = note: required by `std::fmt::Debug::fmt` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr index 8495fe62575bf..30f98d6df9e09 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr @@ -12,6 +12,7 @@ LL | #![warn(rust_2018_compatibility)] = note: `#[warn(absolute_paths_not_starting_with_crate)]` implied by `#[warn(rust_2018_compatibility)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #53130 + = note: this warning originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/suggestions-not-always-applicable.rs:17:5 @@ -21,4 +22,5 @@ LL | #[foo] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #53130 + = note: this warning originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr index 27b8d0e216e05..14c2582121bfd 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr @@ -17,6 +17,7 @@ LL | | } LL | m!(); | ----- in this macro invocation = help: use `self::std` to refer to this module unambiguously + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr index 44b34d2682d8a..de7b79de95c30 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr @@ -17,6 +17,7 @@ LL | | } LL | m!(); | ----- in this macro invocation = help: use `crate::std` to refer to this module unambiguously + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr index 5a981a4a6e48f..23c9513f9ccb4 100644 --- a/src/test/ui/span/E0204.stderr +++ b/src/test/ui/span/E0204.stderr @@ -15,6 +15,8 @@ LL | #[derive(Copy)] LL | struct Foo2<'a> { LL | ty: &'a mut bool, | ---------------- this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/E0204.rs:17:6 @@ -33,6 +35,8 @@ LL | #[derive(Copy)] LL | enum EFoo2<'a> { LL | Bar(&'a mut bool), | ------------ this field does not implement `Copy` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index ee1f99e3b07b4..d1960a8aab300 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types LL | s = format!("foo"); | ^^^^^^^^^^^^^^ expected `&mut std::string::String`, found struct `std::string::String` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index 3d00ef29052e9..184d9644c83ab 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | stream.write_fmt(format!("message received")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::fmt::Arguments`, found struct `std::string::String` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 4eb775155a54d..721d3b121726b 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -13,4 +13,5 @@ note: the lint level is defined here LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index b28e3cf8d666e..745936e11eafc 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -10,7 +10,7 @@ LL | y.use_ref(); | - borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index f928510454ae3..b0cef952b2107 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -6,7 +6,7 @@ LL | | "abc" LL | | }; | |______^ expected `&str`, found struct `std::string::String` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr index 092503cdf8063..b1ea100f16464 100644 --- a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr +++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | assert_eq!(10u64, 10usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 5d26366fe83c6..8dc041ace3662 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -33,7 +33,7 @@ LL | writeln!(fp, "hello world").unwrap(); | = note: the method `write_fmt` exists but the following trait bounds were not satisfied: `std::io::BufWriter<&dyn std::io::Write> : std::io::Write` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/path-display.stderr b/src/test/ui/suggestions/path-display.stderr index 39d236af4f3ae..13546cddbd359 100644 --- a/src/test/ui/suggestions/path-display.stderr +++ b/src/test/ui/suggestions/path-display.stderr @@ -8,6 +8,7 @@ LL | println!("{}", path); = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data = note: required because of the requirements on the impl of `std::fmt::Display` for `&std::path::Path` = note: required by `std::fmt::Display::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr index a69502de786f0..f9d0464ac88b1 100644 --- a/src/test/ui/suggestions/vec-macro-in-pattern.stderr +++ b/src/test/ui/suggestions/vec-macro-in-pattern.stderr @@ -10,7 +10,7 @@ LL | Some(vec![_x]) => (), | help: use a slice pattern here instead: `[_x]` | = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/trace_macros-gate.stderr b/src/test/ui/trace_macros-gate.stderr index 7b9542730713c..7b46bee6a6465 100644 --- a/src/test/ui/trace_macros-gate.stderr +++ b/src/test/ui/trace_macros-gate.stderr @@ -42,6 +42,7 @@ LL | expando!(true); | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 = help: add `#![feature(trace_macros)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr index d88397f398f88..6bae3a8587df0 100644 --- a/src/test/ui/try-block/try-block-opt-init.stderr +++ b/src/test/ui/try-block/try-block-opt-init.stderr @@ -4,7 +4,7 @@ error[E0381]: borrow of possibly-uninitialized variable: `cfg_res` LL | assert_eq!(cfg_res, 5); | ^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `cfg_res` | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.stderr b/src/test/ui/tuple/tuple-struct-fields/test2.stderr index 2f1ca2fe0c1e7..d6ea3626675d8 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test2.stderr +++ b/src/test/ui/tuple/tuple-struct-fields/test2.stderr @@ -8,6 +8,8 @@ LL | struct S3(pub $t ()); ... LL | define_struct! { (foo) } | ------------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `foo` in this scope --> $DIR/test2.rs:11:23 diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.stderr b/src/test/ui/tuple/tuple-struct-fields/test3.stderr index 5d42fe6ef50b3..b38513e5a92a3 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test3.stderr +++ b/src/test/ui/tuple/tuple-struct-fields/test3.stderr @@ -8,6 +8,8 @@ LL | struct S3(pub($t) ()); ... LL | define_struct! { foo } | ---------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `foo` in this scope --> $DIR/test3.rs:11:22 diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr index d6f4a8d761914..baffe4ea351c0 100644 --- a/src/test/ui/type/ascription/issue-47666.stderr +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -11,7 +11,7 @@ LL | let _ = Option:Some(vec![0, 1]); | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` = note: for more information, see https://github.com/rust-lang/rust/issues/23416 - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 7f0de3f1d70de..8162fed2cd8ec 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -6,7 +6,7 @@ LL | let x = vec![]; | | | consider giving `x` the explicit type `std::vec::Vec`, where the type parameter `T` is specified | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 1fa436c216b37..e62565c8f9b70 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -6,7 +6,7 @@ LL | let (x, ) = (vec![], ); | | | consider giving this pattern the explicit type `(std::vec::Vec,)`, where the type parameter `T` is specified | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 0ef5753b5907d..12b5321331a79 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -5,6 +5,7 @@ LL | #[derive(Clone)] | ^^^^^ the trait `std::marker::Copy` is not implemented for `U1` | = note: required by `std::clone::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 diff --git a/src/test/ui/union/union-derive-eq.stderr b/src/test/ui/union/union-derive-eq.stderr index f63ab1704c497..0955c161871d2 100644 --- a/src/test/ui/union/union-derive-eq.stderr +++ b/src/test/ui/union/union-derive-eq.stderr @@ -5,6 +5,7 @@ LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `PartialEqNotEq` | = note: required by `std::cmp::AssertParamIsEq` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/unreachable-code-ret.stderr b/src/test/ui/unreachable-code-ret.stderr index 021f8b03eab3a..72abb4fc8db19 100644 --- a/src/test/ui/unreachable-code-ret.stderr +++ b/src/test/ui/unreachable-code-ret.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/unused/unused-macro-rules.stderr b/src/test/ui/unused/unused-macro-rules.stderr index 9bb3c3f3dec8c..532d9339781d2 100644 --- a/src/test/ui/unused/unused-macro-rules.stderr +++ b/src/test/ui/unused/unused-macro-rules.stderr @@ -22,6 +22,8 @@ LL | | } ... LL | create_macro!(); | ---------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: unused macro definition --> $DIR/unused-macro-rules.rs:24:5 diff --git a/src/test/ui/while-let.stderr b/src/test/ui/while-let.stderr index 09f0d641de060..b2f2ec97c1467 100644 --- a/src/test/ui/while-let.stderr +++ b/src/test/ui/while-let.stderr @@ -10,6 +10,7 @@ LL | | }); | |_______- in this macro invocation | = note: `#[warn(irrefutable_let_patterns)]` on by default + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable while-let pattern --> $DIR/while-let.rs:7:13 @@ -21,6 +22,8 @@ LL | / bar!(_a, 1, { LL | | println!("irrefutable pattern"); LL | | }); | |_______- in this macro invocation + | + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable while-let pattern --> $DIR/while-let.rs:27:5 From 96af578cd9249223c89266306b104820e771858f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 6 Feb 2020 12:16:38 +0200 Subject: [PATCH 0968/1253] tests: add a revision to macro_backtrace without -Zmacro-backtrace. --- ...n.stderr => main.-Zmacro-backtrace.stderr} | 6 ++-- .../ui/macro_backtrace/main.default.stderr | 35 +++++++++++++++++++ src/test/ui/macro_backtrace/main.rs | 3 +- 3 files changed, 40 insertions(+), 4 deletions(-) rename src/test/ui/macro_backtrace/{main.stderr => main.-Zmacro-backtrace.stderr} (96%) create mode 100644 src/test/ui/macro_backtrace/main.default.stderr diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr similarity index 96% rename from src/test/ui/macro_backtrace/main.stderr rename to src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr index c4950e0fdf5b2..41ed545cf1687 100644 --- a/src/test/ui/macro_backtrace/main.stderr +++ b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr @@ -1,5 +1,5 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` - --> $DIR/main.rs:9:20 + --> $DIR/main.rs:10:20 | LL | / macro_rules! pong { LL | | () => { syntax error }; @@ -11,7 +11,7 @@ LL | pong!(); | -------- in this macro invocation error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` - --> $DIR/main.rs:9:20 + --> $DIR/main.rs:10:20 | LL | / macro_rules! pong { LL | | () => { syntax error }; @@ -31,7 +31,7 @@ LL | () => { pong ! () ; } | in this expansion of `ping!` error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` - --> $DIR/main.rs:9:20 + --> $DIR/main.rs:10:20 | LL | / macro_rules! pong { LL | | () => { syntax error }; diff --git a/src/test/ui/macro_backtrace/main.default.stderr b/src/test/ui/macro_backtrace/main.default.stderr new file mode 100644 index 0000000000000..fac76fd6080fe --- /dev/null +++ b/src/test/ui/macro_backtrace/main.default.stderr @@ -0,0 +1,35 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` + --> $DIR/main.rs:10:20 + | +LL | () => { syntax error }; + | ^^^^^ expected one of 8 possible tokens +... +LL | pong!(); + | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` + --> $DIR/main.rs:10:20 + | +LL | () => { syntax error }; + | ^^^^^ expected one of 8 possible tokens +... +LL | ping!(); + | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` + --> $DIR/main.rs:10:20 + | +LL | () => { syntax error }; + | ^^^^^ expected one of 8 possible tokens +... +LL | deep!(); + | -------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/macro_backtrace/main.rs b/src/test/ui/macro_backtrace/main.rs index 05f35855861f5..6cee3b4cd96d5 100644 --- a/src/test/ui/macro_backtrace/main.rs +++ b/src/test/ui/macro_backtrace/main.rs @@ -1,6 +1,7 @@ // Test that the macro backtrace facility works // aux-build:ping.rs -// compile-flags: -Z macro-backtrace +// revisions: default -Zmacro-backtrace +//[-Zmacro-backtrace] compile-flags: -Z macro-backtrace #[macro_use] extern crate ping; From 82c143561f2d9115263e774b0caf75af462f6fcb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 11 Nov 2019 13:14:01 -0500 Subject: [PATCH 0969/1253] do not limit NiceRegionError to SubSupConflict or ConcreteFailure --- .../nice_region_error/different_lifetimes.rs | 2 +- .../error_reporting/nice_region_error/mod.rs | 18 +++++++----------- .../nice_region_error/named_anon_conflict.rs | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index 8f4c643992001..6a9fe19e1ac3d 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -45,7 +45,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// /// It will later be extended to trait objects. pub(super) fn try_report_anon_anon_conflict(&self) -> Option { - let (span, sub, sup) = self.regions(); + let (span, sub, sup) = self.regions()?; // Determine whether the sub and sup consist of both anonymous (elided) regions. let anon_reg_sup = self.tcx().is_suitable_region(sup)?; diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index 8749d6cd34bed..b10a60ef6f11f 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -17,11 +17,6 @@ mod util; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool { - match *error { - ConcreteFailure(..) | SubSupConflict(..) => {} - _ => return false, // inapplicable - } - if let Some(tables) = self.in_progress_tables { let tables = tables.borrow(); NiceRegionError::new(self, error.clone(), Some(&tables)).try_report().is_some() @@ -79,13 +74,14 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { .or_else(|| self.try_report_impl_not_conforming_to_trait()) } - pub fn regions(&self) -> (Span, ty::Region<'tcx>, ty::Region<'tcx>) { + pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> { match (&self.error, self.regions) { - (Some(ConcreteFailure(origin, sub, sup)), None) => (origin.span(), sub, sup), - (Some(SubSupConflict(_, _, origin, sub, _, sup)), None) => (origin.span(), sub, sup), - (None, Some((span, sub, sup))) => (span, sub, sup), - (Some(_), Some(_)) => panic!("incorrectly built NiceRegionError"), - _ => panic!("trying to report on an incorrect lifetime failure"), + (Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), sub, sup)), + (Some(SubSupConflict(_, _, origin, sub, _, sup)), None) => { + Some((origin.span(), sub, sup)) + } + (None, Some((span, sub, sup))) => Some((span, sub, sup)), + _ => None, } } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index df37f53606b37..250dcff372c59 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -9,7 +9,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// When given a `ConcreteFailure` for a function with parameters containing a named region and /// an anonymous region, emit an descriptive diagnostic error. pub(super) fn try_report_named_anon_conflict(&self) -> Option> { - let (span, sub, sup) = self.regions(); + let (span, sub, sup) = self.regions()?; debug!( "try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})", From 65fc086dba3cd20e7e3d75c698c5816d82b7bbc7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Oct 2019 05:06:21 -0400 Subject: [PATCH 0970/1253] add a `IsEmpty` for use in verified bounds We currently have a kind of arbitrary check for `Verify` conditions which says that if the "test region" is `'empty`, then the check passes. This was added to fix #42467 -- it happens to be correct for the purposes that we use verify bounds for, but it doesn't feel generally correct. Replace with a more principled test. --- src/librustc/infer/lexical_region_resolve/mod.rs | 14 ++++++++------ src/librustc/infer/outlives/verify.rs | 13 ++++++++++++- src/librustc/infer/region_constraints/mod.rs | 6 +++++- src/librustc_mir/borrow_check/region_infer/mod.rs | 5 +++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 4b1f8a5be14f3..b0a9e0afa70aa 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -592,12 +592,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { debug!("collect_errors: verify={:?}", verify); let sub = var_data.normalize(self.tcx(), verify.region); - // This was an inference variable which didn't get - // constrained, therefore it can be assume to hold. - if let ty::ReEmpty = *sub { - continue; - } - let verify_kind_ty = verify.kind.to_ty(self.tcx()); if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) { continue; @@ -893,6 +887,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.region_rels.is_subregion_of(min, var_values.normalize(self.tcx(), r)) } + VerifyBound::IsEmpty => { + if let ty::ReEmpty = min { + true + } else { + false + } + } + VerifyBound::AnyBound(bs) => { bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min)) } diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 8ee8482e79dbc..9d6c3f30aa776 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -60,7 +60,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // scope type parameters: let param_bounds = param_bounds.chain(self.implicit_region_bound); - VerifyBound::AnyBound(param_bounds.map(|r| VerifyBound::OutlivedBy(r)).collect()) + let any_bounds: Vec<_> = param_bounds.map(|r| VerifyBound::OutlivedBy(r)).collect(); + + if any_bounds.is_empty() { + // We know that all types `T` outlive `'empty`, so if we + // can find no other bound, then check that the region + // being tested is `'empty`. + VerifyBound::IsEmpty + } else { + // If we can find any other bound R such that `T: R`, then + // we don't need to check for `'empty`, because `R: 'empty`. + VerifyBound::AnyBound(any_bounds) + } } /// Given a projection like `T::Item`, searches the environment diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 410058b70b5d8..667a4c3a7e2ab 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -233,6 +233,9 @@ pub enum VerifyBound<'tcx> { /// if `R: min`, then by transitivity `G: min`. OutlivedBy(Region<'tcx>), + /// Given a region `R`, true if it is `'empty`. + IsEmpty, + /// Given a set of bounds `B`, expands to the function: /// /// ```rust @@ -867,6 +870,7 @@ impl<'tcx> VerifyBound<'tcx> { VerifyBound::IfEq(..) => false, VerifyBound::OutlivedBy(ty::ReStatic) => true, VerifyBound::OutlivedBy(_) => false, + VerifyBound::IsEmpty => false, VerifyBound::AnyBound(bs) => bs.iter().any(|b| b.must_hold()), VerifyBound::AllBounds(bs) => bs.iter().all(|b| b.must_hold()), } @@ -875,7 +879,7 @@ impl<'tcx> VerifyBound<'tcx> { pub fn cannot_hold(&self) -> bool { match self { VerifyBound::IfEq(_, b) => b.cannot_hold(), - VerifyBound::OutlivedBy(ty::ReEmpty) => true, + VerifyBound::IsEmpty => false, VerifyBound::OutlivedBy(_) => false, VerifyBound::AnyBound(bs) => bs.iter().all(|b| b.cannot_hold()), VerifyBound::AllBounds(bs) => bs.iter().any(|b| b.cannot_hold()), diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 26d9cf2e0450f..6abca481eac9c 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -1108,6 +1108,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.eval_if_eq(tcx, body, generic_ty, lower_bound, test_ty, verify_bound1) } + VerifyBound::IsEmpty => { + let lower_bound_scc = self.constraint_sccs.scc(lower_bound); + self.scc_values.elements_contained_in(lower_bound_scc).next().is_none() + } + VerifyBound::OutlivedBy(r) => { let r_vid = self.to_region_vid(r); self.eval_outlives(r_vid, lower_bound) From 03b2fff40ed8c58357934789ab1158eafd942d39 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Oct 2019 05:11:50 -0400 Subject: [PATCH 0971/1253] don't mention specific region numbers in the ~ERROR message --- .../ty-outlives/projection-two-region-trait-bound-closure.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs index 20edfb33931af..2f18f600b753f 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -36,7 +36,7 @@ where T: Anything<'b, 'c>, { with_signature(cell, t, |cell, t| require(cell, t)); - //~^ ERROR associated type `>::AssocType` may not live long enough + //~^ ERROR may not live long enough } #[rustc_regions] @@ -46,7 +46,7 @@ where 'a: 'a, { with_signature(cell, t, |cell, t| require(cell, t)); - //~^ ERROR associated type `>::AssocType` may not live long enough + //~^ ERROR may not live long enough } #[rustc_regions] From b52414fedebe9774bf8a5339eb5042a2fa3dc9a3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Oct 2019 10:56:03 -0400 Subject: [PATCH 0972/1253] integrate the `sub_free_regions` code so we have only one copy of it --- .../infer/lexical_region_resolve/mod.rs | 38 ++++++-- src/librustc/infer/opaque_types/mod.rs | 4 +- src/librustc/middle/free_region.rs | 60 +------------ src/librustc/ty/free_region_map.rs | 89 +++++++++++++------ .../type_check/free_region_relations.rs | 9 +- 5 files changed, 106 insertions(+), 94 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index b0a9e0afa70aa..cd4d2257de896 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -420,12 +420,34 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// True if `a <= b`, but not defined over inference variables. fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { + let tcx = self.tcx(); + let sub_free_regions = |r1, r2| self.region_rels.free_regions.sub_free_regions(tcx, r1, r2); + + // Check for the case where we know that `'b: 'static` -- in that case, + // `a <= b` for all `a`. + let b_free_or_static = self.region_rels.free_regions.is_free_or_static(b); + if b_free_or_static && sub_free_regions(tcx.lifetimes.re_static, b) { + return true; + } + + // If both a and b are free, consult the declared + // relationships. Note that this can be more precise than the + // `lub` relationship defined below, since sometimes the "lub" + // is actually the `postdom_upper_bound` (see + // `TransitiveRelation` for more details). + let a_free_or_static = self.region_rels.free_regions.is_free_or_static(a); + if a_free_or_static && b_free_or_static { + return sub_free_regions(a, b); + } + + // For other cases, leverage the LUB code to find the LUB and + // check if it is equal to b. self.lub_concrete_regions(a, b) == b } /// Returns the smallest region `c` such that `a <= c` and `b <= c`. fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { - match (a, b) { + let r = match (a, b) { (&ty::ReClosureBound(..), _) | (_, &ty::ReClosureBound(..)) | (&ReLateBound(..), _) @@ -509,7 +531,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.tcx().lifetimes.re_static } } - } + }; + + debug!("lub_concrete_regions({:?}, {:?}) = {:?}", a, b, r); + + r } /// After expansion is complete, go and check upper bounds (i.e., @@ -528,7 +554,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } Constraint::RegSubReg(sub, sup) => { - if self.region_rels.is_subregion_of(sub, sup) { + if self.sub_concrete_regions(sub, sup) { continue; } @@ -557,7 +583,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Do not report these errors immediately: // instead, set the variable value to error and // collect them later. - if !self.region_rels.is_subregion_of(a_region, b_region) { + if !self.sub_concrete_regions(a_region, b_region) { debug!( "collect_errors: region error at {:?}: \ cannot verify that {:?}={:?} <= {:?}", @@ -754,7 +780,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { }; for upper_bound in &upper_bounds { - if !self.region_rels.is_subregion_of(effective_lower_bound, upper_bound.region) { + if !self.sub_concrete_regions(effective_lower_bound, upper_bound.region) { let origin = self.var_infos[node_idx].origin; debug!( "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ @@ -884,7 +910,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } VerifyBound::OutlivedBy(r) => { - self.region_rels.is_subregion_of(min, var_values.normalize(self.tcx(), r)) + self.sub_concrete_regions(min, var_values.normalize(self.tcx(), r)) } VerifyBound::IsEmpty => { diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index fe3a5d149f676..c86f9f66ec83a 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -384,9 +384,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match least_region { None => least_region = Some(subst_arg), Some(lr) => { - if free_region_relations.sub_free_regions(lr, subst_arg) { + if free_region_relations.sub_free_regions(self.tcx, lr, subst_arg) { // keep the current least region - } else if free_region_relations.sub_free_regions(subst_arg, lr) { + } else if free_region_relations.sub_free_regions(self.tcx, subst_arg, lr) { // switch to `subst_arg` least_region = Some(subst_arg); } else { diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 355f949b87008..62ccd94674488 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -4,8 +4,8 @@ //! and use that to decide when one free region outlives another, and so forth. use crate::middle::region; -use crate::ty::free_region_map::{FreeRegionMap, FreeRegionRelations}; -use crate::ty::{self, Region, TyCtxt}; +use crate::ty::free_region_map::FreeRegionMap; +use crate::ty::{Region, TyCtxt}; use rustc_hir::def_id::DefId; /// Combines a `region::ScopeTree` (which governs relationships between @@ -38,62 +38,6 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> { Self { tcx, context, region_scope_tree, free_regions } } - /// Determines whether one region is a subregion of another. This is intended to run *after - /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. - pub fn is_subregion_of( - &self, - sub_region: ty::Region<'tcx>, - super_region: ty::Region<'tcx>, - ) -> bool { - let result = sub_region == super_region || { - match (sub_region, super_region) { - (ty::ReEmpty, _) | (_, ty::ReStatic) => true, - - (ty::ReScope(sub_scope), ty::ReScope(super_scope)) => { - self.region_scope_tree.is_subscope_of(*sub_scope, *super_scope) - } - - (ty::ReScope(sub_scope), ty::ReEarlyBound(ref br)) => { - let fr_scope = self.region_scope_tree.early_free_scope(self.tcx, br); - self.region_scope_tree.is_subscope_of(*sub_scope, fr_scope) - } - - (ty::ReScope(sub_scope), ty::ReFree(fr)) => { - let fr_scope = self.region_scope_tree.free_scope(self.tcx, fr); - self.region_scope_tree.is_subscope_of(*sub_scope, fr_scope) - } - - (ty::ReEarlyBound(_), ty::ReEarlyBound(_)) - | (ty::ReFree(_), ty::ReEarlyBound(_)) - | (ty::ReEarlyBound(_), ty::ReFree(_)) - | (ty::ReFree(_), ty::ReFree(_)) => { - self.free_regions.sub_free_regions(sub_region, super_region) - } - - _ => false, - } - }; - let result = result || self.is_static(super_region); - debug!( - "is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", - sub_region, super_region, result - ); - result - } - - /// Determines whether this free region is required to be `'static`. - fn is_static(&self, super_region: ty::Region<'tcx>) -> bool { - debug!("is_static(super_region={:?})", super_region); - match *super_region { - ty::ReStatic => true, - ty::ReEarlyBound(_) | ty::ReFree(_) => { - let re_static = self.tcx.mk_region(ty::ReStatic); - self.free_regions.sub_free_regions(&re_static, &super_region) - } - _ => false, - } - } - pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { self.free_regions.lub_free_regions(self.tcx, r_a, r_b) } diff --git a/src/librustc/ty/free_region_map.rs b/src/librustc/ty/free_region_map.rs index 42f506606e69a..4cd6b4cfadb0c 100644 --- a/src/librustc/ty/free_region_map.rs +++ b/src/librustc/ty/free_region_map.rs @@ -23,11 +23,61 @@ impl<'tcx> FreeRegionMap<'tcx> { // (with the exception that `'static: 'x` is not notable) pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) { debug!("relate_regions(sub={:?}, sup={:?})", sub, sup); - if is_free_or_static(sub) && is_free(sup) { + if self.is_free_or_static(sub) && self.is_free(sup) { self.relation.add(sub, sup) } } + /// Tests whether `r_a <= r_b`. + /// + /// Both regions must meet `is_free_or_static`. + /// + /// Subtle: one tricky case that this code gets correct is as + /// follows. If we know that `r_b: 'static`, then this function + /// will return true, even though we don't know anything that + /// directly relates `r_a` and `r_b`. + /// + /// Also available through the `FreeRegionRelations` trait below. + pub fn sub_free_regions( + &self, + tcx: TyCtxt<'tcx>, + r_a: Region<'tcx>, + r_b: Region<'tcx>, + ) -> bool { + assert!(self.is_free_or_static(r_a) && self.is_free_or_static(r_b)); + let re_static = tcx.lifetimes.re_static; + if self.check_relation(re_static, r_b) { + // `'a <= 'static` is always true, and not stored in the + // relation explicitly, so check if `'b` is `'static` (or + // equivalent to it) + true + } else { + self.check_relation(r_a, r_b) + } + } + + /// Check whether `r_a <= r_b` is found in the relation + fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { + r_a == r_b || self.relation.contains(&r_a, &r_b) + } + + /// True for free regions other than `'static`. + pub fn is_free(&self, r: Region<'_>) -> bool { + match *r { + ty::ReEarlyBound(_) | ty::ReFree(_) => true, + _ => false, + } + } + + /// True if `r` is a free region or static of the sort that this + /// free region map can be used with. + pub fn is_free_or_static(&self, r: Region<'_>) -> bool { + match *r { + ty::ReStatic => true, + _ => self.is_free(r), + } + } + /// Computes the least-upper-bound of two free regions. In some /// cases, this is more conservative than necessary, in order to /// avoid making arbitrary choices. See @@ -39,13 +89,13 @@ impl<'tcx> FreeRegionMap<'tcx> { r_b: Region<'tcx>, ) -> Region<'tcx> { debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b); - assert!(is_free(r_a)); - assert!(is_free(r_b)); + assert!(self.is_free(r_a)); + assert!(self.is_free(r_b)); let result = if r_a == r_b { r_a } else { match self.relation.postdom_upper_bound(&r_a, &r_b) { - None => tcx.mk_region(ty::ReStatic), + None => tcx.lifetimes.re_static, Some(r) => *r, } }; @@ -60,31 +110,18 @@ impl<'tcx> FreeRegionMap<'tcx> { pub trait FreeRegionRelations<'tcx> { /// Tests whether `r_a <= r_b`. Both must be free regions or /// `'static`. - fn sub_free_regions(&self, shorter: ty::Region<'tcx>, longer: ty::Region<'tcx>) -> bool; + fn sub_free_regions( + &self, + tcx: TyCtxt<'tcx>, + shorter: ty::Region<'tcx>, + longer: ty::Region<'tcx>, + ) -> bool; } impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> { - fn sub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { - assert!(is_free_or_static(r_a) && is_free_or_static(r_b)); - if let ty::ReStatic = r_b { - true // `'a <= 'static` is just always true, and not stored in the relation explicitly - } else { - r_a == r_b || self.relation.contains(&r_a, &r_b) - } - } -} - -fn is_free(r: Region<'_>) -> bool { - match *r { - ty::ReEarlyBound(_) | ty::ReFree(_) => true, - _ => false, - } -} - -fn is_free_or_static(r: Region<'_>) -> bool { - match *r { - ty::ReStatic => true, - _ => is_free(r), + fn sub_free_regions(&self, tcx: TyCtxt<'tcx>, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { + // invoke the "inherent method" + self.sub_free_regions(tcx, r_a, r_b) } } diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index f0dc94f417c1e..4caab458025b1 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -5,7 +5,7 @@ use rustc::mir::ConstraintCategory; use rustc::traits::query::outlives_bounds::{self, OutlivesBound}; use rustc::traits::query::type_op::{self, TypeOp}; use rustc::ty::free_region_map::FreeRegionRelations; -use rustc::ty::{self, RegionVid, Ty}; +use rustc::ty::{self, RegionVid, Ty, TyCtxt}; use rustc_data_structures::transitive_relation::TransitiveRelation; use rustc_span::DUMMY_SP; use std::rc::Rc; @@ -359,7 +359,12 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { /// over the `FreeRegionMap` from lexical regions and /// `UniversalRegions` (from NLL)`. impl<'tcx> FreeRegionRelations<'tcx> for UniversalRegionRelations<'tcx> { - fn sub_free_regions(&self, shorter: ty::Region<'tcx>, longer: ty::Region<'tcx>) -> bool { + fn sub_free_regions( + &self, + _tcx: TyCtxt<'tcx>, + shorter: ty::Region<'tcx>, + longer: ty::Region<'tcx>, + ) -> bool { let shorter = shorter.to_region_vid(); assert!(self.universal_regions.is_universal_region(shorter)); let longer = longer.to_region_vid(); From 534f044425d019518b9f7936cbe5955f18157e0a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Oct 2019 19:26:57 -0400 Subject: [PATCH 0973/1253] index ReEmpty by universe We now make `'empty` indexed by a universe index, resulting in a region lattice like this: ``` static ----------+-----...------+ (greatest) | | | early-bound and | | free regions | | | | | scope regions | | | | | empty(root) placeholder(U1) | | / | | / placeholder(Un) empty(U1) -- / | / ... / | / empty(Un) -------- (smallest) ``` Therefore, `exists { forall { B: A } }` is now unprovable, because A must be at least Empty(U1) and B is placeholder(U2), and hence the two regions are unrelated. --- src/librustc/ich/impls_ty.rs | 5 +- src/librustc/infer/canonical/canonicalizer.rs | 17 +++- src/librustc/infer/combine.rs | 2 +- src/librustc/infer/error_reporting/mod.rs | 35 ++++++- .../nice_region_error/placeholder_error.rs | 19 ++++ src/librustc/infer/freshen.rs | 2 +- .../infer/lexical_region_resolve/mod.rs | 98 ++++++++++++++++--- src/librustc/infer/opaque_types/mod.rs | 4 +- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/ty/context.rs | 9 +- src/librustc/ty/print/pretty.rs | 8 +- src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 85 +++++++++++++--- src/librustc_index/vec.rs | 8 ++ .../borrow_check/diagnostics/region_name.rs | 2 +- .../type_check/constraint_conversion.rs | 6 +- .../type_check/free_region_relations.rs | 2 +- .../chalk_context/resolvent_ops.rs | 8 +- src/librustc_typeck/collect.rs | 3 +- src/librustc_typeck/outlives/utils.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +- 22 files changed, 269 insertions(+), 58 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 6af0cee948d86..844250f51a099 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -63,9 +63,12 @@ impl<'a> HashStable> for ty::RegionKind { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - ty::ReErased | ty::ReStatic | ty::ReEmpty => { + ty::ReErased | ty::ReStatic => { // No variant fields to hash for these ... } + ty::ReEmpty(universe) => { + universe.hash_stable(hcx, hasher); + } ty::ReLateBound(db, ty::BrAnon(i)) => { db.hash_stable(hcx, hasher); i.hash_stable(hcx, hasher); diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index b720168f3563e..48a6c6d7413d1 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -167,11 +167,17 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match r { - ty::ReFree(_) | ty::ReEmpty | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r, + ty::ReFree(_) + | ty::ReErased + | ty::ReStatic + | ty::ReEmpty(ty::UniverseIndex::ROOT) + | ty::ReEarlyBound(..) => r, + ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region( CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(*placeholder) }, r, ), + ty::ReVar(vid) => { let universe = canonicalizer.region_var_universe(*vid); canonicalizer.canonical_var_for_region( @@ -179,6 +185,11 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { r, ) } + + ty::ReEmpty(ui) => { + bug!("canonicalizing 'empty in universe {:?}", ui) // FIXME + } + _ => { // Other than `'static` or `'empty`, the query // response should be executing in a fully @@ -213,7 +224,7 @@ impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match r { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReEmpty | ty::ReStatic => r, + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic => r, ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r), _ => { // We only expect region names that the user can type. @@ -320,8 +331,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | ty::ReEarlyBound(..) | ty::ReFree(_) | ty::ReScope(_) + | ty::ReEmpty(_) | ty::RePlaceholder(..) - | ty::ReEmpty | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), ty::ReClosureBound(..) => { diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 5d765a2a3d3e7..2518805a1ecfc 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -577,7 +577,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { ty::RePlaceholder(..) | ty::ReVar(..) - | ty::ReEmpty + | ty::ReEmpty(_) | ty::ReStatic | ty::ReScope(..) | ty::ReEarlyBound(..) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 58566bdcc3549..57a52a991edc8 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -138,7 +138,10 @@ pub(super) fn note_and_explain_region( msg_span_from_free_region(tcx, region) } - ty::ReEmpty => ("the empty lifetime".to_owned(), None), + ty::ReEmpty(ty::UniverseIndex::ROOT) => ("the empty lifetime".to_owned(), None), + + // uh oh, hope no user ever sees THIS + ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None), ty::RePlaceholder(_) => (format!("any other region"), None), @@ -181,7 +184,8 @@ fn msg_span_from_free_region( msg_span_from_early_bound_and_free_regions(tcx, region) } ty::ReStatic => ("the static lifetime".to_owned(), None), - ty::ReEmpty => ("an empty lifetime".to_owned(), None), + ty::ReEmpty(ty::UniverseIndex::ROOT) => ("an empty lifetime".to_owned(), None), + ty::ReEmpty(ui) => (format!("an empty lifetime in universe {:?}", ui), None), _ => bug!("{:?}", region), } } @@ -375,6 +379,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + RegionResolutionError::UpperBoundUniverseConflict( + _, + _, + var_universe, + sup_origin, + sup_r, + ) => { + assert!(sup_r.is_placeholder()); + + // Make a dummy value for the "sub region" -- + // this is the initial value of the + // placeholder. In practice, we expect more + // tailored errors that don't really use this + // value. + let sub_r = self.tcx.mk_region(ty::ReEmpty(var_universe)); + + self.report_placeholder_failure( + region_scope_tree, + sup_origin, + sub_r, + sup_r, + ) + .emit(); + } + RegionResolutionError::MemberConstraintFailure { opaque_type_def_id, hidden_ty, @@ -429,6 +458,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::GenericBoundFailure(..) => true, RegionResolutionError::ConcreteFailure(..) | RegionResolutionError::SubSupConflict(..) + | RegionResolutionError::UpperBoundUniverseConflict(..) | RegionResolutionError::MemberConstraintFailure { .. } => false, }; @@ -443,6 +473,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(), + RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), RegionResolutionError::MemberConstraintFailure { span, .. } => span, }); errors diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 7b31fe7cd7e4d..0b0bd61ce771e 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -107,6 +107,25 @@ impl NiceRegionError<'me, 'tcx> { found.substs, )), + Some(RegionResolutionError::UpperBoundUniverseConflict( + vid, + _, + _, + SubregionOrigin::Subtype(box TypeTrace { + cause, + values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), + }), + sup_placeholder @ ty::RePlaceholder(_), + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + None, + Some(*sup_placeholder), + expected.def_id, + expected.substs, + found.substs, + )), + Some(RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(box TypeTrace { cause, diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 16087959972b7..cf61cac0ac4bb 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -130,7 +130,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::ReScope(_) | ty::ReVar(_) | ty::RePlaceholder(..) - | ty::ReEmpty + | ty::ReEmpty(_) | ty::ReErased => { // replace all free regions with 'erased self.tcx().lifetimes.re_erased diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index cd4d2257de896..f4d583d9092ea 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -82,6 +82,16 @@ pub enum RegionResolutionError<'tcx> { Region<'tcx>, ), + /// Indicates a `'b: 'a` constraint where `'a` is in a universe that + /// cannot name the placeholder `'b` + UpperBoundUniverseConflict( + RegionVid, + RegionVariableOrigin, + ty::UniverseIndex, // the universe index of the region variable + SubregionOrigin<'tcx>, // cause of the constraint + Region<'tcx>, // the placeholder `'b` + ), + /// Indicates a failure of a `MemberConstraint`. These arise during /// impl trait processing explicitly -- basically, the impl trait's hidden type /// included some region that it was not supposed to. @@ -149,7 +159,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> { LexicalRegionResolutions { error_region: tcx.lifetimes.re_static, - values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars()), + values: IndexVec::from_fn_n( + |vid| { + let vid_universe = self.var_infos[vid].universe; + let re_empty = tcx.mk_region(ty::ReEmpty(vid_universe)); + VarValue::Value(re_empty) + }, + self.num_vars(), + ), } } @@ -381,8 +398,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // This is a specialized version of the `lub_concrete_regions` // check below for a common case, here purely as an // optimization. - if let ReEmpty = a_region { - return false; + let b_universe = self.var_infos[b_vid].universe; + if let ReEmpty(a_universe) = a_region { + if *a_universe == b_universe { + return false; + } } let mut lub = self.lub_concrete_regions(a_region, cur_region); @@ -399,7 +419,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // tighter bound than `'static`. // // (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.) - let b_universe = self.var_infos[b_vid].universe; if let ty::RePlaceholder(p) = lub { if b_universe.cannot_name(p.universe) { lub = self.tcx().lifetimes.re_static; @@ -445,7 +464,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.lub_concrete_regions(a, b) == b } - /// Returns the smallest region `c` such that `a <= c` and `b <= c`. + /// Returns the least-upper-bound of `a` and `b`; i.e., the + /// smallest region `c` such that `a <= c` and `b <= c`. + /// + /// Neither `a` nor `b` may be an inference variable (hence the + /// term "concrete regions"). fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let r = match (a, b) { (&ty::ReClosureBound(..), _) @@ -457,14 +480,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { bug!("cannot relate region: LUB({:?}, {:?})", a, b); } - (r @ &ReStatic, _) | (_, r @ &ReStatic) => { - r // nothing lives longer than static - } - - (&ReEmpty, r) | (r, &ReEmpty) => { - r // everything lives longer than empty - } - (&ReVar(v_id), _) | (_, &ReVar(v_id)) => { span_bug!( self.var_infos[v_id].origin.span(), @@ -475,6 +490,41 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } + (&ReStatic, _) | (_, &ReStatic) => { + // nothing lives longer than static + self.tcx().lifetimes.re_static + } + + (&ReEmpty(_), r @ ReEarlyBound(_)) + | (r @ ReEarlyBound(_), &ReEmpty(_)) + | (&ReEmpty(_), r @ ReFree(_)) + | (r @ ReFree(_), &ReEmpty(_)) + | (&ReEmpty(_), r @ ReScope(_)) + | (r @ ReScope(_), &ReEmpty(_)) => { + // all empty regions are less than early-bound, free, + // and scope regions + r + } + + (&ReEmpty(a_ui), &ReEmpty(b_ui)) => { + // empty regions are ordered according to the universe + // they are associated with + let ui = a_ui.min(b_ui); + self.tcx().mk_region(ReEmpty(ui)) + } + + (&ReEmpty(empty_ui), &RePlaceholder(placeholder)) + | (&RePlaceholder(placeholder), &ReEmpty(empty_ui)) => { + // If this empty region is from a universe that can + // name the placeholder, then the placeholder is + // larger; otherwise, the only ancestor is `'static`. + if empty_ui.can_name(placeholder.universe) { + self.tcx().mk_region(RePlaceholder(placeholder)) + } else { + self.tcx().lifetimes.re_static + } + } + (&ReEarlyBound(_), &ReScope(s_id)) | (&ReScope(s_id), &ReEarlyBound(_)) | (&ReFree(_), &ReScope(s_id)) @@ -800,6 +850,26 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + // If we have a scenario like `exists<'a> { forall<'b> { 'b: + // 'a } }`, we wind up without any lower-bound -- all we have + // are placeholders as upper bounds, but the universe of the + // variable `'a` doesn't permit those placeholders. + for upper_bound in &upper_bounds { + if let ty::RePlaceholder(p) = upper_bound.region { + if node_universe.cannot_name(p.universe) { + let origin = self.var_infos[node_idx].origin.clone(); + errors.push(RegionResolutionError::UpperBoundUniverseConflict( + node_idx, + origin, + node_universe, + upper_bound.origin.clone(), + upper_bound.region, + )); + return; + } + } + } + // Errors in earlier passes can yield error variables without // resolution errors here; delay ICE in favor of those errors. self.tcx().sess.delay_span_bug( @@ -914,7 +984,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } VerifyBound::IsEmpty => { - if let ty::ReEmpty = min { + if let ty::ReEmpty(_) = min { true } else { false diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index c86f9f66ec83a..fab753bb0f4c1 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -611,7 +611,7 @@ pub fn unexpected_hidden_region_diagnostic( ); // Explain the region we are capturing. - if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty = hidden_region { + if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) = hidden_region { // Assuming regionck succeeded (*), we ought to always be // capturing *some* region from the fn header, and hence it // ought to be free. So under normal circumstances, we will go @@ -843,7 +843,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { .emit(); } } - self.tcx.lifetimes.re_empty + self.tcx.lifetimes.re_root_empty } None => { self.tcx diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 667a4c3a7e2ab..2c580e2e3490a 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -795,10 +795,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { match *region { ty::ReScope(..) | ty::ReStatic - | ty::ReEmpty | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT, + ty::ReEmpty(ui) => ui, ty::RePlaceholder(placeholder) => placeholder.universe, ty::ReClosureBound(vid) | ty::ReVar(vid) => self.var_universe(vid), ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index f12032943f91f..d56d4fa14855d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -173,8 +173,13 @@ pub struct CommonTypes<'tcx> { } pub struct CommonLifetimes<'tcx> { - pub re_empty: Region<'tcx>, + /// ReEmpty in the root universe + pub re_root_empty: Region<'tcx>, + + /// ReStatic pub re_static: Region<'tcx>, + + /// Erased region, used after type-checking pub re_erased: Region<'tcx>, } @@ -876,7 +881,7 @@ impl<'tcx> CommonLifetimes<'tcx> { let mk = |r| interners.region.intern(r, |r| Interned(interners.arena.alloc(r))).0; CommonLifetimes { - re_empty: mk(RegionKind::ReEmpty), + re_root_empty: mk(RegionKind::ReEmpty(ty::UniverseIndex::ROOT)), re_static: mk(RegionKind::ReStatic), re_erased: mk(RegionKind::ReErased), } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index f5c14e73db2bc..0da680d1f915e 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1382,7 +1382,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false, - ty::ReStatic | ty::ReEmpty | ty::ReClosureBound(_) => true, + ty::ReStatic | ty::ReEmpty(_) | ty::ReClosureBound(_) => true, } } } @@ -1464,10 +1464,14 @@ impl FmtPrinter<'_, '_, F> { p!(write("'static")); return Ok(self); } - ty::ReEmpty => { + ty::ReEmpty(ty::UniverseIndex::ROOT) => { p!(write("'")); return Ok(self); } + ty::ReEmpty(ui) => { + p!(write("'", ui)); + return Ok(self); + } // The user should never encounter these in unsubstituted form. ty::ReClosureBound(vid) => { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c1ae4d9fe1724..a56684ee8e974 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -108,7 +108,7 @@ impl fmt::Debug for ty::RegionKind { ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder), - ty::ReEmpty => write!(f, "ReEmpty"), + ty::ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui), ty::ReErased => write!(f, "ReErased"), } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index dffe86d946212..c0ee14192ff7d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1269,11 +1269,67 @@ rustc_index::newtype_index! { pub type Region<'tcx> = &'tcx RegionKind; -/// Representation of regions. +/// Representation of (lexical) regions. Note that the NLL checker +/// uses a distinct representation of regions. For this reason, it +/// internally replaces all the regions with inference variables -- +/// the index of the variable is then used to index into internal NLL +/// data structures. See `rustc_mir::borrow_check` module for more +/// information. /// -/// Unlike types, most region variants are "fictitious", not concrete, -/// regions. Among these, `ReStatic`, `ReEmpty` and `ReScope` are the only -/// ones representing concrete regions. +/// ## The Region lattice within a given function +/// +/// In general, the (lexical, and hence deprecated) region lattice +/// looks like +/// +/// ``` +/// static ----------+-----...------+ (greatest) +/// | | | +/// early-bound and | | +/// free regions | | +/// | | | +/// scope regions | | +/// | | | +/// empty(root) placeholder(U1) | +/// | / | +/// | / placeholder(Un) +/// empty(U1) -- / +/// | / +/// ... / +/// | / +/// empty(Un) -------- (smallest) +/// ``` +/// +/// Early-bound/free regions are the named lifetimes in scope from the +/// function declaration. They have relationships to one another +/// determined based on the declared relationships from the +/// function. They all collectively outlive the scope regions. (See +/// `RegionRelations` type, and particularly +/// `crate::infer::outlives::free_region_map::FreeRegionMap`.) +/// +/// The scope regions are related to one another based on the AST +/// structure. (See `RegionRelations` type, and particularly the +/// `rustc::middle::region::ScopeTree`.) +/// +/// Note that inference variables and bound regions are not included +/// in this diagram. In the case of inference variables, they should +/// be inferred to some other region from the diagram. In the case of +/// bound regions, they are excluded because they don't make sense to +/// include -- the diagram indicates the relationship between free +/// regions. +/// +/// ## Inference variables +/// +/// During region inference, we sometimes create inference variables, +/// represented as `ReVar`. These will be inferred by the code in +/// `infer::lexical_region_resolve` to some free region from the +/// lattice above (the minimal region that meets the +/// constraints). +/// +/// During NLL checking, where regions are defined differently, we +/// also use `ReVar` -- in that case, the index is used to index into +/// the NLL region checker's data structures. The variable may in fact +/// represent either a free region or an inference variable, in that +/// case. /// /// ## Bound Regions /// @@ -1356,14 +1412,13 @@ pub enum RegionKind { /// Should not exist after typeck. RePlaceholder(ty::PlaceholderRegion), - /// Empty lifetime is for data that is never accessed. - /// Bottom in the region lattice. We treat ReEmpty somewhat - /// specially; at least right now, we do not generate instances of - /// it during the GLB computations, but rather - /// generate an error instead. This is to improve error messages. - /// The only way to get an instance of ReEmpty is to have a region - /// variable with no constraints. - ReEmpty, + /// Empty lifetime is for data that is never accessed. We tag the + /// empty lifetime with a universe -- the idea is that we don't + /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable. + /// Therefore, the `'empty` in a universe U is less than all + /// regions visible from U, but not less than regions not visible + /// from U. + ReEmpty(ty::UniverseIndex), /// Erased region, used by trait selection, in MIR and during codegen. ReErased, @@ -1612,7 +1667,7 @@ impl RegionKind { RegionKind::ReStatic => true, RegionKind::ReVar(..) => false, RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(), - RegionKind::ReEmpty => false, + RegionKind::ReEmpty(_) => false, RegionKind::ReErased => false, RegionKind::ReClosureBound(..) => false, } @@ -1695,7 +1750,7 @@ impl RegionKind { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; } - ty::ReEmpty | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => { + ty::ReEmpty(_) | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } ty::ReErased => {} @@ -1705,7 +1760,7 @@ impl RegionKind { } match *self { - ty::ReStatic | ty::ReEmpty | ty::ReErased | ty::ReLateBound(..) => (), + ty::ReStatic | ty::ReEmpty(_) | ty::ReErased | ty::ReLateBound(..) => (), _ => flags = flags | TypeFlags::HAS_FREE_LOCAL_NAMES, } diff --git a/src/librustc_index/vec.rs b/src/librustc_index/vec.rs index d14bafb44fd5b..1dfe97238a3df 100644 --- a/src/librustc_index/vec.rs +++ b/src/librustc_index/vec.rs @@ -574,6 +574,14 @@ impl IndexVec { IndexVec { raw: vec![elem; n], _marker: PhantomData } } + /// Create an `IndexVec` with `n` elements, where the value of each + /// element is the result of `func(i)` + #[inline] + pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self { + let indices = (0..n).map(I::new); + Self::from_raw(indices.map(func).collect()) + } + #[inline] pub fn push(&mut self, d: T) -> I { let idx = I::new(self.len()); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 47eb2d8940af4..09d61d9ad9ad1 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) - | ty::ReEmpty + | ty::ReEmpty(_) | ty::ReErased | ty::ReClosureBound(..) => None, } diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs index 8f65a0f01c6e0..a3e38cd7a5f85 100644 --- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs @@ -160,7 +160,8 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<' a: ty::Region<'tcx>, b: ty::Region<'tcx>, ) { - if let ty::ReEmpty = a { + // FIXME -- this is not the fix I would prefer + if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a { return; } let b = self.to_region_vid(b); @@ -175,7 +176,8 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<' a: ty::Region<'tcx>, bound: VerifyBound<'tcx>, ) { - if let ty::ReEmpty = a { + // FIXME: I'd prefer if NLL had a notion of empty + if let ty::ReEmpty(ty::UniverseIndex::ROOT) = a { return; } let type_test = self.verify_to_type_test(kind, a, bound); diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index 4caab458025b1..cf8c3449d666b 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -333,7 +333,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { // `where Type:` is lowered to `where Type: 'empty` so that // we check `Type` is well formed, but there's no use for // this bound here. - if let ty::ReEmpty = r1 { + if let ty::ReEmpty(_) = r1 { return; } diff --git a/src/librustc_traits/chalk_context/resolvent_ops.rs b/src/librustc_traits/chalk_context/resolvent_ops.rs index 70e3c4c7ab18b..301ebf8adc5c7 100644 --- a/src/librustc_traits/chalk_context/resolvent_ops.rs +++ b/src/librustc_traits/chalk_context/resolvent_ops.rs @@ -246,9 +246,11 @@ impl TypeRelation<'tcx> for AnswerSubstitutor<'cx, 'tcx> { assert_eq!(a_bound.assert_bound_var(), b_bound.assert_bound_var()); } - (ty::ReStatic, ty::ReStatic) - | (ty::ReErased, ty::ReErased) - | (ty::ReEmpty, ty::ReEmpty) => (), + (ty::ReStatic, ty::ReStatic) | (ty::ReErased, ty::ReErased) => (), + + (ty::ReEmpty(a_ui), ty::ReEmpty(b_ui)) => { + assert_eq!(a_ui, b_ui); + } (&ty::ReFree(a_free), &ty::ReFree(b_free)) => { assert_eq!(a_free, b_free); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4d812d2621c61..713f41311a696 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2322,7 +2322,8 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // compiler/tooling bugs from not handling WF predicates. } else { let span = bound_pred.bounded_ty.span; - let predicate = ty::OutlivesPredicate(ty, tcx.mk_region(ty::ReEmpty)); + let re_root_empty = tcx.lifetimes.re_root_empty; + let predicate = ty::OutlivesPredicate(ty, re_root_empty); predicates.push(( ty::Predicate::TypeOutlives(ty::Binder::dummy(predicate)), span, diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index 2d7fc9d62e5fb..0cc322f8c2d3d 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -166,7 +166,7 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { // // struct Bar(::Type) where Self: ; // struct Baz<'a>(&'a Self) where Self: ; - RegionKind::ReEmpty => false, + RegionKind::ReEmpty(_) => false, // These regions don't appear in types from type declarations: RegionKind::ReErased diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 5ca961ed34424..6f5caea250b07 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -453,7 +453,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) - | ty::ReEmpty + | ty::ReEmpty(_) | ty::ReErased => { // We don't expect to see anything but 'static or bound // regions when visiting member types or method types. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2a35ab812a5f2..f140f11b09098 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -447,7 +447,7 @@ impl Clean> for ty::RegionKind { | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) - | ty::ReEmpty + | ty::ReEmpty(_) | ty::ReClosureBound(_) | ty::ReErased => { debug!("cannot clean region {:?}", self); @@ -521,7 +521,7 @@ impl<'tcx> Clean> let ty::OutlivesPredicate(ref a, ref b) = *self; match (a, b) { - (ty::ReEmpty, ty::ReEmpty) => { + (ty::ReEmpty(_), ty::ReEmpty(_)) => { return None; } _ => {} @@ -539,7 +539,7 @@ impl<'tcx> Clean> for ty::OutlivesPredicate, ty: let ty::OutlivesPredicate(ref ty, ref lt) = *self; match lt { - ty::ReEmpty => return None, + ty::ReEmpty(_) => return None, _ => {} } From 6bc79c9cf36538a724994db228f94aafb4d4fb53 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 11 Nov 2019 13:14:57 -0500 Subject: [PATCH 0974/1253] use derive(Debug) for TypeTrace --- src/librustc/infer/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4681a47317cf2..f6edccc8ed76d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -246,7 +246,7 @@ pub enum ValuePairs<'tcx> { /// encounter an error or subtyping constraint. /// /// See the `error_reporting` module for more details. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct TypeTrace<'tcx> { cause: ObligationCause<'tcx>, values: ValuePairs<'tcx>, @@ -1647,12 +1647,6 @@ impl<'tcx> TypeTrace<'tcx> { } } -impl<'tcx> fmt::Debug for TypeTrace<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "TypeTrace({:?})", self.cause) - } -} - impl<'tcx> SubregionOrigin<'tcx> { pub fn span(&self) -> Span { match *self { From 5e0197f13a28d2b3d9aadbc6c5d48506ab4d696f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 18 Jan 2020 05:47:28 -0500 Subject: [PATCH 0975/1253] apply various formatting nits --- src/librustc/infer/lexical_region_resolve/mod.rs | 16 ++++++++-------- src/librustc/infer/outlives/verify.rs | 2 +- src/librustc/ty/context.rs | 4 ++-- src/librustc/ty/free_region_map.rs | 2 +- src/librustc/ty/sty.rs | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f4d583d9092ea..e0a8c3b4e654a 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -83,7 +83,7 @@ pub enum RegionResolutionError<'tcx> { ), /// Indicates a `'b: 'a` constraint where `'a` is in a universe that - /// cannot name the placeholder `'b` + /// cannot name the placeholder `'b`. UpperBoundUniverseConflict( RegionVid, RegionVariableOrigin, @@ -449,7 +449,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { return true; } - // If both a and b are free, consult the declared + // If both `a` and `b` are free, consult the declared // relationships. Note that this can be more precise than the // `lub` relationship defined below, since sometimes the "lub" // is actually the `postdom_upper_bound` (see @@ -460,7 +460,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } // For other cases, leverage the LUB code to find the LUB and - // check if it is equal to b. + // check if it is equal to `b`. self.lub_concrete_regions(a, b) == b } @@ -491,7 +491,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } (&ReStatic, _) | (_, &ReStatic) => { - // nothing lives longer than static + // nothing lives longer than `'static` self.tcx().lifetimes.re_static } @@ -501,14 +501,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { | (r @ ReFree(_), &ReEmpty(_)) | (&ReEmpty(_), r @ ReScope(_)) | (r @ ReScope(_), &ReEmpty(_)) => { - // all empty regions are less than early-bound, free, - // and scope regions + // All empty regions are less than early-bound, free, + // and scope regions. r } (&ReEmpty(a_ui), &ReEmpty(b_ui)) => { - // empty regions are ordered according to the universe - // they are associated with + // Empty regions are ordered according to the universe + // they are associated with. let ui = a_ui.min(b_ui); self.tcx().mk_region(ReEmpty(ui)) } diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 9d6c3f30aa776..a2c99064caa4e 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -68,7 +68,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // being tested is `'empty`. VerifyBound::IsEmpty } else { - // If we can find any other bound R such that `T: R`, then + // If we can find any other bound `R` such that `T: R`, then // we don't need to check for `'empty`, because `R: 'empty`. VerifyBound::AnyBound(any_bounds) } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d56d4fa14855d..f104cb084e65e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -173,10 +173,10 @@ pub struct CommonTypes<'tcx> { } pub struct CommonLifetimes<'tcx> { - /// ReEmpty in the root universe + /// `ReEmpty` in the root universe. pub re_root_empty: Region<'tcx>, - /// ReStatic + /// `ReStatic` pub re_static: Region<'tcx>, /// Erased region, used after type-checking diff --git a/src/librustc/ty/free_region_map.rs b/src/librustc/ty/free_region_map.rs index 4cd6b4cfadb0c..2ab12a4acbfa4 100644 --- a/src/librustc/ty/free_region_map.rs +++ b/src/librustc/ty/free_region_map.rs @@ -56,7 +56,7 @@ impl<'tcx> FreeRegionMap<'tcx> { } } - /// Check whether `r_a <= r_b` is found in the relation + /// Check whether `r_a <= r_b` is found in the relation. fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { r_a == r_b || self.relation.contains(&r_a, &r_b) } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index c0ee14192ff7d..9414c78c781d6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1415,9 +1415,9 @@ pub enum RegionKind { /// Empty lifetime is for data that is never accessed. We tag the /// empty lifetime with a universe -- the idea is that we don't /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable. - /// Therefore, the `'empty` in a universe U is less than all - /// regions visible from U, but not less than regions not visible - /// from U. + /// Therefore, the `'empty` in a universe `U` is less than all + /// regions visible from `U`, but not less than regions not visible + /// from `U`. ReEmpty(ty::UniverseIndex), /// Erased region, used by trait selection, in MIR and during codegen. From e9c78947dcd947709f41d52feaaf2eb6ea2711c8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 18 Jan 2020 07:59:16 -0500 Subject: [PATCH 0976/1253] add the ability to skip leak check within a snapshot The intention is that coherence code will skip the leak check and determine whether two impls *would have* overlapped, and then issue a warning. --- src/librustc/infer/higher_ranked/mod.rs | 10 +++++++ src/librustc/infer/mod.rs | 27 +++++++++++++++++++ .../infer/region_constraints/leak_check.rs | 12 --------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index bbca4823431e8..d25d186f4d74e 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -128,6 +128,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { placeholder_map: &PlaceholderMap<'tcx>, snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> RelateResult<'tcx, ()> { + // If the user gave `-Zno-leak-check`, or we have been + // configured to skip the leak check, then skip the leak check + // completely. The leak check is deprecated. Any legitimate + // subtyping errors that it would have caught will now be + // caught later on, during region checking. However, we + // continue to use it for a transition period. + if self.tcx.sess.opts.debugging_opts.no_leak_check || self.skip_leak_check.get() { + return Ok(()); + } + self.borrow_region_constraints().leak_check( self.tcx, overly_polymorphic, diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index f6edccc8ed76d..35863a3a89a73 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -125,6 +125,13 @@ pub struct InferCtxt<'a, 'tcx> { /// order, represented by its upper and lower bounds. pub type_variables: RefCell>, + /// If set, this flag causes us to skip the 'leak check' during + /// higher-ranked subtyping operations. This flag is a temporary one used + /// to manage the removal of the leak-check: for the time being, we still run the + /// leak-check, but we issue warnings. This flag can only be set to true + /// when entering a snapshot. + skip_leak_check: Cell, + /// Map from const parameter variable to the kind of const it represents. const_unification_table: RefCell>>>, @@ -550,6 +557,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { tainted_by_errors_flag: Cell::new(false), err_count_on_creation: tcx.sess.err_count(), in_snapshot: Cell::new(false), + skip_leak_check: Cell::new(false), region_obligations: RefCell::new(vec![]), universe: Cell::new(ty::UniverseIndex::ROOT), }) @@ -593,6 +601,7 @@ pub struct CombinedSnapshot<'a, 'tcx> { region_obligations_snapshot: usize, universe: ty::UniverseIndex, was_in_snapshot: bool, + was_skip_leak_check: bool, _in_progress_tables: Option>>, } @@ -720,6 +729,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot: self.region_obligations.borrow().len(), universe: self.universe(), was_in_snapshot: in_snapshot, + was_skip_leak_check: self.skip_leak_check.get(), // Borrow tables "in progress" (i.e., during typeck) // to ban writes from within a snapshot to them. _in_progress_tables: self.in_progress_tables.map(|tables| tables.borrow()), @@ -738,11 +748,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot, universe, was_in_snapshot, + was_skip_leak_check, _in_progress_tables, } = snapshot; self.in_snapshot.set(was_in_snapshot); self.universe.set(universe); + self.skip_leak_check.set(was_skip_leak_check); self.projection_cache.borrow_mut().rollback_to(projection_cache_snapshot); self.type_variables.borrow_mut().rollback_to(type_snapshot); @@ -765,10 +777,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot: _, universe: _, was_in_snapshot, + was_skip_leak_check, _in_progress_tables, } = snapshot; self.in_snapshot.set(was_in_snapshot); + self.skip_leak_check.set(was_skip_leak_check); self.projection_cache.borrow_mut().commit(projection_cache_snapshot); self.type_variables.borrow_mut().commit(type_snapshot); @@ -822,6 +836,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { r } + /// Execute `f` then unroll any bindings it creates. + pub fn skip_leak_check(&self, f: F) -> R + where + F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, + { + debug!("probe()"); + let snapshot = self.start_snapshot(); + self.skip_leak_check.set(true); + let r = f(&snapshot); + self.rollback_to("probe", snapshot); + r + } + /// Scan the constraints produced since `snapshot` began and returns: /// /// - `None` -- if none of them involve "region outlives" constraints diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs index 3b3a464ba557a..29290cef2d288 100644 --- a/src/librustc/infer/region_constraints/leak_check.rs +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -33,18 +33,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); - // If the user gave `-Zno-leak-check`, then skip the leak - // check completely. This is wildly unsound and also not - // unlikely to cause an ICE or two. It is intended for use - // only during a transition period, in which the MIR typeck - // uses the "universe-style" check, and the rest of typeck - // uses the more conservative leak check. Since the leak - // check is more conservative, we can't test the - // universe-style check without disabling it. - if tcx.sess.opts.debugging_opts.no_leak_check { - return Ok(()); - } - // Go through each placeholder that we created. for (_, &placeholder_region) in placeholder_map { // Find the universe this placeholder inhabits. From 363fabaf1fbd0f38a7ddde4a64866d8cd2cd49f2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 24 Jan 2020 15:57:01 -0500 Subject: [PATCH 0977/1253] lint impls that will become incoherent when leak-check is removed --- src/librustc/infer/mod.rs | 7 +++--- src/librustc/traits/coherence.rs | 15 ++++++++---- src/librustc/traits/mod.rs | 22 +++++++++++++++++ src/librustc/traits/specialize/mod.rs | 6 +++-- .../traits/specialize/specialization_graph.rs | 24 +++++++++++++++++-- src/librustc_session/lint/builtin.rs | 11 +++++++++ .../coherence/inherent_impls_overlap.rs | 5 +++- .../coherence-inherited-subtyping.old.stderr | 14 +++++++++++ .../coherence-inherited-subtyping.re.stderr | 14 +++++++++++ .../coherence-inherited-subtyping.rs | 21 ++++++++++++++++ .../coherence/coherence-subtyping.old.stderr | 16 +++++++++++++ .../coherence/coherence-subtyping.re.stderr | 16 +++++++++++++ src/test/ui/coherence/coherence-subtyping.rs | 12 ++++++---- 13 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/coherence/coherence-inherited-subtyping.old.stderr create mode 100644 src/test/ui/coherence/coherence-inherited-subtyping.re.stderr create mode 100644 src/test/ui/coherence/coherence-inherited-subtyping.rs create mode 100644 src/test/ui/coherence/coherence-subtyping.old.stderr create mode 100644 src/test/ui/coherence/coherence-subtyping.re.stderr diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 35863a3a89a73..b93f4408cdc46 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -836,14 +836,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { r } - /// Execute `f` then unroll any bindings it creates. - pub fn skip_leak_check(&self, f: F) -> R + /// If `should_skip` is true, then execute `f` then unroll any bindings it creates. + pub fn probe_maybe_skip_leak_check(&self, should_skip: bool, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, { debug!("probe()"); let snapshot = self.start_snapshot(); - self.skip_leak_check.set(true); + let skip_leak_check = should_skip || self.skip_leak_check.get(); + self.skip_leak_check.set(skip_leak_check); let r = f(&snapshot); self.rollback_to("probe", snapshot); r diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 29ea47809a077..855da0367de06 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -7,6 +7,7 @@ use crate::infer::{CombinedSnapshot, InferOk}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::IntercrateMode; +use crate::traits::SkipLeakCheck; use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionContext}; use crate::ty::fold::TypeFoldable; use crate::ty::subst::Subst; @@ -53,6 +54,7 @@ pub fn overlapping_impls( impl1_def_id: DefId, impl2_def_id: DefId, intercrate_mode: IntercrateMode, + skip_leak_check: SkipLeakCheck, on_overlap: F1, no_overlap: F2, ) -> R @@ -70,7 +72,7 @@ where let overlaps = tcx.infer_ctxt().enter(|infcx| { let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode); - overlap(selcx, impl1_def_id, impl2_def_id).is_some() + overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id).is_some() }); if !overlaps { @@ -83,7 +85,7 @@ where tcx.infer_ctxt().enter(|infcx| { let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode); selcx.enable_tracking_intercrate_ambiguity_causes(); - on_overlap(overlap(selcx, impl1_def_id, impl2_def_id).unwrap()) + on_overlap(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id).unwrap()) }) } @@ -113,12 +115,15 @@ fn with_fresh_ty_vars<'cx, 'tcx>( /// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls. fn overlap<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, + skip_leak_check: SkipLeakCheck, a_def_id: DefId, b_def_id: DefId, ) -> Option> { debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id); - selcx.infcx().probe(|snapshot| overlap_within_probe(selcx, a_def_id, b_def_id, snapshot)) + selcx.infcx().probe_maybe_skip_leak_check(skip_leak_check.is_yes(), |snapshot| { + overlap_within_probe(selcx, a_def_id, b_def_id, snapshot) + }) } fn overlap_within_probe( @@ -146,7 +151,9 @@ fn overlap_within_probe( .eq_impl_headers(&a_impl_header, &b_impl_header) { Ok(InferOk { obligations, value: () }) => obligations, - Err(_) => return None, + Err(_) => { + return None; + } }; debug!("overlap: unification check succeeded"); diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index e88f4e65c7eb1..50068b89687ba 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -83,6 +83,28 @@ pub enum IntercrateMode { Fixed, } +/// Whether to skip the leak check, as part of a future compatibility warning step. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum SkipLeakCheck { + Yes, + No, +} + +impl SkipLeakCheck { + fn is_yes(self) -> bool { + self == SkipLeakCheck::Yes + } +} + +/// The "default" for skip-leak-check corresponds to the current +/// behavior (do not skip the leak check) -- not the behavior we are +/// transitioning into. +impl Default for SkipLeakCheck { + fn default() -> Self { + SkipLeakCheck::No + } +} + /// The mode that trait queries run in. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum TraitQueryMode { diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index e559ea391cde0..8b68d6f260399 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -19,6 +19,7 @@ use crate::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir::def_id::DefId; +use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::DUMMY_SP; @@ -97,7 +98,7 @@ pub fn translate_substs<'a, 'tcx>( |_| { bug!( "When translating substitutions for specialization, the expected \ - specialization failed to hold" + specialization failed to hold" ) }, ) @@ -268,7 +269,7 @@ fn fulfill_implication<'a, 'tcx>( // no dice! debug!( "fulfill_implication: for impls on {:?} and {:?}, \ - could not fulfill: {:?} given {:?}", + could not fulfill: {:?} given {:?}", source_trait_ref, target_trait_ref, errors, param_env.caller_bounds ); Err(()) @@ -342,6 +343,7 @@ pub(super) fn specialization_graph_provider( FutureCompatOverlapErrorKind::Issue33140 => { ORDER_DEPENDENT_TRAIT_OBJECTS } + FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; tcx.struct_span_lint_hir( lint, diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index c90fa428001fc..98908e672f0aa 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -11,6 +11,7 @@ pub use rustc::traits::types::specialization_graph::*; pub enum FutureCompatOverlapErrorKind { Issue43355, Issue33140, + LeakCheck, } #[derive(Debug)] @@ -111,6 +112,7 @@ impl<'tcx> Children { possible_sibling, impl_def_id, traits::IntercrateMode::Issue43355, + traits::SkipLeakCheck::default(), |overlap| { if let Some(overlap_kind) = tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) @@ -161,6 +163,7 @@ impl<'tcx> Children { possible_sibling, impl_def_id, traits::IntercrateMode::Fixed, + traits::SkipLeakCheck::default(), |overlap| { last_lint = Some(FutureCompatOverlapError { error: overlap_error(overlap), @@ -169,6 +172,23 @@ impl<'tcx> Children { }, || (), ); + + if last_lint.is_none() { + traits::overlapping_impls( + tcx, + possible_sibling, + impl_def_id, + traits::IntercrateMode::Fixed, + traits::SkipLeakCheck::Yes, + |overlap| { + last_lint = Some(FutureCompatOverlapError { + error: overlap_error(overlap), + kind: FutureCompatOverlapErrorKind::LeakCheck, + }); + }, + || (), + ); + } } // no overlap (error bailed already via ?) @@ -247,7 +267,7 @@ impl<'tcx> Graph { if trait_ref.references_error() { debug!( "insert: inserting dummy node for erroneous TraitRef {:?}, \ - impl_def_id={:?}, trait_def_id={:?}", + impl_def_id={:?}, trait_def_id={:?}", trait_ref, impl_def_id, trait_def_id ); @@ -326,7 +346,7 @@ impl<'tcx> Graph { if self.parent.insert(child, parent).is_some() { bug!( "When recording an impl from the crate store, information about its parent \ - was already present." + was already present." ); } diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index c326061100b06..cd972bdb993d2 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -260,6 +260,16 @@ declare_lint! { }; } +declare_lint! { + pub COHERENCE_LEAK_CHECK, + Deny, + "distinct impls distinguished only by the leak-check code", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #56105 ", + edition: None, + }; +} + declare_lint! { pub DEPRECATED, Warn, @@ -509,6 +519,7 @@ declare_lint_pass! { MISSING_FRAGMENT_SPECIFIER, LATE_BOUND_LIFETIME_ARGUMENTS, ORDER_DEPENDENT_TRAIT_OBJECTS, + COHERENCE_LEAK_CHECK, DEPRECATED, UNUSED_UNSAFE, UNUSED_MUT, diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index d60c3cfba9a5b..3e17b661cf4ce 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -1,5 +1,5 @@ use crate::namespace::Namespace; -use rustc::traits::{self, IntercrateMode}; +use rustc::traits::{self, IntercrateMode, SkipLeakCheck}; use rustc::ty::TyCtxt; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -76,6 +76,9 @@ impl InherentOverlapChecker<'tcx> { impl1_def_id, impl2_def_id, IntercrateMode::Issue43355, + // We go ahead and just skip the leak check for + // inherent impls without warning. + SkipLeakCheck::Yes, |overlap| { self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); false diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr b/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr new file mode 100644 index 0000000000000..6ea0b89be74d3 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `method1` + --> $DIR/coherence-inherited-subtyping.rs:14:5 + | +LL | fn method1(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `method1` +... +LL | fn method1(&self) {} + | -------------------- other definition for `method1` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr b/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr new file mode 100644 index 0000000000000..6ea0b89be74d3 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `method1` + --> $DIR/coherence-inherited-subtyping.rs:14:5 + | +LL | fn method1(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `method1` +... +LL | fn method1(&self) {} + | -------------------- other definition for `method1` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.rs b/src/test/ui/coherence/coherence-inherited-subtyping.rs new file mode 100644 index 0000000000000..8587eb77950c7 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.rs @@ -0,0 +1,21 @@ +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. + +// revisions: old re + +struct Foo { + t: T, +} + +impl Foo fn(&'a u8, &'b u8) -> &'a u8> { + fn method1(&self) {} //~ ERROR duplicate definitions with name `method1` +} + +impl Foo fn(&'a u8, &'a u8) -> &'a u8> { + fn method1(&self) {} +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.old.stderr new file mode 100644 index 0000000000000..6bae152bd2a8e --- /dev/null +++ b/src/test/ui/coherence/coherence-subtyping.old.stderr @@ -0,0 +1,16 @@ +error: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: + --> $DIR/coherence-subtyping.rs:15:1 + | +LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} + | ---------------------------------------------------------- first implementation here +LL | +LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + | + = note: `#[deny(coherence_leak_check)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr new file mode 100644 index 0000000000000..6bae152bd2a8e --- /dev/null +++ b/src/test/ui/coherence/coherence-subtyping.re.stderr @@ -0,0 +1,16 @@ +error: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: + --> $DIR/coherence-subtyping.rs:15:1 + | +LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} + | ---------------------------------------------------------- first implementation here +LL | +LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + | + = note: `#[deny(coherence_leak_check)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index a742bf2884e3c..9f45290c65b13 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -5,16 +5,18 @@ // universe transition (#56105) may eventually become an error. // revisions: old re -// build-pass (FIXME(62277): could be check-pass?) trait TheTrait { - fn foo(&self) { } + fn foo(&self) {} } -impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { -} +impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { + //[re]~^ ERROR conflicting implementation + //[re]~^^ WARNING this was previously accepted by the compiler but is being phased out + //[old]~^^^ ERROR conflicting implementation + //[old]~^^^^ WARNING this was previously accepted by the compiler but is being phased out } -fn main() { } +fn main() {} From 4a1c6ce23547346757fa8b61207aea7eb6997aa3 Mon Sep 17 00:00:00 2001 From: Josh White Date: Wed, 5 Feb 2020 06:28:31 -0500 Subject: [PATCH 0978/1253] Added long error description & modifed error_codes.rs --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0637.md | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/librustc_error_codes/error_codes/E0637.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index c3d9ed088981d..ba43b29538d50 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -353,6 +353,7 @@ E0631: include_str!("./error_codes/E0631.md"), E0633: include_str!("./error_codes/E0633.md"), E0635: include_str!("./error_codes/E0635.md"), E0636: include_str!("./error_codes/E0636.md"), +E0637: include_str!("./error_codes/E0637.md"), E0638: include_str!("./error_codes/E0638.md"), E0639: include_str!("./error_codes/E0639.md"), E0641: include_str!("./error_codes/E0641.md"), @@ -584,7 +585,6 @@ E0746: include_str!("./error_codes/E0746.md"), E0632, // cannot provide explicit generic arguments when `impl Trait` is // used in argument position E0634, // type has conflicting packed representaton hints - E0637, // "'_" is not a valid lifetime bound E0640, // infer outlives requirements // E0645, // trait aliases not finished E0657, // `impl Trait` can only capture lifetimes bound at the fn level diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md new file mode 100644 index 0000000000000..4f139b0ec49d6 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -0,0 +1,22 @@ +The underscore `_` character has been used as the identifier for a lifetime. + +Erroneous code example: +``` +fn some_function<'_>(x: &'_ str, y: &'_ str) -> &'_ str { + //Some code +} +``` + +Lifetimes are named with 'ident, where ident is the name of the +lifetime or loop. The `_` character, which represents the ignore pattern, +cannot be used because it is a reserved lifetime name. +To fix this, use a single lowercase letter as the +lifetime identifier, such as `'a`. For more information, see [The Rust Book](https://doc.rust-lang.org/stable/book/appendix-02-operators.html#non-operator-symbols). + +Corrected code example: +``` +fn some_function<'a>(x: &'a str, y: &'a str) -> &'a str { + //Some code +} +``` + From 201a262ac4a9cb61e4e94d8e841a973fee0edc86 Mon Sep 17 00:00:00 2001 From: Josh White Date: Thu, 6 Feb 2020 16:07:35 -0500 Subject: [PATCH 0979/1253] Revised error long description --- src/librustc_error_codes/error_codes/E0637.md | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md index 4f139b0ec49d6..f5da357534e26 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -1,22 +1,34 @@ -The underscore `_` character has been used as the identifier for a lifetime. + +An underscore `_` character or a numeric literal `u8`, `i32`, `f64`, etc has +been used as the identifier for a lifetime. Erroneous code example: ``` -fn some_function<'_>(x: &'_ str, y: &'_ str) -> &'_ str { +fn some_function<'_>(string1: &'_ str, string2: &'_ str) -> &'_ str { + //Some code +} +``` +or Erroneous code example 2: +``` +fn some_function<'u8>(string1: &'u8 str, string2: &'u8 str) -> &'u8 str { //Some code } ``` -Lifetimes are named with 'ident, where ident is the name of the -lifetime or loop. The `_` character, which represents the ignore pattern, -cannot be used because it is a reserved lifetime name. -To fix this, use a single lowercase letter as the -lifetime identifier, such as `'a`. For more information, see [The Rust Book](https://doc.rust-lang.org/stable/book/appendix-02-operators.html#non-operator-symbols). +Lifetimes are named with `'ident`, where ident is the name of the lifetime or +loop. The `_` character, which represents the ignore pattern, cannot be used +as the identifier because it is a reserved lifetime name. Numeric literals are +also invalid lifetime identifiers and will cause this error to be thrown. To fix +this, use a series of lowercase letters as the lifetime identifier. Often a +single lowercase letter, such as `'a`, is sufficient. For more information, see +[the book][bk-no]. Corrected code example: ``` -fn some_function<'a>(x: &'a str, y: &'a str) -> &'a str { +fn some_function<'a>(string1: &'a str, string2: &'a str) -> &'a str { //Some code } ``` +[bk-no]: https://doc.rust-lang.org/book/appendix-02-operators.html#non-operator-symbols + From 4b3c66d2c309a16d48c2b7f992a2038016a098d3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 6 Feb 2020 15:59:09 -0500 Subject: [PATCH 0980/1253] make lint warn by default --- src/librustc_session/lint/builtin.rs | 2 +- src/test/ui/coherence/coherence-subtyping.old.stderr | 8 +++----- src/test/ui/coherence/coherence-subtyping.re.stderr | 8 +++----- src/test/ui/coherence/coherence-subtyping.rs | 5 +++-- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index cd972bdb993d2..0038deda91b43 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -262,7 +262,7 @@ declare_lint! { declare_lint! { pub COHERENCE_LEAK_CHECK, - Deny, + Warn, "distinct impls distinguished only by the leak-check code", @future_incompatible = FutureIncompatibleInfo { reference: "issue #56105 ", diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.old.stderr index 6bae152bd2a8e..76f5cc1b78232 100644 --- a/src/test/ui/coherence/coherence-subtyping.old.stderr +++ b/src/test/ui/coherence/coherence-subtyping.old.stderr @@ -1,5 +1,5 @@ -error: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 +warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: + --> $DIR/coherence-subtyping.rs:16:1 | LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} | ---------------------------------------------------------- first implementation here @@ -7,10 +7,8 @@ LL | LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` | - = note: `#[deny(coherence_leak_check)]` on by default + = note: `#[warn(coherence_leak_check)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56105 = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error: aborting due to previous error - diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr index 6bae152bd2a8e..76f5cc1b78232 100644 --- a/src/test/ui/coherence/coherence-subtyping.re.stderr +++ b/src/test/ui/coherence/coherence-subtyping.re.stderr @@ -1,5 +1,5 @@ -error: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 +warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: + --> $DIR/coherence-subtyping.rs:16:1 | LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} | ---------------------------------------------------------- first implementation here @@ -7,10 +7,8 @@ LL | LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` | - = note: `#[deny(coherence_leak_check)]` on by default + = note: `#[warn(coherence_leak_check)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56105 = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error: aborting due to previous error - diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index 9f45290c65b13..f5c1d92411baa 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -5,6 +5,7 @@ // universe transition (#56105) may eventually become an error. // revisions: old re +// check-pass trait TheTrait { fn foo(&self) {} @@ -13,9 +14,9 @@ trait TheTrait { impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - //[re]~^ ERROR conflicting implementation + //[re]~^ WARNING conflicting implementation //[re]~^^ WARNING this was previously accepted by the compiler but is being phased out - //[old]~^^^ ERROR conflicting implementation + //[old]~^^^ WARNING conflicting implementation //[old]~^^^^ WARNING this was previously accepted by the compiler but is being phased out } From 1923586286dea1a0f8ece43056126fc2ecc89337 Mon Sep 17 00:00:00 2001 From: Josh White Date: Thu, 6 Feb 2020 16:54:24 -0500 Subject: [PATCH 0981/1253] Edited error description --- src/librustc_error_codes/error_codes/E0637.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md index f5da357534e26..44a365be7e0f7 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -2,15 +2,15 @@ An underscore `_` character or a numeric literal `u8`, `i32`, `f64`, etc has been used as the identifier for a lifetime. -Erroneous code example: +Erroneous code example 1: ``` -fn some_function<'_>(string1: &'_ str, string2: &'_ str) -> &'_ str { +fn some_function<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { //Some code } ``` or Erroneous code example 2: ``` -fn some_function<'u8>(string1: &'u8 str, string2: &'u8 str) -> &'u8 str { +fn some_function<'u8>(str1: &'u8 str, str2: &'u8 str) -> &'u8 str { //Some code } ``` @@ -25,7 +25,7 @@ single lowercase letter, such as `'a`, is sufficient. For more information, see Corrected code example: ``` -fn some_function<'a>(string1: &'a str, string2: &'a str) -> &'a str { +fn some_function<'a>(str1: &'a str, str2: &'a str) -> &'a str { //Some code } ``` From 78df44655aa8547baa25ee9ca49699ad82c7f76d Mon Sep 17 00:00:00 2001 From: Josh White Date: Thu, 6 Feb 2020 17:28:03 -0500 Subject: [PATCH 0982/1253] Tidied up the long error description --- src/librustc_error_codes/error_codes/E0637.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md index 44a365be7e0f7..978cf273c94d3 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -1,6 +1,5 @@ - An underscore `_` character or a numeric literal `u8`, `i32`, `f64`, etc has -been used as the identifier for a lifetime. +been used as the identifier for a lifetime. Erroneous code example 1: ``` @@ -29,6 +28,4 @@ fn some_function<'a>(str1: &'a str, str2: &'a str) -> &'a str { //Some code } ``` - [bk-no]: https://doc.rust-lang.org/book/appendix-02-operators.html#non-operator-symbols - From 861b328f7d62aebd1cfe381eb81bc7e80faf758e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 6 Feb 2020 14:43:53 -0800 Subject: [PATCH 0983/1253] Respect --nocapture in panic=abort test mode --- src/libtest/lib.rs | 26 ++++++++----- src/test/ui/test-panic-abort-nocapture.rs | 39 +++++++++++++++++++ .../ui/test-panic-abort-nocapture.run.stderr | 9 +++++ .../ui/test-panic-abort-nocapture.run.stdout | 23 +++++++++++ 4 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/test-panic-abort-nocapture.rs create mode 100644 src/test/ui/test-panic-abort-nocapture.run.stderr create mode 100644 src/test/ui/test-panic-abort-nocapture.run.stdout diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index e99473177e838..de001cacbe195 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -63,8 +63,7 @@ use std::{ env, io, io::prelude::Write, panic::{self, catch_unwind, AssertUnwindSafe, PanicInfo}, - process, - process::{Command, Termination}, + process::{self, Command, Termination}, sync::mpsc::{channel, Sender}, sync::{Arc, Mutex}, thread, @@ -457,9 +456,13 @@ pub fn run_test( monitor_ch, opts.time, ), - RunStrategy::SpawnPrimary => { - spawn_test_subprocess(desc, opts.time.is_some(), monitor_ch, opts.time) - } + RunStrategy::SpawnPrimary => spawn_test_subprocess( + desc, + opts.nocapture, + opts.time.is_some(), + monitor_ch, + opts.time, + ), }; // If the platform is single-threaded we're just going to run @@ -558,6 +561,7 @@ fn run_test_in_process( fn spawn_test_subprocess( desc: TestDesc, + nocapture: bool, report_time: bool, monitor_ch: Sender, time_opts: Option, @@ -566,11 +570,15 @@ fn spawn_test_subprocess( let args = env::args().collect::>(); let current_exe = &args[0]; + let mut command = Command::new(current_exe); + command.env(SECONDARY_TEST_INVOKER_VAR, desc.name.as_slice()); + if nocapture { + command.stdout(process::Stdio::inherit()); + command.stderr(process::Stdio::inherit()); + } + let start = report_time.then(Instant::now); - let output = match Command::new(current_exe) - .env(SECONDARY_TEST_INVOKER_VAR, desc.name.as_slice()) - .output() - { + let output = match command.output() { Ok(out) => out, Err(e) => { let err = format!("Failed to spawn {} as child for test: {:?}", args[0], e); diff --git a/src/test/ui/test-panic-abort-nocapture.rs b/src/test/ui/test-panic-abort-nocapture.rs new file mode 100644 index 0000000000000..75f7983865020 --- /dev/null +++ b/src/test/ui/test-panic-abort-nocapture.rs @@ -0,0 +1,39 @@ +// no-prefer-dynamic +// compile-flags: --test -Cpanic=abort -Zpanic_abort_tests +// run-flags: --test-threads=1 --nocapture +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 + +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![cfg(test)] + +use std::io::Write; + +#[test] +fn it_works() { + println!("about to succeed"); + assert_eq!(1 + 1, 2); +} + +#[test] +#[should_panic] +fn it_panics() { + println!("about to panic"); + assert_eq!(1 + 1, 4); +} + +#[test] +fn it_fails() { + println!("about to fail"); + assert_eq!(1 + 1, 4); +} + +#[test] +fn it_writes_to_stdio() { + println!("hello, world"); + writeln!(std::io::stdout(), "testing123").unwrap(); + writeln!(std::io::stderr(), "testing321").unwrap(); +} diff --git a/src/test/ui/test-panic-abort-nocapture.run.stderr b/src/test/ui/test-panic-abort-nocapture.run.stderr new file mode 100644 index 0000000000000..37fbe3d3ff21f --- /dev/null +++ b/src/test/ui/test-panic-abort-nocapture.run.stderr @@ -0,0 +1,9 @@ +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `2`, + right: `4`', $DIR/test-panic-abort-nocapture.rs:31:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `2`, + right: `4`', $DIR/test-panic-abort-nocapture.rs:25:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +testing321 diff --git a/src/test/ui/test-panic-abort-nocapture.run.stdout b/src/test/ui/test-panic-abort-nocapture.run.stdout new file mode 100644 index 0000000000000..87a246db5e07b --- /dev/null +++ b/src/test/ui/test-panic-abort-nocapture.run.stdout @@ -0,0 +1,23 @@ + +running 4 tests +test it_fails ... about to fail +FAILED +test it_panics ... about to panic +ok +test it_works ... about to succeed +ok +test it_writes_to_stdio ... hello, world +testing123 +ok + +failures: + +---- it_fails stdout ---- +---- it_fails stderr ---- + + +failures: + it_fails + +test result: FAILED. 3 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out + From c39f2092f727f128c60ac77f0ef9abd88e343f06 Mon Sep 17 00:00:00 2001 From: Hanna Kruppe Date: Thu, 6 Feb 2020 23:45:20 +0100 Subject: [PATCH 0984/1253] Add myself to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 6ab6be26cf101..14797092475a2 100644 --- a/.mailmap +++ b/.mailmap @@ -100,6 +100,7 @@ Graydon Hoare Graydon Hoare Guillaume Gomez Guillaume Gomez ggomez Guillaume Gomez Guillaume Gomez +Hanna Kruppe Heather Heather Herman J. Radtke III Herman J. Radtke III From be051adb57f1ff28edf997c3379aed2934bff104 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 23 Jan 2020 21:58:55 +0100 Subject: [PATCH 0985/1253] Create benchmarks for BTreeMap::range --- src/liballoc/benches/btree/map.rs | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs index ea69769279f12..83cdebf0e3f4a 100644 --- a/src/liballoc/benches/btree/map.rs +++ b/src/liballoc/benches/btree/map.rs @@ -1,5 +1,6 @@ use std::collections::BTreeMap; use std::iter::Iterator; +use std::ops::Bound::{Excluded, Unbounded}; use std::vec::Vec; use rand::{seq::SliceRandom, thread_rng, Rng}; @@ -200,3 +201,58 @@ pub fn first_and_last_100(b: &mut Bencher) { pub fn first_and_last_10k(b: &mut Bencher) { bench_first_and_last(b, 10_000); } + +#[bench] +pub fn range_excluded_excluded(b: &mut Bencher) { + let size = 144; + let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); + b.iter(|| { + for first in 0..size { + for last in first + 1..size { + black_box(map.range((Excluded(first), Excluded(last)))); + } + } + }); +} + +#[bench] +pub fn range_excluded_unbounded(b: &mut Bencher) { + let size = 144; + let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); + b.iter(|| { + for first in 0..size { + black_box(map.range((Excluded(first), Unbounded))); + } + }); +} + +#[bench] +pub fn range_included_included(b: &mut Bencher) { + let size = 144; + let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); + b.iter(|| { + for first in 0..size { + for last in first..size { + black_box(map.range(first..=last)); + } + } + }); +} + +#[bench] +pub fn range_included_unbounded(b: &mut Bencher) { + let size = 144; + let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); + b.iter(|| { + for first in 0..size { + black_box(map.range(first..)); + } + }); +} + +#[bench] +pub fn range_unbounded_unbounded(b: &mut Bencher) { + let size = 144; + let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); + b.iter(|| map.range(..)); +} From ae03e16d083d6d3cc9ad98ecb06e2f6cc2f5df68 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 23 Jan 2020 07:48:09 +0100 Subject: [PATCH 0986/1253] Lift range_search up one level of abstraction --- src/liballoc/collections/btree/map.rs | 66 ++++++++++-------------- src/liballoc/collections/btree/node.rs | 9 ++++ src/liballoc/collections/btree/search.rs | 12 ++++- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 8eabc1773042f..0b3f603686dc6 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1861,65 +1861,51 @@ where let mut max_node = root2; let mut min_found = false; let mut max_found = false; - let mut diverged = false; loop { - let min_edge = match (min_found, range.start_bound()) { - (false, Included(key)) => match search::search_linear(&min_node, key) { - (i, true) => { + let front = match (min_found, range.start_bound()) { + (false, Included(key)) => match search::search_node(min_node, key) { + Found(kv) => { min_found = true; - i + kv.left_edge() } - (i, false) => i, + GoDown(edge) => edge, }, - (false, Excluded(key)) => match search::search_linear(&min_node, key) { - (i, true) => { + (false, Excluded(key)) => match search::search_node(min_node, key) { + Found(kv) => { min_found = true; - i + 1 + kv.right_edge() } - (i, false) => i, + GoDown(edge) => edge, }, - (_, Unbounded) => 0, - (true, Included(_)) => min_node.len(), - (true, Excluded(_)) => 0, + (true, Included(_)) => min_node.last_edge(), + (true, Excluded(_)) => min_node.first_edge(), + (_, Unbounded) => min_node.first_edge(), }; - let max_edge = match (max_found, range.end_bound()) { - (false, Included(key)) => match search::search_linear(&max_node, key) { - (i, true) => { + let back = match (max_found, range.end_bound()) { + (false, Included(key)) => match search::search_node(max_node, key) { + Found(kv) => { max_found = true; - i + 1 + kv.right_edge() } - (i, false) => i, + GoDown(edge) => edge, }, - (false, Excluded(key)) => match search::search_linear(&max_node, key) { - (i, true) => { + (false, Excluded(key)) => match search::search_node(max_node, key) { + Found(kv) => { max_found = true; - i + kv.left_edge() } - (i, false) => i, + GoDown(edge) => edge, }, - (_, Unbounded) => max_node.len(), - (true, Included(_)) => 0, - (true, Excluded(_)) => max_node.len(), + (true, Included(_)) => max_node.first_edge(), + (true, Excluded(_)) => max_node.last_edge(), + (_, Unbounded) => max_node.last_edge(), }; - if !diverged { - if max_edge < min_edge { - panic!("Ord is ill-defined in BTreeMap range") - } - if min_edge != max_edge { - diverged = true; - } + if front.partial_cmp(&back) == Some(Ordering::Greater) { + panic!("Ord is ill-defined in BTreeMap range"); } - - // Safety guarantee: `min_edge` is always in range for `min_node`, because - // `min_edge` is unconditionally calculated for each iteration's value of `min_node`, - // either (if not found) as the edge index returned by `search_linear`, - // or (if found) as the KV index returned by `search_linear`, possibly + 1. - // Likewise for `max_node` versus `max_edge`. - let front = unsafe { Handle::new_edge(min_node, min_edge) }; - let back = unsafe { Handle::new_edge(max_node, max_edge) }; match (front.force(), back.force()) { (Leaf(f), Leaf(b)) => { return (f, b); diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index e4123c9a20b19..abf926186e82c 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -31,6 +31,7 @@ // - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges. // This implies that even an empty internal node has at least one edge. +use core::cmp::Ordering; use core::marker::PhantomData; use core::mem::{self, MaybeUninit}; use core::ptr::{self, NonNull, Unique}; @@ -832,6 +833,14 @@ impl PartialEq } } +impl PartialOrd + for Handle, HandleType> +{ + fn partial_cmp(&self, other: &Self) -> Option { + if self.node.node == other.node.node { Some(self.idx.cmp(&other.idx)) } else { None } + } +} + impl Handle, HandleType> { diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index e680e36414747..2ba5cebbdee74 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -10,6 +10,10 @@ pub enum SearchResult { GoDown(Handle, marker::Edge>), } +/// Looks up a given key in a (sub)tree headed by the given node, recursively. +/// Returns a `Found` with the handle of the matching KV, if any. Otherwise, +/// returns a `GoDown` with the handle of the possible leaf edge where the key +/// belongs. pub fn search_tree( mut node: NodeRef, key: &Q, @@ -32,6 +36,10 @@ where } } +/// Looks up a given key in a given node, without recursion. +/// Returns a `Found` with the handle of the matching KV, if any. Otherwise, +/// returns a `GoDown` with the handle of the edge where the key might be found. +/// If the node is a leaf, a `GoDown` edge is not an actual edge but a possible edge. pub fn search_node( node: NodeRef, key: &Q, @@ -50,8 +58,8 @@ where /// or could exist, and whether it exists in the node itself. If it doesn't /// exist in the node itself, it may exist in the subtree with that index /// (if the node has subtrees). If the key doesn't exist in node or subtree, -/// the returned index is the position or subtree to insert at. -pub fn search_linear( +/// the returned index is the position or subtree where the key belongs. +fn search_linear( node: &NodeRef, key: &Q, ) -> (usize, bool) From 8251e12950159c5802dd3995b14be7cf4fa99acd Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 7 Feb 2020 13:59:43 +0800 Subject: [PATCH 0987/1253] Don't use the word 'unwrap' to describe core unwrapping functions It's tautological, and Rust-specific Jargon. This changes various Option/Result methods to consistently describe unwrapping behavior using the words "return", "contain", "consume". It also renames the closure argument of `Return::unwrap_or_else` to `default` to be consistent with `Option`. --- src/libcore/option.rs | 26 ++++++++++++++++---------- src/libcore/result.rs | 38 ++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index ad0491f888cc7..c7b36d8ad6362 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -317,7 +317,7 @@ impl Option { // Getting to contained values ///////////////////////////////////////////////////////////////////////// - /// Unwraps an option, yielding the content of a [`Some`]. + /// Returns the contained [`Some`] value, consuming the `self` value. /// /// # Panics /// @@ -348,17 +348,22 @@ impl Option { } } - /// Moves the value `v` out of the `Option` if it is [`Some(v)`]. + /// Returns the contained [`Some`] value, consuming the `self` value. /// - /// In general, because this function may panic, its use is discouraged. + /// Because this function may panic, its use is generally discouraged. /// Instead, prefer to use pattern matching and handle the [`None`] - /// case explicitly. + /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or + /// [`unwrap_or_default`]. + /// + /// [`unwrap_or`]: #method.unwrap_or + /// [`unwrap_or_else`]: #method.unwrap_or_else + /// [`unwrap_or_default`]: #method.unwrap_or_default /// /// # Panics /// /// Panics if the self value equals [`None`]. /// - /// [`Some(v)`]: #variant.Some + /// [`Some`]: #variant.Some /// [`None`]: #variant.None /// /// # Examples @@ -382,12 +387,13 @@ impl Option { } } - /// Returns the contained value or a default. + /// Returns the contained [`Some`] value or a provided default. /// /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing /// the result of a function call, it is recommended to use [`unwrap_or_else`], /// which is lazily evaluated. /// + /// [`Some`]: #variant.Some /// [`unwrap_or_else`]: #method.unwrap_or_else /// /// # Examples @@ -405,7 +411,7 @@ impl Option { } } - /// Returns the contained value or computes it from a closure. + /// Returns the contained [`Some`] value or computes it from a closure. /// /// # Examples /// @@ -980,7 +986,7 @@ impl Option<&mut T> { } impl Option { - /// Unwraps an option, expecting [`None`] and returning nothing. + /// Consumes `self` while expecting [`None`] and returning nothing. /// /// # Panics /// @@ -1023,7 +1029,7 @@ impl Option { } } - /// Unwraps an option, expecting [`None`] and returning nothing. + /// Consumes `self` while expecting [`None`] and returning nothing. /// /// # Panics /// @@ -1068,7 +1074,7 @@ impl Option { } impl Option { - /// Returns the contained value or a default + /// Returns the contained [`Some`] value or a default /// /// Consumes the `self` argument then, if [`Some`], returns the contained /// value, otherwise if [`None`], returns the [default value] for that diff --git a/src/libcore/result.rs b/src/libcore/result.rs index ee28946f0da7a..022701c949815 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -792,8 +792,7 @@ impl Result { } } - /// Unwraps a result, yielding the content of an [`Ok`]. - /// Else, it returns `optb`. + /// Returns the contained [`Ok`] value or a provided default. /// /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing /// the result of a function call, it is recommended to use [`unwrap_or_else`], @@ -808,27 +807,25 @@ impl Result { /// Basic usage: /// /// ``` - /// let optb = 2; + /// let default = 2; /// let x: Result = Ok(9); - /// assert_eq!(x.unwrap_or(optb), 9); + /// assert_eq!(x.unwrap_or(default), 9); /// /// let x: Result = Err("error"); - /// assert_eq!(x.unwrap_or(optb), optb); + /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, optb: T) -> T { + pub fn unwrap_or(self, default: T) -> T { match self { Ok(t) => t, - Err(_) => optb, + Err(_) => default, } } - /// Unwraps a result, yielding the content of an [`Ok`]. - /// If the value is an [`Err`] then it calls `op` with its value. + /// Returns the contained [`Ok`] value or computes it from a closure. /// /// [`Ok`]: enum.Result.html#variant.Ok - /// [`Err`]: enum.Result.html#variant.Err /// /// # Examples /// @@ -931,7 +928,7 @@ impl Result<&mut T, E> { } impl Result { - /// Unwraps a result, yielding the content of an [`Ok`]. + /// Returns the contained [`Ok`] value, consuming the `self` value. /// /// # Panics /// @@ -959,7 +956,16 @@ impl Result { } } - /// Unwraps a result, yielding the content of an [`Ok`]. + /// Returns the contained [`Ok`] value, consuming the `self` value. + /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Err`] + /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or + /// [`unwrap_or_default`]. + /// + /// [`unwrap_or`]: #method.unwrap_or + /// [`unwrap_or_else`]: #method.unwrap_or_else + /// [`unwrap_or_default`]: #method.unwrap_or_default /// /// # Panics /// @@ -994,7 +1000,7 @@ impl Result { } impl Result { - /// Unwraps a result, yielding the content of an [`Err`]. + /// Returns the contained [`Err`] value, consuming the `self` value. /// /// # Panics /// @@ -1022,7 +1028,7 @@ impl Result { } } - /// Unwraps a result, yielding the content of an [`Err`]. + /// Returns the contained [`Err`] value, consuming the `self` value. /// /// # Panics /// @@ -1056,7 +1062,7 @@ impl Result { } impl Result { - /// Returns the contained value or a default + /// Returns the contained [`Ok`] value or a default /// /// Consumes the `self` argument then, if [`Ok`], returns the contained /// value, otherwise if [`Err`], returns the default value for that @@ -1095,7 +1101,7 @@ impl Result { #[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")] impl> Result { - /// Unwraps a result that can never be an [`Err`], yielding the content of the [`Ok`]. + /// Returns the contained [`Ok`] value, but never panics. /// /// Unlike [`unwrap`], this method is known to never panic on the /// result types it is implemented for. Therefore, it can be used From 44edbc0e90dd7364bc427e8a95a588251b9ef560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 7 Feb 2020 08:07:06 +0100 Subject: [PATCH 0988/1253] Remove HashStable impl for ast::Lifetime --- src/librustc/ich/impls_syntax.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index e1733794b8d72..d1815d5e320db 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -12,13 +12,6 @@ use smallvec::SmallVec; impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {} -impl<'a> HashStable> for ast::Lifetime { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.id.hash_stable(hcx, hasher); - self.ident.hash_stable(hcx, hasher); - } -} - impl<'a> HashStable> for [ast::Attribute] { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { if self.len() == 0 { From 26020f506338add6fec610ad8c2cb64c28546cbe Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Feb 2020 13:23:33 +0100 Subject: [PATCH 0989/1253] clean up E0276 explanation --- src/librustc_error_codes/error_codes/E0276.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0276.md b/src/librustc_error_codes/error_codes/E0276.md index 0e3a613bf9c02..ad76968c5897d 100644 --- a/src/librustc_error_codes/error_codes/E0276.md +++ b/src/librustc_error_codes/error_codes/E0276.md @@ -1,5 +1,6 @@ -This error occurs when a bound in an implementation of a trait does not match -the bounds specified in the original trait. For example: +A trait implementation has stricter requirements than the trait definition. + +Erroneous code example: ```compile_fail,E0276 trait Foo { From d252791a93b7ad26c9af63b68d223164a3678e8e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:14:21 +0100 Subject: [PATCH 0990/1253] Remove unused feature gate from librustc_incremental --- src/librustc_incremental/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 7ce4def2886b8..ca824fde7efc1 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -3,7 +3,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(specialization)] #![recursion_limit = "256"] #[macro_use] From 6638b867022fb1d2a56b6ed5f899e9fd00183396 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:18:04 +0100 Subject: [PATCH 0991/1253] Remove unused feature gates from librustc_interface --- src/librustc_interface/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index e4e6849ab8e59..ba1e2216ca805 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -2,10 +2,8 @@ #![feature(box_syntax)] #![feature(set_stdio)] #![feature(nll)] -#![feature(arbitrary_self_types)] #![feature(generator_trait)] #![feature(generators)] -#![cfg_attr(unix, feature(libc))] #![recursion_limit = "256"] #[cfg(unix)] From 74994af266a83edb9f82f8175de0c5c84bd849a0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:19:03 +0100 Subject: [PATCH 0992/1253] Remove unused feature gate from librustc_lint --- src/librustc_lint/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 78e9d0f14f2de..6e2db65c84005 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -28,7 +28,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![cfg_attr(test, feature(test))] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] #![feature(never_type)] From 6305c683cb63a3a83641aaf4ec763c290fc52b0c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 19:51:00 +0100 Subject: [PATCH 0993/1253] Remove unused feature gates from librustc_metadata --- src/librustc_metadata/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index d94f23ff8bc6a..d4cc3c32616ac 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -1,15 +1,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(core_intrinsics)] #![feature(crate_visibility_modifier)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] -#![feature(libc)] #![feature(nll)] #![feature(proc_macro_internals)] -#![feature(proc_macro_quote)] -#![feature(rustc_private)] #![feature(specialization)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] From 341594e1969795e4d48840ec48f0d6309ea0fa3a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:04:44 +0100 Subject: [PATCH 0994/1253] Remove unused feature gates from librustc_mir --- src/librustc_mir/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f064869d66471..4f1b90e34cf00 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -6,21 +6,15 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nll)] #![feature(in_band_lifetimes)] -#![feature(inner_deref)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(core_intrinsics)] -#![feature(decl_macro)] #![feature(drain_filter)] #![feature(exhaustive_patterns)] #![feature(iter_order_by)] #![feature(never_type)] #![feature(specialization)] -#![feature(try_trait)] -#![feature(unicode_internals)] -#![feature(slice_concat_ext)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(associated_type_bounds)] From 1bfba4fbce25ac02a8023a817eee2c539c47c37e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:08:15 +0100 Subject: [PATCH 0995/1253] Remove unused feature gate from librustc_resolve --- src/librustc_resolve/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index af4ba4c0eb20e..2e63c3e170605 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -9,7 +9,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(label_break_value)] #![feature(nll)] #![recursion_limit = "256"] From 1a26c1c67acd9360bed7121b917581c9d69fc214 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:09:43 +0100 Subject: [PATCH 0996/1253] Remove unused feature gate from librustc_target --- src/librustc_target/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index a9db0254a7d11..71150e74f70d4 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -8,7 +8,6 @@ //! LLVM. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(box_syntax)] #![feature(bool_to_option)] #![feature(nll)] From 8f672cd7dd9139947feb6b04f8b20dc27735dcc9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:12:28 +0100 Subject: [PATCH 0997/1253] Remove unused feature gates from librustc_typeck --- src/librustc_typeck/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 05ea9b1ac56dc..474868f0dd6c4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -58,10 +58,8 @@ This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(exhaustive_patterns)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(try_blocks)] From b7599990d492e2650f343ab61e1ce5d390996284 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:14:27 +0100 Subject: [PATCH 0998/1253] Remove unused feature gates from librustdoc --- src/librustdoc/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ed3f0f94e0ed8..4e0a2d9427431 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -3,19 +3,15 @@ html_playground_url = "https://play.rust-lang.org/" )] #![feature(rustc_private)] -#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(set_stdio)] #![feature(test)] #![feature(vec_remove_item)] #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] -#![feature(drain_filter)] #![feature(never_type)] -#![feature(unicode_internals)] #![recursion_limit = "256"] extern crate env_logger; From 9d6bdccd9e835c46de1f703a31cb00ccfeab9e84 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:15:15 +0100 Subject: [PATCH 0999/1253] Remove unused feature gate from libserialize --- src/libserialize/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 280fb078f7de4..b990e71bef0dd 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -10,7 +10,6 @@ Core encoding and decoding interfaces. test(attr(allow(unused_variables), deny(warnings))) )] #![feature(box_syntax)] -#![feature(core_intrinsics)] #![feature(specialization)] #![feature(never_type)] #![feature(nll)] From 91d01e7c6b3c646a183f9f0caab53b696b3feea8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 17 Nov 2019 20:17:38 +0100 Subject: [PATCH 1000/1253] Remove unused feature gates from libsyntax_pos --- src/librustc_span/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 413bd77daae24..ac9c3360b860d 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -8,9 +8,6 @@ #![feature(crate_visibility_modifier)] #![feature(nll)] #![feature(optin_builtin_traits)] -#![feature(rustc_attrs)] -#![feature(specialization)] -#![feature(step_trait)] use rustc_data_structures::AtomicRef; use rustc_macros::HashStable_Generic; From e38665676b291eeacf1b9ba54a476588da1230c1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 23 Dec 2019 16:26:53 +0100 Subject: [PATCH 1001/1253] Rustfmt --- src/librustc_codegen_llvm/metadata.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 36b12f1a7b184..0f30c2c020de7 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -22,10 +22,11 @@ impl MetadataLoader for LlvmMetadataLoader { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. - let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| { - debug!("llvm didn't like `{}`: {}", filename.display(), e); - format!("failed to read rlib metadata in '{}': {}", filename.display(), e) - })?; + let archive = + ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| { + debug!("llvm didn't like `{}`: {}", filename.display(), e); + format!("failed to read rlib metadata in '{}': {}", filename.display(), e) + })?; let buf: OwningRef<_, [u8]> = archive.try_map(|ar| { ar.iter() .filter_map(|s| s.ok()) @@ -44,9 +45,10 @@ impl MetadataLoader for LlvmMetadataLoader { let buf = path_to_c_string(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; - let of = ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| { - format!("provided path not an object file: '{}'", filename.display()) - })?; + let of = + ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| { + format!("provided path not an object file: '{}'", filename.display()) + })?; let buf = of.try_map(|of| search_meta_section(of, target, filename))?; Ok(rustc_erase_owner!(buf)) } From 5827d78f18ce688a96ecd5a20defda07c8834936 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 25 Jan 2020 12:13:14 +0100 Subject: [PATCH 1002/1253] Fix test --- src/test/ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index a316d8f1698ac..3eb8e0ec18288 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:357:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:355:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 4eeaa923666077f4690253acbff82a409a4a9028 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Feb 2020 15:04:44 +0100 Subject: [PATCH 1003/1253] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 75417e5a66009..e3cfb61ece273 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 75417e5a660096929aa10f1072a21d6662c9c0dc +Subproject commit e3cfb61ece273d59b62fb959ed17c99c04941d82 From 73936ab57ad567802a613157ae9db0cccf31eda3 Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Fri, 7 Feb 2020 04:03:54 +0300 Subject: [PATCH 1004/1253] print generic bounds on associated types --- src/librustc_ast_pretty/pprust.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index d9077d1606f3a..78bf149f0e01a 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1074,12 +1074,15 @@ impl<'a> State<'a> { fn print_associated_type( &mut self, ident: ast::Ident, + generics: &ast::Generics, bounds: &ast::GenericBounds, ty: Option<&ast::Ty>, ) { self.word_space("type"); self.print_ident(ident); + self.print_generic_params(&generics.params); self.print_type_bounds(":", bounds); + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.s.space(); self.word_space("="); @@ -1474,7 +1477,7 @@ impl<'a> State<'a> { self.print_fn_full(sig, item.ident, &item.generics, &item.vis, body, &item.attrs); } ast::AssocItemKind::TyAlias(bounds, ty) => { - self.print_associated_type(item.ident, bounds, ty.as_deref()); + self.print_associated_type(item.ident, &item.generics, bounds, ty.as_deref()); } ast::AssocItemKind::Macro(mac) => { self.print_mac(mac); From ab6ea2bba771836ebbf8759e718fedd2c6d229d2 Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Fri, 7 Feb 2020 05:17:38 +0300 Subject: [PATCH 1005/1253] add regression test --- src/test/pretty/gat-bounds.pp | 25 +++++++++++++++++++++++++ src/test/pretty/gat-bounds.rs | 17 +++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/test/pretty/gat-bounds.pp create mode 100644 src/test/pretty/gat-bounds.rs diff --git a/src/test/pretty/gat-bounds.pp b/src/test/pretty/gat-bounds.pp new file mode 100644 index 0000000000000..0c95add490110 --- /dev/null +++ b/src/test/pretty/gat-bounds.pp @@ -0,0 +1,25 @@ +// Check that associated types print generic parameters and where clauses. +// See issue #67509. + +// pretty-compare-only +// pp-exact:gat-bounds.pp + +#![feature(generic_associated_types)] + +trait X { + type + Y: Trait + where + Self: Sized; +} + +impl X for () { + type + Y + where + Self: Sized + = + u32; +} + +fn main() { } diff --git a/src/test/pretty/gat-bounds.rs b/src/test/pretty/gat-bounds.rs new file mode 100644 index 0000000000000..1275f432a3c50 --- /dev/null +++ b/src/test/pretty/gat-bounds.rs @@ -0,0 +1,17 @@ +// Check that associated types print generic parameters and where clauses. +// See issue #67509. + +// pretty-compare-only +// pp-exact:gat-bounds.pp + +#![feature(generic_associated_types)] + +trait X { + type Y: Trait where Self: Sized; +} + +impl X for () { + type Y where Self: Sized = u32; +} + +fn main() { } From bf82582d6f8de744df5c34e80a04ad72f40afed7 Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Fri, 7 Feb 2020 18:27:12 +0300 Subject: [PATCH 1006/1253] add hir printing --- src/librustc_hir/print.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index b0d2f96c71a03..071c3de4b1c2c 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -454,14 +454,17 @@ impl<'a> State<'a> { fn print_associated_type( &mut self, ident: ast::Ident, + generics: &hir::Generics<'_>, bounds: Option>, ty: Option<&hir::Ty<'_>>, ) { self.word_space("type"); self.print_ident(ident); + self.print_generic_params(&generics.params); if let Some(bounds) = bounds { self.print_bounds(":", bounds); } + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.s.space(); self.word_space("="); @@ -902,6 +905,7 @@ impl<'a> State<'a> { hir::TraitItemKind::Type(ref bounds, ref default) => { self.print_associated_type( ti.ident, + &ti.generics, Some(bounds), default.as_ref().map(|ty| &**ty), ); @@ -930,7 +934,7 @@ impl<'a> State<'a> { self.ann.nested(self, Nested::Body(body)); } hir::ImplItemKind::TyAlias(ref ty) => { - self.print_associated_type(ii.ident, None, Some(ty)); + self.print_associated_type(ii.ident, &ii.generics, None, Some(ty)); } hir::ImplItemKind::OpaqueTy(bounds) => { self.word_space("type"); From 8b77f8688e9436c6b35d5746e3bb79e20c67567d Mon Sep 17 00:00:00 2001 From: Josh White Date: Fri, 7 Feb 2020 12:44:31 -0500 Subject: [PATCH 1007/1253] performed --bless of 15 ui tests affected --- src/librustc_error_codes/error_codes/E0637.md | 69 ++++++++++++++----- .../const-param-elided-lifetime.stderr | 1 + src/test/ui/error-codes/E0637.stderr | 1 + ...rrect-explicit-lifetime-name-needed.stderr | 3 +- .../ui/underscore-lifetime/in-binder.stderr | 1 + .../underscore-lifetime-binders.stderr | 3 +- .../underscore-outlives-bounds.stderr | 1 + ...se-inherent-impl-ampersand.rust2015.stderr | 1 + ...se-inherent-impl-ampersand.rust2018.stderr | 1 + ...e-inherent-impl-underscore.rust2015.stderr | 1 + ...e-inherent-impl-underscore.rust2018.stderr | 1 + ...e-clause-trait-impl-region.rust2015.stderr | 1 + ...e-clause-trait-impl-region.rust2018.stderr | 1 + ...ause-trait-impl-underscore.rust2015.stderr | 1 + ...ause-trait-impl-underscore.rust2018.stderr | 1 + .../underscore-lifetime/where-clauses.stderr | 1 + 16 files changed, 67 insertions(+), 21 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md index 978cf273c94d3..ba81e42ce0850 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -1,31 +1,62 @@ -An underscore `_` character or a numeric literal `u8`, `i32`, `f64`, etc has -been used as the identifier for a lifetime. +An underscore `_` character has been used as the identifier for a lifetime, +or a const generic has been borrowed without an explicit lifetime. -Erroneous code example 1: +Erroneous example with an underscore: ``` -fn some_function<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { - //Some code -} +fn foo<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {} + // ^^ `'_` is a reserved lifetime name +``` +Lifetimes are named with `'ident`, where ident is the name of the lifetime or +loop. The `_` character, which represents the ignore pattern, cannot be used +as the identifier because it is a reserved lifetime name. To fix +this, use a lowercase letter, or a series of lowercase letters as the lifetime +identifier. Often a single lowercase letter, such as `'a`, is sufficient. For +more information, see +[the book][bk-no]. + +Corrected underscore example: +``` +fn <'a>(str1: &'a str, str2: &'a str) -> &'a str {} ``` -or Erroneous code example 2: + +Erroneous example with const generic: ``` -fn some_function<'u8>(str1: &'u8 str, str2: &'u8 str) -> &'u8 str { - //Some code +struct A; +//~^ ERROR `&` without an explicit lifetime name cannot be used here +trait B {} + +impl A { +//~^ ERROR `&` without an explicit lifetime name cannot be used here + fn foo(&self) {} + //~^ ERROR `&` without an explicit lifetime name cannot be used here +} + +impl B for A {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here + +fn bar() {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here } ``` -Lifetimes are named with `'ident`, where ident is the name of the lifetime or -loop. The `_` character, which represents the ignore pattern, cannot be used -as the identifier because it is a reserved lifetime name. Numeric literals are -also invalid lifetime identifiers and will cause this error to be thrown. To fix -this, use a series of lowercase letters as the lifetime identifier. Often a -single lowercase letter, such as `'a`, is sufficient. For more information, see -[the book][bk-no]. +Const generics cannot be borrowed without specifying a lifetime.The +compiler handles memory allocation of constants differently than that of +variables and it cannot infer the lifetime of the borrowed constant. +To fix this, explicitly specify a lifetime for the const generic. -Corrected code example: +Corrected const generic example: ``` -fn some_function<'a>(str1: &'a str, str2: &'a str) -> &'a str { - //Some code +struct A; + +trait B {} + +impl A { + fn foo(&self) {} +} + +impl B for A {} + +fn bar() {} } ``` [bk-no]: https://doc.rust-lang.org/book/appendix-02-operators.html#non-operator-symbols diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.stderr index 93133c507fe40..6841d1fdf360b 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.stderr +++ b/src/test/ui/const-generics/const-param-elided-lifetime.stderr @@ -38,3 +38,4 @@ LL | #![feature(const_generics)] error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/error-codes/E0637.stderr b/src/test/ui/error-codes/E0637.stderr index 9c3ca87ed7e64..d19ebfd15a52c 100644 --- a/src/test/ui/error-codes/E0637.stderr +++ b/src/test/ui/error-codes/E0637.stderr @@ -18,3 +18,4 @@ LL | impl<'a: '_> Bar<'a> { error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr index 8720288b53e58..9f410c0dbbbd2 100644 --- a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr +++ b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr @@ -18,4 +18,5 @@ LL | fn bar<'b, L: X<&'b Nested>>(){} error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0106`. +Some errors have detailed explanations: E0106, E0637. +For more information about an error, try `rustc --explain E0106`. diff --git a/src/test/ui/underscore-lifetime/in-binder.stderr b/src/test/ui/underscore-lifetime/in-binder.stderr index 1b936dd9aec2f..fcd7eddb57605 100644 --- a/src/test/ui/underscore-lifetime/in-binder.stderr +++ b/src/test/ui/underscore-lifetime/in-binder.stderr @@ -36,3 +36,4 @@ LL | fn foo<'_>() { error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index c7cda38e47691..ada4551baefff 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -38,4 +38,5 @@ LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y } error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0106`. +Some errors have detailed explanations: E0106, E0637. +For more information about an error, try `rustc --explain E0106`. diff --git a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr index 6fa74d4e31034..4b38a26f957f9 100644 --- a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr +++ b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr @@ -6,3 +6,4 @@ LL | impl<'b: '_> Foo<'b> for i32 {} error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr index eec8e4b846886..fe726cb49c737 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr @@ -6,3 +6,4 @@ LL | T: WithType<&u32> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr index eec8e4b846886..fe726cb49c737 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr @@ -6,3 +6,4 @@ LL | T: WithType<&u32> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr index d2c3e352045b6..95939fd6b7e03 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2015.stderr @@ -6,3 +6,4 @@ LL | T: WithRegion<'_> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr index d2c3e352045b6..95939fd6b7e03 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rust2018.stderr @@ -6,3 +6,4 @@ LL | T: WithRegion<'_> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr index 586b2b6aeaf28..fbd14de21078b 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr @@ -6,3 +6,4 @@ LL | T: WithType<&u32> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr index 586b2b6aeaf28..fbd14de21078b 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr @@ -6,3 +6,4 @@ LL | T: WithType<&u32> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr index faabf57a7df40..92caff0dcde99 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2015.stderr @@ -6,3 +6,4 @@ LL | T: WithRegion<'_> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr index faabf57a7df40..92caff0dcde99 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rust2018.stderr @@ -6,3 +6,4 @@ LL | T: WithRegion<'_> error: aborting due to previous error +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/underscore-lifetime/where-clauses.stderr b/src/test/ui/underscore-lifetime/where-clauses.stderr index 8674a925c110d..1a3ea4af7e12e 100644 --- a/src/test/ui/underscore-lifetime/where-clauses.stderr +++ b/src/test/ui/underscore-lifetime/where-clauses.stderr @@ -12,3 +12,4 @@ LL | impl Foo<'static> for Vec {} error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0637`. From 953f6ecb6adc37b4f8e52102c1e7ca86cc5bc92c Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Fri, 7 Feb 2020 23:38:13 +0300 Subject: [PATCH 1008/1253] fix lifetime shadowing check in GATs --- src/librustc_resolve/lifetimes.rs | 6 ++++-- .../ui/generic-associated-types/shadowing.rs | 4 ++-- .../generic-associated-types/shadowing.stderr | 21 +++++++++++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 0ba9b4f17068e..c527d6050cabc 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -747,7 +747,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: true, }; - self.with(scope, |_old_scope, this| { + self.with(scope, |old_scope, this| { + this.check_lifetime_params(old_scope, &generics.params); this.visit_generics(generics); for bound in bounds { this.visit_param_bound(bound); @@ -804,7 +805,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: true, }; - self.with(scope, |_old_scope, this| { + self.with(scope, |old_scope, this| { + this.check_lifetime_params(old_scope, &generics.params); this.visit_generics(generics); this.visit_ty(ty); }); diff --git a/src/test/ui/generic-associated-types/shadowing.rs b/src/test/ui/generic-associated-types/shadowing.rs index 7277c0d87c6ff..5c308948bd3f8 100644 --- a/src/test/ui/generic-associated-types/shadowing.rs +++ b/src/test/ui/generic-associated-types/shadowing.rs @@ -2,8 +2,8 @@ #![feature(generic_associated_types)] trait Shadow<'a> { - //FIXME(#44265): The lifetime parameter shadowing should cause an error. type Bar<'a>; + //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope } trait NoShadow<'a> { @@ -11,8 +11,8 @@ trait NoShadow<'a> { } impl<'a> NoShadow<'a> for &'a u32 { - //FIXME(#44265): The lifetime parameter shadowing should cause an error. type Bar<'a> = i32; + //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope } trait ShadowT { diff --git a/src/test/ui/generic-associated-types/shadowing.stderr b/src/test/ui/generic-associated-types/shadowing.stderr index 50c12e822e7db..1cb6f071f3a19 100644 --- a/src/test/ui/generic-associated-types/shadowing.stderr +++ b/src/test/ui/generic-associated-types/shadowing.stderr @@ -14,6 +14,22 @@ LL | impl NoShadowT for Option { LL | type Bar = i32; | ^ already used +error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope + --> $DIR/shadowing.rs:5:14 + | +LL | trait Shadow<'a> { + | -- first declared here +LL | type Bar<'a>; + | ^^ lifetime 'a already in scope + +error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope + --> $DIR/shadowing.rs:14:14 + | +LL | impl<'a> NoShadow<'a> for &'a u32 { + | -- first declared here +LL | type Bar<'a> = i32; + | ^^ lifetime 'a already in scope + error: type-generic associated types are not yet implemented --> $DIR/shadowing.rs:19:5 | @@ -30,6 +46,7 @@ LL | type Bar; // OK | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0403`. +Some errors have detailed explanations: E0403, E0496. +For more information about an error, try `rustc --explain E0403`. From 3998249ae77f3a6e1c6e44de944e9d5928963594 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 22:00:25 -0500 Subject: [PATCH 1009/1253] remove unnecessary local variable assignment in context manager --- src/bootstrap/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 1935759a5628e..563f12e7bacbd 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -351,7 +351,7 @@ def support_xz(): try: with tempfile.NamedTemporaryFile(delete=False) as temp_file: temp_path = temp_file.name - with tarfile.open(temp_path, "w:xz") as tar: + with tarfile.open(temp_path, "w:xz"): pass return True except tarfile.CompressionError: From 19aaf639459705e2b397f2b8a12f3d73ef0748b2 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 22:04:44 -0500 Subject: [PATCH 1010/1253] PEP8 format spacing --- src/bootstrap/bootstrap.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 563f12e7bacbd..50e1726240fff 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -80,7 +80,7 @@ def _download(path, url, probably_big, verbose, exception): option = "-s" run(["curl", option, "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds - "--connect-timeout", "30", # timeout if cannot connect within 30 seconds + "--connect-timeout", "30", # timeout if cannot connect within 30 seconds "--retry", "3", "-Sf", "-o", path, url], verbose=verbose, exception=exception) @@ -332,7 +332,6 @@ def __init__(self): self.use_vendored_sources = '' self.verbose = False - def download_stage0(self): """Fetch the build system for Rust, written in Rust @@ -825,7 +824,7 @@ def check_vendored_status(self): if not os.path.exists(vendor_dir): print('error: vendoring required, but vendor directory does not exist.') print(' Run `cargo vendor` without sudo to initialize the ' - 'vendor directory.') + 'vendor directory.') raise Exception("{} not found".format(vendor_dir)) if self.use_vendored_sources: @@ -839,7 +838,7 @@ def check_vendored_status(self): "\n" "[source.vendored-sources]\n" "directory = '{}/vendor'\n" - .format(self.rust_root)) + .format(self.rust_root)) else: if os.path.exists('.cargo'): shutil.rmtree('.cargo') From 6ce8d2b00005143d5f0fb0c9b712ece7709b3ecf Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 22:09:55 -0500 Subject: [PATCH 1011/1253] PEP8 format spacing --- src/bootstrap/configure.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 7cfc5385e2104..27bd6d028cd32 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -392,11 +392,12 @@ def set(key, value): def is_number(value): - try: - float(value) - return True - except ValueError: - return False + try: + float(value) + return True + except ValueError: + return False + # Here we walk through the constructed configuration we have from the parsed # command line arguments. We then apply each piece of configuration by From adde3d443d042cd53f7448ce1d6f32e1634fcf28 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 22:30:11 -0500 Subject: [PATCH 1012/1253] PEP8 format spacing --- src/tools/publish_toolstate.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 61762ae1d9b04..967333c1ace4f 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -1,11 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -## This script publishes the new "current" toolstate in the toolstate repo (not to be -## confused with publishing the test results, which happens in -## `src/ci/docker/x86_64-gnu-tools/checktools.sh`). -## It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts -## when a new commit lands on `master` (i.e., after it passed all checks on `auto`). +# This script publishes the new "current" toolstate in the toolstate repo (not to be +# confused with publishing the test results, which happens in +# `src/ci/docker/x86_64-gnu-tools/checktools.sh`). +# It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts +# when a new commit lands on `master` (i.e., after it passed all checks on `auto`). from __future__ import print_function @@ -103,6 +103,7 @@ def validate_maintainers(repo, github_token): print("The build will fail due to this.") exit(1) + def read_current_status(current_commit, path): '''Reads build status of `current_commit` from content of `history/*.tsv` ''' @@ -113,14 +114,17 @@ def read_current_status(current_commit, path): return json.loads(status) return {} + def gh_url(): return os.environ['TOOLSTATE_ISSUES_API_URL'] + def maybe_delink(message): if os.environ.get('TOOLSTATE_SKIP_MENTIONS') is not None: return message.replace("@", "") return message + def issue( tool, status, @@ -164,6 +168,7 @@ def issue( )) response.read() + def update_latest( current_commit, relevant_pr_number, @@ -194,7 +199,7 @@ def update_latest( for status in latest: tool = status['tool'] changed = False - create_issue_for_status = None # set to the status that caused the issue + create_issue_for_status = None # set to the status that caused the issue for os, s in current_status.items(): old = status[os] From cd5ad993d093f8ee5eedb63ed888a2ae2c35299f Mon Sep 17 00:00:00 2001 From: John VanEnk Date: Fri, 10 Jan 2020 17:16:04 -0800 Subject: [PATCH 1013/1253] Add a test that demonstrates a segfault when calling into rust with non-c-like-enum. --- .../return-non-c-like-enum/Makefile | 7 ++++ .../return-non-c-like-enum/nonclike.rs | 13 +++++++ .../return-non-c-like-enum/test.c | 35 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum/Makefile create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum/test.c diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile b/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile new file mode 100644 index 0000000000000..5b5d620efe655 --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) --crate-type=staticlib nonclike.rs + $(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \ + $(EXTRACFLAGS) $(EXTRACXXFLAGS) + $(call RUN,test) diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs new file mode 100644 index 0000000000000..36f618b05e843 --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] +#![crate_name = "nonclike"] + +#[repr(C,u8)] +pub enum T { + A(u64), + B, +} + +#[no_mangle] +pub extern "C" fn t_new(a: u64) -> T { + T::A(a) +} diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/test.c b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c new file mode 100644 index 0000000000000..bcc17c0008d9c --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c @@ -0,0 +1,35 @@ +#include +#include + +/* This is the code generated by cbindgen 0.12.1 for the `enum T` type + * in nonclike.rs . */ +enum T_Tag { + A, + B, +}; +typedef uint8_t T_Tag; + +typedef struct { + uint64_t _0; +} A_Body; + +typedef struct { + T_Tag tag; + union { + A_Body a; + }; +} T; + +/* This symbol is defined by the Rust staticlib built from + * nonclike.rs. */ +extern T t_new(uint64_t v); + +int main(int argc, char *argv[]) { + (void)argc; (void)argv; + + T t = t_new(10); + assert(A == t.tag); + assert(10 == t.a._0); + + return 0; +} From f1b52b34f201456d8a0e9da907e3e5619fa24ac7 Mon Sep 17 00:00:00 2001 From: John VanEnk Date: Fri, 10 Jan 2020 17:42:30 -0800 Subject: [PATCH 1014/1253] Add a test that demonstrates an incorrect return value when calling into rust with non-c-like-enums. --- .../arguments-non-c-like-enum/Makefile | 7 ++++ .../arguments-non-c-like-enum/nonclike.rs | 18 +++++++++ .../arguments-non-c-like-enum/test.c | 40 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile create mode 100644 src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs create mode 100644 src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile b/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile new file mode 100644 index 0000000000000..5b5d620efe655 --- /dev/null +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) --crate-type=staticlib nonclike.rs + $(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \ + $(EXTRACFLAGS) $(EXTRACXXFLAGS) + $(call RUN,test) diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs new file mode 100644 index 0000000000000..563f907608bd0 --- /dev/null +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] +#![crate_name = "nonclike"] + +#[repr(C,u8)] +pub enum T { + A(u64), + B, +} + +#[no_mangle] +pub extern "C" fn t_add(a: T, b: T) -> u64 { + match (a,b) { + (T::A(a), T::A(b)) => a + b, + (T::A(a), T::B) => a, + (T::B, T::A(b)) => b, + _ => 0, + } +} diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c new file mode 100644 index 0000000000000..f622471e7d1fa --- /dev/null +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c @@ -0,0 +1,40 @@ +#include +#include + +#include + +/* This is the code generated by cbindgen 0.12.1 for the `enum T` type + * in nonclike.rs . */ +enum T_Tag { + A, + B, +}; +typedef uint8_t T_Tag; + +typedef struct { + uint64_t _0; +} A_Body; + +typedef struct { + T_Tag tag; + union { + A_Body a; + }; +} T; + +/* This symbol is defined by the Rust staticlib built from + * nonclike.rs. */ +extern uint64_t t_add(T a, T b); + +int main(int argc, char *argv[]) { + (void)argc; (void)argv; + + T x = { .tag = A, .a = { ._0 = 1 } }; + T y = { .tag = A, .a = { ._0 = 10 } }; + + uint64_t r = t_add(x, y); + + assert(11 == r); + + return 0; +} From 26bb0f15e7e97bc93385296c2932193fe6da6300 Mon Sep 17 00:00:00 2001 From: John VanEnk Date: Fri, 10 Jan 2020 17:59:18 -0800 Subject: [PATCH 1015/1253] Add similar examples that work to each test. --- .../arguments-non-c-like-enum/nonclike.rs | 20 ++++++++++-- .../arguments-non-c-like-enum/test.c | 32 +++++++++++++++++-- .../return-non-c-like-enum/nonclike.rs | 11 +++++++ .../return-non-c-like-enum/test.c | 30 ++++++++++++++++- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs index 563f907608bd0..8f75076a30e99 100644 --- a/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs @@ -1,7 +1,23 @@ #![crate_type = "lib"] #![crate_name = "nonclike"] -#[repr(C,u8)] +#[repr(C, u8)] +pub enum TT { + AA(u64, u64), + BB, +} + +#[no_mangle] +pub extern "C" fn tt_add(a: TT, b: TT) -> u64 { + match (a, b) { + (TT::AA(a1, b1), TT::AA(a2, b2)) => a1 + a2 + b1 + b2, + (TT::AA(a1, b1), TT::BB) => a1 + b1, + (TT::BB, TT::AA(a1, b1)) => a1 + b1, + _ => 0, + } +} + +#[repr(C, u8)] pub enum T { A(u64), B, @@ -9,7 +25,7 @@ pub enum T { #[no_mangle] pub extern "C" fn t_add(a: T, b: T) -> u64 { - match (a,b) { + match (a, b) { (T::A(a), T::A(b)) => a + b, (T::A(a), T::B) => a, (T::B, T::A(b)) => b, diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c index f622471e7d1fa..d34babcf3d33d 100644 --- a/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c @@ -3,6 +3,26 @@ #include +/* This is the code generated by cbindgen 0.12.1 for the `enum TT` + * type in nonclike.rs . */ +enum TT_Tag { + AA, + BB, +}; +typedef uint8_t TT_Tag; + +typedef struct { + uint64_t _0; + uint64_t _1; +} AA_Body; + +typedef struct { + TT_Tag tag; + union { + AA_Body aa; + }; +} TT; + /* This is the code generated by cbindgen 0.12.1 for the `enum T` type * in nonclike.rs . */ enum T_Tag { @@ -22,18 +42,24 @@ typedef struct { }; } T; -/* This symbol is defined by the Rust staticlib built from +/* These symbols are defined by the Rust staticlib built from * nonclike.rs. */ extern uint64_t t_add(T a, T b); +extern uint64_t tt_add(TT a, TT b); int main(int argc, char *argv[]) { (void)argc; (void)argv; + /* This example works. */ + TT xx = { .tag = AA, .aa = { ._0 = 1, ._1 = 2 } }; + TT yy = { .tag = AA, .aa = { ._0 = 10, ._1 = 20 } }; + uint64_t rr = tt_add(xx, yy); + assert(33 == rr); + + /* This one returns an incorrect result. */ T x = { .tag = A, .a = { ._0 = 1 } }; T y = { .tag = A, .a = { ._0 = 10 } }; - uint64_t r = t_add(x, y); - assert(11 == r); return 0; diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs index 36f618b05e843..700d2df1f3811 100644 --- a/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs @@ -1,6 +1,17 @@ #![crate_type = "lib"] #![crate_name = "nonclike"] +#[repr(C, u8)] +pub enum TT { + AA(u64, u64), + BB, +} + +#[no_mangle] +pub extern "C" fn tt_new(a: u64, b: u64) -> TT { + TT::AA(a, b) +} + #[repr(C,u8)] pub enum T { A(u64), diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/test.c b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c index bcc17c0008d9c..3cbd8e6a20cb2 100644 --- a/src/test/run-make-fulldeps/return-non-c-like-enum/test.c +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c @@ -1,6 +1,26 @@ #include #include +/* This is the code generated by cbindgen 0.12.1 for the `enum TT` + * type in nonclike.rs . */ +enum TT_Tag { + AA, + BB, +}; +typedef uint8_t TT_Tag; + +typedef struct { + uint64_t _0; + uint64_t _1; +} AA_Body; + +typedef struct { + TT_Tag tag; + union { + AA_Body aa; + }; +} TT; + /* This is the code generated by cbindgen 0.12.1 for the `enum T` type * in nonclike.rs . */ enum T_Tag { @@ -20,13 +40,21 @@ typedef struct { }; } T; -/* This symbol is defined by the Rust staticlib built from +/* These symbols are defined by the Rust staticlib built from * nonclike.rs. */ +extern TT tt_new(uint64_t a, uint64_t b); extern T t_new(uint64_t v); int main(int argc, char *argv[]) { (void)argc; (void)argv; + /* This example works. */ + TT tt = tt_new(10, 20); + assert(AA == tt.tag); + assert(10 == tt.aa._0); + assert(20 == tt.aa._1); + + /* This one segfaults. */ T t = t_new(10); assert(A == t.tag); assert(10 == t.a._0); From 60889d418e37897e272844d15b03fed62c60b92d Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 23:35:27 -0500 Subject: [PATCH 1016/1253] remove unnecessary semicolons --- src/ci/cpu-usage-over-time.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/cpu-usage-over-time.py b/src/ci/cpu-usage-over-time.py index daf21670b3339..78ac060368193 100644 --- a/src/ci/cpu-usage-over-time.py +++ b/src/ci/cpu-usage-over-time.py @@ -148,11 +148,11 @@ def idle_since(self, prev): print('unknown platform', sys.platform) sys.exit(1) -cur_state = State(); +cur_state = State() print("Time,Idle") while True: - time.sleep(1); - next_state = State(); + time.sleep(1) + next_state = State() now = datetime.datetime.utcnow().isoformat() idle = next_state.idle_since(cur_state) print("%s,%s" % (now, idle)) From 92fc98c695d133ae28fb9d386d22efef57e2fc87 Mon Sep 17 00:00:00 2001 From: Josh White Date: Fri, 7 Feb 2020 23:40:16 -0500 Subject: [PATCH 1017/1253] Cleaned up long error description --- src/librustc_error_codes/error_codes/E0637.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0637.md b/src/librustc_error_codes/error_codes/E0637.md index ba81e42ce0850..13be503676790 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/src/librustc_error_codes/error_codes/E0637.md @@ -11,8 +11,7 @@ loop. The `_` character, which represents the ignore pattern, cannot be used as the identifier because it is a reserved lifetime name. To fix this, use a lowercase letter, or a series of lowercase letters as the lifetime identifier. Often a single lowercase letter, such as `'a`, is sufficient. For -more information, see -[the book][bk-no]. +more information, see [the book][bk-no]. Corrected underscore example: ``` From e30dd86c61c8159b02940b888d876a57d8b07b7e Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 23:47:29 -0500 Subject: [PATCH 1018/1253] PEP8 format spacing --- src/etc/debugger_pretty_printers_common.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py index 385ce8efab87b..b3f8f50636bee 100644 --- a/src/etc/debugger_pretty_printers_common.py +++ b/src/etc/debugger_pretty_printers_common.py @@ -212,7 +212,6 @@ def __classify_struct(self): # REGULAR STRUCT return TYPE_KIND_REGULAR_STRUCT - def __classify_union(self): assert self.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION @@ -233,7 +232,6 @@ def __classify_union(self): else: return TYPE_KIND_REGULAR_UNION - def __conforms_to_field_layout(self, expected_fields): actual_fields = self.get_fields() actual_field_count = len(actual_fields) @@ -363,6 +361,7 @@ def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val): assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR return (tail, head, data_ptr, capacity) + def extract_length_and_ptr_from_slice(slice_val): assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE) @@ -376,8 +375,10 @@ def extract_length_and_ptr_from_slice(slice_val): assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR return (length, data_ptr) + UNQUALIFIED_TYPE_MARKERS = frozenset(["(", "[", "&", "*"]) + def extract_type_name(qualified_type_name): """Extracts the type name from a fully qualified path""" if qualified_type_name[0] in UNQUALIFIED_TYPE_MARKERS: @@ -393,6 +394,7 @@ def extract_type_name(qualified_type_name): else: return qualified_type_name[index + 2:] + try: compat_str = unicode # Python 2 except NameError: From f38e2701d862379eca06475d196438038ca72564 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Fri, 7 Feb 2020 23:49:40 -0500 Subject: [PATCH 1019/1253] remove unnecessary sys import --- src/etc/dec2flt_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/dec2flt_table.py b/src/etc/dec2flt_table.py index 85395d2ecdfc7..4979882ffeaff 100755 --- a/src/etc/dec2flt_table.py +++ b/src/etc/dec2flt_table.py @@ -14,7 +14,6 @@ even larger, and it's already uncomfortably large (6 KiB). """ from __future__ import print_function -import sys from math import ceil, log from fractions import Fraction from collections import namedtuple @@ -82,6 +81,7 @@ def error(f, e, z): ulp_err = abs_err / Fraction(2) ** z.exp return float(ulp_err) + HEADER = """ //! Tables of approximations of powers of ten. //! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py` From 3b23b9864c07e47247c93d69e7ed8197c4cc9b37 Mon Sep 17 00:00:00 2001 From: John VanEnk Date: Tue, 21 Jan 2020 22:26:13 -0800 Subject: [PATCH 1020/1253] Two test cases where Rust calls C using enums by value One calls into C functions passing non-c-like enumerations by value. The other calls into C expecting non-C-like enumerations as returns. These test cases are based on the tests provided by @bitwalker on issue #68190. The original tests were provided at: https://github.com/bitwalker/rust_non_c_like_enums_issue/tree/2688d5c672bd4e289085fcdf1c6110e99e7e8ab1 --- .../pass-non-c-like-enum-to-c/Makefile | 6 ++ .../pass-non-c-like-enum-to-c/nonclike.rs | 24 ++++++ .../pass-non-c-like-enum-to-c/test.c | 85 +++++++++++++++++++ .../return-non-c-like-enum-from-c/Makefile | 6 ++ .../return-non-c-like-enum-from-c/nonclike.rs | 34 ++++++++ .../return-non-c-like-enum-from-c/test.c | 61 +++++++++++++ 6 files changed, 216 insertions(+) create mode 100644 src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile create mode 100644 src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs create mode 100644 src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs create mode 100644 src/test/run-make-fulldeps/return-non-c-like-enum-from-c/test.c diff --git a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile new file mode 100644 index 0000000000000..0b793b32aa1ff --- /dev/null +++ b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + $(CC) -c test.c -o $(call STATICLIB,test) $(EXTRACFLAGS) $(EXTRACXXFLAGS) + $(RUSTC) nonclike.rs -L$(TMPDIR) -ltest + $(call RUN,nonclike) diff --git a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs new file mode 100644 index 0000000000000..22d6bdcb35bdf --- /dev/null +++ b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs @@ -0,0 +1,24 @@ +#![crate_type = "bin"] +#![crate_name = "nonclike"] + +#[repr(C, u8)] +pub enum TT { + AA(u64, u64), + BB, +} + +#[repr(C,u8)] +pub enum T { + A(u64), + B, +} + +extern "C" { + pub fn t_add(a: T, b: T) -> u64; + pub fn tt_add(a: TT, b: TT) -> u64; +} + +fn main() { + assert_eq!(33, unsafe { tt_add(TT::AA(1,2), TT::AA(10,20)) }); + assert_eq!(11, unsafe { t_add(T::A(1), T::A(10)) }); +} diff --git a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c new file mode 100644 index 0000000000000..99511b2530f06 --- /dev/null +++ b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c @@ -0,0 +1,85 @@ +#include + +/* This is the code generated by cbindgen 0.12.1 for the `enum TT` + * type in nonclike.rs . */ +enum TT_Tag { + AA, + BB, +}; +typedef uint8_t TT_Tag; + +typedef struct { + uint64_t _0; + uint64_t _1; +} AA_Body; + +typedef struct { + TT_Tag tag; + union { + AA_Body aa; + }; +} TT; + +/* This is the code generated by cbindgen 0.12.1 for the `enum T` type + * in nonclike.rs . */ +enum T_Tag { + A, + B, +}; +typedef uint8_t T_Tag; + +typedef struct { + uint64_t _0; +} A_Body; + +typedef struct { + T_Tag tag; + union { + A_Body a; + }; +} T; + +uint64_t tt_add(TT a, TT b) { + if (a.tag == AA && b.tag == AA) { + return a.aa._0 + a.aa._1 + b.aa._0 + b.aa._1; + } else if (a.tag == AA) { + return a.aa._0 + a.aa._1; + } else if (b.tag == BB) { + return b.aa._0 + b.aa._1; + } else { + return 0; + } +} + +uint64_t t_add(T a, T b) { + if (a.tag == A && b.tag == A) { + return a.a._0 + b.a._0; + } else if (a.tag == AA) { + return a.a._0; + } else if (b.tag == BB) { + return b.a._0; + } else { + return 0; + } +} + +TT tt_new(uint64_t a, uint64_t b) { + TT tt = { + .tag = AA, + .aa = { + ._0 = a, + ._1 = b, + }, + }; + return tt; +} + +T t_new(uint64_t a) { + T t = { + .tag = A, + .a = { + ._0 = a, + }, + }; + return t; +} diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile new file mode 100644 index 0000000000000..0b793b32aa1ff --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + $(CC) -c test.c -o $(call STATICLIB,test) $(EXTRACFLAGS) $(EXTRACXXFLAGS) + $(RUSTC) nonclike.rs -L$(TMPDIR) -ltest + $(call RUN,nonclike) diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs new file mode 100644 index 0000000000000..1a2686cacd0b7 --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs @@ -0,0 +1,34 @@ +#![crate_type = "bin"] +#![crate_name = "nonclike"] + +#[repr(C, u8)] +pub enum TT { + AA(u64, u64), + BB, +} + +#[repr(C,u8)] +pub enum T { + A(u64), + B, +} + +extern "C" { + pub fn t_new(a: u64) -> T; + pub fn tt_new(a: u64, b: u64) -> TT; +} + +fn main() { + if let TT::AA(a, b) = unsafe { tt_new(10, 11) } { + assert_eq!(10, a); + assert_eq!(11, b); + } else { + panic!("expected TT::AA"); + } + + if let T::A(a) = unsafe { t_new(10) } { + assert_eq!(10, a); + } else { + panic!("expected T::A"); + } +} diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/test.c b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/test.c new file mode 100644 index 0000000000000..3ad135bab4a1e --- /dev/null +++ b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/test.c @@ -0,0 +1,61 @@ +#include + +/* This is the code generated by cbindgen 0.12.1 for the `enum TT` + * type in nonclike.rs . */ +enum TT_Tag { + AA, + BB, +}; +typedef uint8_t TT_Tag; + +typedef struct { + uint64_t _0; + uint64_t _1; +} AA_Body; + +typedef struct { + TT_Tag tag; + union { + AA_Body aa; + }; +} TT; + +/* This is the code generated by cbindgen 0.12.1 for the `enum T` type + * in nonclike.rs . */ +enum T_Tag { + A, + B, +}; +typedef uint8_t T_Tag; + +typedef struct { + uint64_t _0; +} A_Body; + +typedef struct { + T_Tag tag; + union { + A_Body a; + }; +} T; + +TT tt_new(uint64_t a, uint64_t b) { + TT tt = { + .tag = AA, + .aa = { + ._0 = a, + ._1 = b, + }, + }; + return tt; +} + +T t_new(uint64_t a) { + T t = { + .tag = A, + .a = { + ._0 = a, + }, + }; + return t; +} From 1d28952631b37f422a6c0bd9660c20b0b40f5bf9 Mon Sep 17 00:00:00 2001 From: John VanEnk Date: Wed, 22 Jan 2020 13:07:03 -0800 Subject: [PATCH 1021/1253] Add non-C-like enumeration tests on Rust->C calls to the abi-sysv64-arg-passing test. --- src/test/auxiliary/rust_test_helpers.c | 84 +++++++++++++++++++++++ src/test/ui/abi/abi-sysv64-arg-passing.rs | 73 ++++++++++++++++++++ 2 files changed, 157 insertions(+) diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c index b95b0ca1a89c0..a5299638e52f8 100644 --- a/src/test/auxiliary/rust_test_helpers.c +++ b/src/test/auxiliary/rust_test_helpers.c @@ -300,3 +300,87 @@ __int128 sub(__int128 a, __int128 b) { } #endif + +#define OPTION_TAG_NONE (0) +#define OPTION_TAG_SOME (1) + +struct U8TaggedEnumOptionU64 { + uint8_t tag; + union { + uint64_t some; + }; +}; + +struct U8TaggedEnumOptionU64 +rust_dbg_new_some_u64(uint64_t some) { + struct U8TaggedEnumOptionU64 r = { + .tag = OPTION_TAG_SOME, + .some = some, + }; + return r; +} + +struct U8TaggedEnumOptionU64 +rust_dbg_new_none_u64(void) { + struct U8TaggedEnumOptionU64 r = { + .tag = OPTION_TAG_NONE, + }; + return r; +} + +int32_t +rust_dbg_unpack_option_u64(struct U8TaggedEnumOptionU64 o, uint64_t *into) { + assert(into); + switch (o.tag) { + case OPTION_TAG_SOME: + *into = o.some; + return 1; + case OPTION_TAG_NONE: + return 0; + default: + assert(0 && "unexpected tag"); + } +} + +struct U8TaggedEnumOptionU64U64 { + uint8_t tag; + union { + struct { + uint64_t a; + uint64_t b; + } some; + }; +}; + +struct U8TaggedEnumOptionU64U64 +rust_dbg_new_some_u64u64(uint64_t a, uint64_t b) { + struct U8TaggedEnumOptionU64U64 r = { + .tag = OPTION_TAG_SOME, + .some = { .a = a, .b = b }, + }; + return r; +} + +struct U8TaggedEnumOptionU64U64 +rust_dbg_new_none_u64u64(void) { + struct U8TaggedEnumOptionU64U64 r = { + .tag = OPTION_TAG_NONE, + }; + return r; +} + +int32_t +rust_dbg_unpack_option_u64u64(struct U8TaggedEnumOptionU64U64 o, uint64_t *a, uint64_t *b) { + assert(a); + assert(b); + switch (o.tag) { + case OPTION_TAG_SOME: + *a = o.some.a; + *b = o.some.b; + return 1; + case OPTION_TAG_NONE: + return 0; + default: + assert(0 && "unexpected tag"); + } +} diff --git a/src/test/ui/abi/abi-sysv64-arg-passing.rs b/src/test/ui/abi/abi-sysv64-arg-passing.rs index d40006eb9b68d..adb62ab698eb9 100644 --- a/src/test/ui/abi/abi-sysv64-arg-passing.rs +++ b/src/test/ui/abi/abi-sysv64-arg-passing.rs @@ -92,6 +92,18 @@ mod tests { #[derive(Copy, Clone)] pub struct Floats { a: f64, b: u8, c: f64 } + #[repr(C, u8)] + pub enum U8TaggedEnumOptionU64U64 { + None, + Some(u64,u64), + } + + #[repr(C, u8)] + pub enum U8TaggedEnumOptionU64 { + None, + Some(u64), + } + #[link(name = "rust_test_helpers", kind = "static")] extern "sysv64" { pub fn rust_int8_to_int32(_: i8) -> i32; @@ -125,6 +137,12 @@ mod tests { ) -> f32; pub fn rust_dbg_abi_1(q: Quad) -> Quad; pub fn rust_dbg_abi_2(f: Floats) -> Floats; + pub fn rust_dbg_new_some_u64u64(a: u64, b: u64) -> U8TaggedEnumOptionU64U64; + pub fn rust_dbg_new_none_u64u64() -> U8TaggedEnumOptionU64U64; + pub fn rust_dbg_unpack_option_u64u64(o: U8TaggedEnumOptionU64U64, a: *mut u64, b: *mut u64) -> i32; + pub fn rust_dbg_new_some_u64(some: u64) -> U8TaggedEnumOptionU64; + pub fn rust_dbg_new_none_u64() -> U8TaggedEnumOptionU64; + pub fn rust_dbg_unpack_option_u64(o: U8TaggedEnumOptionU64, v: *mut u64) -> i32; } pub fn cabi_int_widening() { @@ -336,6 +354,59 @@ mod tests { test1(); test2(); } + + pub fn enum_passing_and_return_pair() { + let some_u64u64 = unsafe { rust_dbg_new_some_u64u64(10, 20) }; + if let U8TaggedEnumOptionU64U64::Some(a, b) = some_u64u64 { + assert_eq!(10, a); + assert_eq!(20, b); + } else { + panic!("unexpected none"); + } + + let none_u64u64 = unsafe { rust_dbg_new_none_u64u64() }; + if let U8TaggedEnumOptionU64U64::Some(_,_) = none_u64u64 { + panic!("unexpected some"); + } + + let mut a: u64 = 0; + let mut b: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64u64(some_u64u64, &mut a as *mut _, &mut b as *mut _) }; + assert_eq!(1, r); + assert_eq!(10, a); + assert_eq!(20, b); + + let mut a: u64 = 0; + let mut b: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64u64(none_u64u64, &mut a as *mut _, &mut b as *mut _) }; + assert_eq!(0, r); + assert_eq!(0, a); + assert_eq!(0, b); + } + + pub fn enum_passing_and_return() { + let some_u64 = unsafe { rust_dbg_new_some_u64(10) }; + if let U8TaggedEnumOptionU64::Some(v) = some_u64 { + assert_eq!(10, v); + } else { + panic!("unexpected none"); + } + + let none_u64 = unsafe { rust_dbg_new_none_u64() }; + if let U8TaggedEnumOptionU64::Some(_) = none_u64 { + panic!("unexpected some"); + } + + let mut target: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64(some_u64, &mut target as *mut _) }; + assert_eq!(1, r); + assert_eq!(10, target); + + let mut target: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64(none_u64, &mut target as *mut _) }; + assert_eq!(0, r); + assert_eq!(0, target); + } } #[cfg(target_arch = "x86_64")] @@ -359,6 +430,8 @@ fn main() { issue_28676(); issue_62350(); struct_return(); + enum_passing_and_return_pair(); + enum_passing_and_return(); } #[cfg(not(target_arch = "x86_64"))] From 8f81593d6c9b731973c0f8e57548948101dda928 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 22 Jan 2020 02:52:14 +0200 Subject: [PATCH 1022/1253] rustc_target: switch homogeneous_aggregate to returning Result. --- src/librustc_target/abi/call/aarch64.rs | 2 +- src/librustc_target/abi/call/arm.rs | 2 +- src/librustc_target/abi/call/mod.rs | 141 ++++++++++-------- src/librustc_target/abi/call/powerpc64.rs | 2 +- src/librustc_target/abi/call/sparc64.rs | 2 +- src/librustc_target/abi/call/wasm32.rs | 2 +- src/librustc_target/abi/call/x86.rs | 2 +- .../homogeneous-aggr-zero-sized-c-struct.rs | 4 +- ...omogeneous-aggr-zero-sized-c-struct.stderr | 4 +- .../homogeneous-aggr-zero-sized-repr-rust.rs | 10 +- ...mogeneous-aggr-zero-sized-repr-rust.stderr | 10 +- src/test/ui/layout/zero-sized-array-union.rs | 8 +- .../ui/layout/zero-sized-array-union.stderr | 8 +- 13 files changed, 108 insertions(+), 89 deletions(-) diff --git a/src/librustc_target/abi/call/aarch64.rs b/src/librustc_target/abi/call/aarch64.rs index 2dd41a0d80f95..c8bac5aebc634 100644 --- a/src/librustc_target/abi/call/aarch64.rs +++ b/src/librustc_target/abi/call/aarch64.rs @@ -6,7 +6,7 @@ where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout, { - arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs index eb9364091dc02..59ec87e3c9e09 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -7,7 +7,7 @@ where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout, { - arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index af82f9e318371..748fd2b6579ff 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -219,26 +219,47 @@ impl CastTarget { } } -/// Returns value from the `homogeneous_aggregate` test function. +/// Return value from the `homogeneous_aggregate` test function. #[derive(Copy, Clone, Debug)] pub enum HomogeneousAggregate { /// Yes, all the "leaf fields" of this struct are passed in the /// same way (specified in the `Reg` value). Homogeneous(Reg), - /// There are distinct leaf fields passed in different ways, - /// or this is uninhabited. - Heterogeneous, - /// There are no leaf fields at all. NoData, } +/// Error from the `homogeneous_aggregate` test function, indicating +/// there are distinct leaf fields passed in different ways, +/// or this is uninhabited. +#[derive(Copy, Clone, Debug)] +pub struct Heterogeneous; + impl HomogeneousAggregate { /// If this is a homogeneous aggregate, returns the homogeneous /// unit, else `None`. pub fn unit(self) -> Option { - if let HomogeneousAggregate::Homogeneous(r) = self { Some(r) } else { None } + match self { + HomogeneousAggregate::Homogeneous(reg) => Some(reg), + HomogeneousAggregate::NoData => None, + } + } + + /// Try to combine two `HomogeneousAggregate`s, e.g. from two fields in + /// the same `struct`. Only succeeds if only one of them has any data, + /// or both units are identical. + fn merge(self, other: HomogeneousAggregate) -> Result { + match (self, other) { + (x, HomogeneousAggregate::NoData) | (HomogeneousAggregate::NoData, x) => Ok(x), + + (HomogeneousAggregate::Homogeneous(a), HomogeneousAggregate::Homogeneous(b)) => { + if a != b { + return Err(Heterogeneous); + } + Ok(self) + } + } } } @@ -250,8 +271,8 @@ impl<'a, Ty> TyLayout<'a, Ty> { } } - /// Returns `true` if this layout is an aggregate containing fields of only - /// a single type (e.g., `(u32, u32)`). Such aggregates are often + /// Returns `Homogeneous` if this layout is an aggregate containing fields of + /// only a single type (e.g., `(u32, u32)`). Such aggregates are often /// special-cased in ABIs. /// /// Note: We generally ignore fields of zero-sized type when computing @@ -260,13 +281,13 @@ impl<'a, Ty> TyLayout<'a, Ty> { /// This is public so that it can be used in unit tests, but /// should generally only be relevant to the ABI details of /// specific targets. - pub fn homogeneous_aggregate(&self, cx: &C) -> HomogeneousAggregate + pub fn homogeneous_aggregate(&self, cx: &C) -> Result where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf, { match self.abi { - Abi::Uninhabited => HomogeneousAggregate::Heterogeneous, + Abi::Uninhabited => Err(Heterogeneous), // The primitive for this algorithm. Abi::Scalar(ref scalar) => { @@ -274,80 +295,78 @@ impl<'a, Ty> TyLayout<'a, Ty> { abi::Int(..) | abi::Pointer => RegKind::Integer, abi::F32 | abi::F64 => RegKind::Float, }; - HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }) + Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size })) } Abi::Vector { .. } => { assert!(!self.is_zst()); - HomogeneousAggregate::Homogeneous(Reg { kind: RegKind::Vector, size: self.size }) + Ok(HomogeneousAggregate::Homogeneous(Reg { + kind: RegKind::Vector, + size: self.size, + })) } Abi::ScalarPair(..) | Abi::Aggregate { .. } => { - let mut total = Size::ZERO; - let mut result = None; - - let is_union = match self.fields { - FieldPlacement::Array { count, .. } => { - if count > 0 { - return self.field(cx, 0).homogeneous_aggregate(cx); - } else { - return HomogeneousAggregate::NoData; - } - } - FieldPlacement::Union(_) => true, - FieldPlacement::Arbitrary { .. } => false, - }; + // Helper for computing `homogenous_aggregate`, allowing a custom + // starting offset (TODO(eddyb): use this to handle variants). + let from_fields_at = + |layout: Self, + start: Size| + -> Result<(HomogeneousAggregate, Size), Heterogeneous> { + let is_union = match layout.fields { + FieldPlacement::Array { count, .. } => { + assert_eq!(start, Size::ZERO); + + let result = if count > 0 { + layout.field(cx, 0).homogeneous_aggregate(cx)? + } else { + HomogeneousAggregate::NoData + }; + return Ok((result, layout.size)); + } + FieldPlacement::Union(_) => true, + FieldPlacement::Arbitrary { .. } => false, + }; - for i in 0..self.fields.count() { - if !is_union && total != self.fields.offset(i) { - return HomogeneousAggregate::Heterogeneous; - } + let mut result = HomogeneousAggregate::NoData; + let mut total = start; - let field = self.field(cx, i); + for i in 0..layout.fields.count() { + if !is_union && total != layout.fields.offset(i) { + return Err(Heterogeneous); + } - match (result, field.homogeneous_aggregate(cx)) { - (_, HomogeneousAggregate::NoData) => { - // Ignore fields that have no data - } - (_, HomogeneousAggregate::Heterogeneous) => { - // The field itself must be a homogeneous aggregate. - return HomogeneousAggregate::Heterogeneous; - } - // If this is the first field, record the unit. - (None, HomogeneousAggregate::Homogeneous(unit)) => { - result = Some(unit); - } - // For all following fields, the unit must be the same. - (Some(prev_unit), HomogeneousAggregate::Homogeneous(unit)) => { - if prev_unit != unit { - return HomogeneousAggregate::Heterogeneous; + let field = layout.field(cx, i); + + result = result.merge(field.homogeneous_aggregate(cx)?)?; + + // Keep track of the offset (without padding). + let size = field.size; + if is_union { + total = total.max(size); + } else { + total += size; } } - } - // Keep track of the offset (without padding). - let size = field.size; - if is_union { - total = total.max(size); - } else { - total += size; - } - } + Ok((result, total)) + }; + + let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?; // There needs to be no padding. if total != self.size { - HomogeneousAggregate::Heterogeneous + Err(Heterogeneous) } else { match result { - Some(reg) => { + HomogeneousAggregate::Homogeneous(_) => { assert_ne!(total, Size::ZERO); - HomogeneousAggregate::Homogeneous(reg) } - None => { + HomogeneousAggregate::NoData => { assert_eq!(total, Size::ZERO); - HomogeneousAggregate::NoData } } + Ok(result) } } } diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 2db3954b481e0..93c4e97de10b9 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -22,7 +22,7 @@ where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout, { - arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { // ELFv1 only passes one-member aggregates transparently. // ELFv2 passes up to eight uniquely addressable members. if (abi == ELFv1 && arg.layout.size > unit.size) diff --git a/src/librustc_target/abi/call/sparc64.rs b/src/librustc_target/abi/call/sparc64.rs index 8bcb02b876472..c80f8316feb72 100644 --- a/src/librustc_target/abi/call/sparc64.rs +++ b/src/librustc_target/abi/call/sparc64.rs @@ -8,7 +8,7 @@ where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout, { - arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { // Ensure we have at most eight uniquely addressable members. if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { return None; diff --git a/src/librustc_target/abi/call/wasm32.rs b/src/librustc_target/abi/call/wasm32.rs index 852ead8c522ce..9aab64ef272b2 100644 --- a/src/librustc_target/abi/call/wasm32.rs +++ b/src/librustc_target/abi/call/wasm32.rs @@ -7,7 +7,7 @@ where C: LayoutOf> + HasDataLayout, { if val.layout.is_aggregate() { - if let Some(unit) = val.layout.homogeneous_aggregate(cx).unit() { + if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { let size = val.layout.size; if unit.size == size { val.cast_to(Uniform { unit, total: size }); diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs index a7884849b8249..e776a8b3fe4a9 100644 --- a/src/librustc_target/abi/call/x86.rs +++ b/src/librustc_target/abi/call/x86.rs @@ -100,7 +100,7 @@ where }; // At this point we know this must be a primitive of sorts. - let unit = arg.layout.homogeneous_aggregate(cx).unit().unwrap(); + let unit = arg.layout.homogeneous_aggregate(cx).unwrap().unit().unwrap(); assert_eq!(unit.size, arg.layout.size); if unit.kind == RegKind::Float { continue; diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs index 1c70624e4a220..7eecd99dc016a 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs @@ -20,7 +20,7 @@ pub struct Middle { #[rustc_layout(homogeneous_aggregate)] pub type TestMiddle = Middle; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous #[repr(C)] pub struct Final { @@ -31,6 +31,6 @@ pub struct Final { #[rustc_layout(homogeneous_aggregate)] pub type TestFinal = Final; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous fn main() { } diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr index 0d44260635187..cd3fb5ca5ea40 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr @@ -1,10 +1,10 @@ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:22:1 | LL | pub type TestMiddle = Middle; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:33:1 | LL | pub type TestFinal = Final; diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs index 4b429412aebfc..ec2c9b70224b5 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs @@ -52,22 +52,22 @@ pub struct WithEmptyRustEnum { #[rustc_layout(homogeneous_aggregate)] pub type Test1 = BaseCase; -//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) #[rustc_layout(homogeneous_aggregate)] pub type Test2 = WithPhantomData; -//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) #[rustc_layout(homogeneous_aggregate)] pub type Test3 = WithEmptyRustStruct; -//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) #[rustc_layout(homogeneous_aggregate)] pub type Test4 = WithTransitivelyEmptyRustStruct; -//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) #[rustc_layout(homogeneous_aggregate)] pub type Test5 = WithEmptyRustEnum; -//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) fn main() { } diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr index be04ba3e7f6cb..ec2b08bf02d65 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr @@ -1,28 +1,28 @@ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:54:1 | LL | pub type Test1 = BaseCase; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:58:1 | LL | pub type Test2 = WithPhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:62:1 | LL | pub type Test3 = WithEmptyRustStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:66:1 | LL | pub type Test4 = WithTransitivelyEmptyRustStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:70:1 | LL | pub type Test5 = WithEmptyRustEnum; diff --git a/src/test/ui/layout/zero-sized-array-union.rs b/src/test/ui/layout/zero-sized-array-union.rs index 68b218249eb9a..1a662ba44677d 100644 --- a/src/test/ui/layout/zero-sized-array-union.rs +++ b/src/test/ui/layout/zero-sized-array-union.rs @@ -57,7 +57,7 @@ struct Baz1 { #[rustc_layout(homogeneous_aggregate)] type TestBaz1 = Baz1; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous #[repr(C)] struct Baz2 { @@ -68,7 +68,7 @@ struct Baz2 { #[rustc_layout(homogeneous_aggregate)] type TestBaz2 = Baz2; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous #[repr(C)] struct Baz3 { @@ -79,7 +79,7 @@ struct Baz3 { #[rustc_layout(homogeneous_aggregate)] type TestBaz3 = Baz3; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous #[repr(C)] struct Baz4 { @@ -90,6 +90,6 @@ struct Baz4 { #[rustc_layout(homogeneous_aggregate)] type TestBaz4 = Baz4; -//~^ ERROR homogeneous_aggregate: Homogeneous +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous fn main() { } diff --git a/src/test/ui/layout/zero-sized-array-union.stderr b/src/test/ui/layout/zero-sized-array-union.stderr index 1bb31aaf7b7b9..43b1588266bb7 100644 --- a/src/test/ui/layout/zero-sized-array-union.stderr +++ b/src/test/ui/layout/zero-sized-array-union.stderr @@ -1,22 +1,22 @@ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/zero-sized-array-union.rs:59:1 | LL | type TestBaz1 = Baz1; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/zero-sized-array-union.rs:70:1 | LL | type TestBaz2 = Baz2; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/zero-sized-array-union.rs:81:1 | LL | type TestBaz3 = Baz3; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) --> $DIR/zero-sized-array-union.rs:92:1 | LL | type TestBaz4 = Baz4; From da33935c260bf8859d20b83dec40be7fc3d82310 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 22 Jan 2020 02:52:54 +0200 Subject: [PATCH 1023/1253] rustc_target: treat enum variants like union members, in call ABIs. --- src/librustc_target/abi/call/mod.rs | 28 +++++++++++++++++++++++++- src/librustc_target/abi/call/x86_64.rs | 24 ++++++++++++++-------- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 748fd2b6579ff..e3cbf176c350e 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -308,7 +308,7 @@ impl<'a, Ty> TyLayout<'a, Ty> { Abi::ScalarPair(..) | Abi::Aggregate { .. } => { // Helper for computing `homogenous_aggregate`, allowing a custom - // starting offset (TODO(eddyb): use this to handle variants). + // starting offset (used below for handling variants). let from_fields_at = |layout: Self, start: Size| @@ -354,6 +354,32 @@ impl<'a, Ty> TyLayout<'a, Ty> { let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?; + match &self.variants { + abi::Variants::Single { .. } => {} + abi::Variants::Multiple { variants, .. } => { + // Treat enum variants like union members. + // HACK(eddyb) pretend the `enum` field (discriminant) + // is at the start of every variant (otherwise the gap + // at the start of all variants would disqualify them). + // + // NB: for all tagged `enum`s (which include all non-C-like + // `enum`s with defined FFI representation), this will + // match the homogenous computation on the equivalent + // `struct { tag; union { variant1; ... } }` and/or + // `union { struct { tag; variant1; } ... }` + // (the offsets of variant fields should be identical + // between the two for either to be a homogenous aggregate). + let variant_start = total; + for variant_idx in variants.indices() { + let (variant_result, variant_total) = + from_fields_at(self.for_variant(cx, variant_idx), variant_start)?; + + result = result.merge(variant_result)?; + total = total.max(variant_total); + } + } + } + // There needs to be no padding. if total != self.size { Err(Heterogeneous) diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs index a547d7262e23b..4c192c46786be 100644 --- a/src/librustc_target/abi/call/x86_64.rs +++ b/src/librustc_target/abi/call/x86_64.rs @@ -56,16 +56,24 @@ where Abi::Vector { .. } => Class::Sse, - Abi::ScalarPair(..) | Abi::Aggregate { .. } => match layout.variants { - abi::Variants::Single { .. } => { - for i in 0..layout.fields.count() { - let field_off = off + layout.fields.offset(i); - classify(cx, layout.field(cx, i), cls, field_off)?; + Abi::ScalarPair(..) | Abi::Aggregate { .. } => { + for i in 0..layout.fields.count() { + let field_off = off + layout.fields.offset(i); + classify(cx, layout.field(cx, i), cls, field_off)?; + } + + match &layout.variants { + abi::Variants::Single { .. } => {} + abi::Variants::Multiple { variants, .. } => { + // Treat enum variants like union members. + for variant_idx in variants.indices() { + classify(cx, layout.for_variant(cx, variant_idx), cls, off)?; + } } - return Ok(()); } - abi::Variants::Multiple { .. } => return Err(Memory), - }, + + return Ok(()); + } }; // Fill in `cls` for scalars (Int/Sse) and vectors (Sse). From d69b3b16e500ea2116d41bc717cb8026a5873827 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 8 Feb 2020 06:50:41 +0200 Subject: [PATCH 1024/1253] test: address comments and pacify the merciless tidy. --- src/test/auxiliary/rust_test_helpers.c | 6 +++--- .../arguments-non-c-like-enum/nonclike.rs | 3 --- .../arguments-non-c-like-enum/test.c | 2 +- .../pass-non-c-like-enum-to-c/nonclike.rs | 3 --- .../return-non-c-like-enum-from-c/nonclike.rs | 3 --- .../return-non-c-like-enum/nonclike.rs | 3 --- .../return-non-c-like-enum/test.c | 2 +- src/test/ui/abi/abi-sysv64-arg-passing.rs | 14 +++++++++++--- 8 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c index a5299638e52f8..c1fe8b7743a8c 100644 --- a/src/test/auxiliary/rust_test_helpers.c +++ b/src/test/auxiliary/rust_test_helpers.c @@ -346,9 +346,9 @@ struct U8TaggedEnumOptionU64U64 { uint8_t tag; union { struct { - uint64_t a; - uint64_t b; - } some; + uint64_t a; + uint64_t b; + } some; }; }; diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs index 8f75076a30e99..57c2c6127ed9c 100644 --- a/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs @@ -1,6 +1,3 @@ -#![crate_type = "lib"] -#![crate_name = "nonclike"] - #[repr(C, u8)] pub enum TT { AA(u64, u64), diff --git a/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c index d34babcf3d33d..0a1621e49f2ee 100644 --- a/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c +++ b/src/test/run-make-fulldeps/arguments-non-c-like-enum/test.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { uint64_t rr = tt_add(xx, yy); assert(33 == rr); - /* This one returns an incorrect result. */ + /* This one used to return an incorrect result (see issue #68190). */ T x = { .tag = A, .a = { ._0 = 1 } }; T y = { .tag = A, .a = { ._0 = 10 } }; uint64_t r = t_add(x, y); diff --git a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs index 22d6bdcb35bdf..517286a868d8c 100644 --- a/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs +++ b/src/test/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs @@ -1,6 +1,3 @@ -#![crate_type = "bin"] -#![crate_name = "nonclike"] - #[repr(C, u8)] pub enum TT { AA(u64, u64), diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs index 1a2686cacd0b7..ea22a2a56e09b 100644 --- a/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs +++ b/src/test/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs @@ -1,6 +1,3 @@ -#![crate_type = "bin"] -#![crate_name = "nonclike"] - #[repr(C, u8)] pub enum TT { AA(u64, u64), diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs index 700d2df1f3811..de529cf641ab0 100644 --- a/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/nonclike.rs @@ -1,6 +1,3 @@ -#![crate_type = "lib"] -#![crate_name = "nonclike"] - #[repr(C, u8)] pub enum TT { AA(u64, u64), diff --git a/src/test/run-make-fulldeps/return-non-c-like-enum/test.c b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c index 3cbd8e6a20cb2..afadd3c10c5ca 100644 --- a/src/test/run-make-fulldeps/return-non-c-like-enum/test.c +++ b/src/test/run-make-fulldeps/return-non-c-like-enum/test.c @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) { assert(10 == tt.aa._0); assert(20 == tt.aa._1); - /* This one segfaults. */ + /* This one used to segfault (see issue #68190). */ T t = t_new(10); assert(A == t.tag); assert(10 == t.a._0); diff --git a/src/test/ui/abi/abi-sysv64-arg-passing.rs b/src/test/ui/abi/abi-sysv64-arg-passing.rs index adb62ab698eb9..c87353b93a7c0 100644 --- a/src/test/ui/abi/abi-sysv64-arg-passing.rs +++ b/src/test/ui/abi/abi-sysv64-arg-passing.rs @@ -139,7 +139,11 @@ mod tests { pub fn rust_dbg_abi_2(f: Floats) -> Floats; pub fn rust_dbg_new_some_u64u64(a: u64, b: u64) -> U8TaggedEnumOptionU64U64; pub fn rust_dbg_new_none_u64u64() -> U8TaggedEnumOptionU64U64; - pub fn rust_dbg_unpack_option_u64u64(o: U8TaggedEnumOptionU64U64, a: *mut u64, b: *mut u64) -> i32; + pub fn rust_dbg_unpack_option_u64u64( + o: U8TaggedEnumOptionU64U64, + a: *mut u64, + b: *mut u64, + ) -> i32; pub fn rust_dbg_new_some_u64(some: u64) -> U8TaggedEnumOptionU64; pub fn rust_dbg_new_none_u64() -> U8TaggedEnumOptionU64; pub fn rust_dbg_unpack_option_u64(o: U8TaggedEnumOptionU64, v: *mut u64) -> i32; @@ -371,14 +375,18 @@ mod tests { let mut a: u64 = 0; let mut b: u64 = 0; - let r = unsafe { rust_dbg_unpack_option_u64u64(some_u64u64, &mut a as *mut _, &mut b as *mut _) }; + let r = unsafe { + rust_dbg_unpack_option_u64u64(some_u64u64, &mut a as *mut _, &mut b as *mut _) + }; assert_eq!(1, r); assert_eq!(10, a); assert_eq!(20, b); let mut a: u64 = 0; let mut b: u64 = 0; - let r = unsafe { rust_dbg_unpack_option_u64u64(none_u64u64, &mut a as *mut _, &mut b as *mut _) }; + let r = unsafe { + rust_dbg_unpack_option_u64u64(none_u64u64, &mut a as *mut _, &mut b as *mut _) + }; assert_eq!(0, r); assert_eq!(0, a); assert_eq!(0, b); From d36634315a9e07ca4517b9d04c5bd10f218d61d8 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Sat, 8 Feb 2020 00:01:32 -0500 Subject: [PATCH 1025/1253] PEP8 format spacing --- src/etc/gdb_rust_pretty_printing.py | 43 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 5da01b96fa5e3..0914c22eb13f0 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -9,7 +9,7 @@ if sys.version_info[0] >= 3: xrange = range -rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True) +rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string=True) # The btree pretty-printers fail in a confusing way unless # https://sourceware.org/bugzilla/show_bug.cgi?id=21763 is fixed. @@ -21,9 +21,10 @@ if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1): gdb_81 = True -#=============================================================================== +# =============================================================================== # GDB Pretty Printing Module for Rust -#=============================================================================== +# =============================================================================== + class GdbType(rustpp.Type): @@ -133,39 +134,39 @@ def rust_pretty_printer_lookup_function(gdb_val): if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT: return RustStructPrinter(val, - omit_first_field = False, - omit_type_name = False, - is_tuple_like = False) + omit_first_field=False, + omit_type_name=False, + is_tuple_like=False) if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT: return RustStructPrinter(val, - omit_first_field = True, - omit_type_name = False, - is_tuple_like = False) + omit_first_field=True, + omit_type_name=False, + is_tuple_like=False) if type_kind == rustpp.TYPE_KIND_STR_SLICE: return RustStringSlicePrinter(val) if type_kind == rustpp.TYPE_KIND_TUPLE: return RustStructPrinter(val, - omit_first_field = False, - omit_type_name = True, - is_tuple_like = True) + omit_first_field=False, + omit_type_name=True, + is_tuple_like=True) if type_kind == rustpp.TYPE_KIND_TUPLE_STRUCT: return RustStructPrinter(val, - omit_first_field = False, - omit_type_name = False, - is_tuple_like = True) + omit_first_field=False, + omit_type_name=False, + is_tuple_like=True) if type_kind == rustpp.TYPE_KIND_CSTYLE_VARIANT: return RustCStyleVariantPrinter(val.get_child_at_index(0)) if type_kind == rustpp.TYPE_KIND_TUPLE_VARIANT: return RustStructPrinter(val, - omit_first_field = True, - omit_type_name = False, - is_tuple_like = True) + omit_first_field=True, + omit_type_name=False, + is_tuple_like=True) if type_kind == rustpp.TYPE_KIND_SINGLETON_ENUM: variant = get_field_at_index(gdb_val, 0) @@ -189,9 +190,9 @@ def rust_pretty_printer_lookup_function(gdb_val): return None -#=------------------------------------------------------------------------------ +# =------------------------------------------------------------------------------ # Pretty Printer Classes -#=------------------------------------------------------------------------------ +# =------------------------------------------------------------------------------ class RustEmptyPrinter(object): def __init__(self, val): self.__val = val @@ -355,6 +356,7 @@ def children_of_node(boxed_node, height, want_values): else: yield keys[i]['value']['value'] + class RustStdBTreeSetPrinter(object): def __init__(self, val): self.__val = val @@ -429,6 +431,7 @@ def to_string(self): def display_hint(self): return "string" + class RustCStyleVariantPrinter(object): def __init__(self, val): assert val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_ENUM From a53f45fe90daf376558d018bc0a474d2a83626f0 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Sat, 8 Feb 2020 00:02:11 -0500 Subject: [PATCH 1026/1253] PEP8 format spacing, split import statements --- src/etc/generate-deriving-span-tests.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index afa6bbdae4e9e..c42f942c63cf5 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -8,7 +8,8 @@ sample usage: src/etc/generate-deriving-span-tests.py """ -import os, stat +import os +import stat TEST_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '../test/ui/derives/')) @@ -56,6 +57,7 @@ ENUM_TUPLE, ENUM_STRUCT, STRUCT_FIELDS, STRUCT_TUPLE = range(4) + def create_test_case(type, trait, super_traits, error_count): string = [ENUM_STRING, ENUM_STRUCT_VARIANT_STRING, STRUCT_STRING, STRUCT_TUPLE_STRING][type] all_traits = ','.join([trait] + super_traits) @@ -63,8 +65,9 @@ def create_test_case(type, trait, super_traits, error_count): error_deriving = '#[derive(%s)]' % super_traits if super_traits else '' errors = '\n'.join('//~%s ERROR' % ('^' * n) for n in range(error_count)) - code = string.format(traits = all_traits, errors = errors) - return TEMPLATE.format(error_deriving=error_deriving, code = code) + code = string.format(traits=all_traits, errors=errors) + return TEMPLATE.format(error_deriving=error_deriving, code=code) + def write_file(name, string): test_file = os.path.join(TEST_DIR, 'derives-span-%s.rs' % name) @@ -86,10 +89,10 @@ def write_file(name, string): traits = { 'Default': (STRUCT, [], 1), - 'FromPrimitive': (0, [], 0), # only works for C-like enums + 'FromPrimitive': (0, [], 0), # only works for C-like enums - 'Decodable': (0, [], 0), # FIXME: quoting gives horrible spans - 'Encodable': (0, [], 0), # FIXME: quoting gives horrible spans + 'Decodable': (0, [], 0), # FIXME: quoting gives horrible spans + 'Encodable': (0, [], 0), # FIXME: quoting gives horrible spans } for (trait, supers, errs) in [('Clone', [], 1), From 8d04b95188fc96236472b7affae73ccfc5547636 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Sat, 8 Feb 2020 00:03:51 -0500 Subject: [PATCH 1027/1253] remove unnecessary import statement --- src/etc/generate-keyword-tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/etc/generate-keyword-tests.py b/src/etc/generate-keyword-tests.py index bc046a8f42d0b..77c3d2758c6dc 100755 --- a/src/etc/generate-keyword-tests.py +++ b/src/etc/generate-keyword-tests.py @@ -11,7 +11,6 @@ import sys import os -import datetime import stat From 85e3661214564010bdb6858d3253c214e686dc04 Mon Sep 17 00:00:00 2001 From: Chris Simpkins Date: Sat, 8 Feb 2020 00:12:25 -0500 Subject: [PATCH 1028/1253] PEP8 format spacing, remove unnecessary local variable assignment --- src/etc/htmldocck.py | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index e8be2b9b53710..7789b24b62c83 100644 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -131,6 +131,7 @@ except NameError: unichr = chr + class CustomHTMLParser(HTMLParser): """simplified HTML parser. @@ -169,21 +170,25 @@ def close(self): HTMLParser.close(self) return self.__builder.close() + Command = namedtuple('Command', 'negated cmd args lineno context') + class FailedCheck(Exception): pass + class InvalidCheck(Exception): pass + def concat_multi_lines(f): """returns a generator out of the file object, which - removes `\\` then `\n` then a shared prefix with the previous line then optional whitespace; - keeps a line number (starting from 0) of the first line being concatenated.""" - lastline = None # set to the last line when the last line has a backslash + lastline = None # set to the last line when the last line has a backslash firstlineno = None catenated = '' for lineno, line in enumerate(f): @@ -208,6 +213,7 @@ def concat_multi_lines(f): if lastline is not None: print_err(lineno, line, 'Trailing backslash at the end of the file') + LINE_PATTERN = re.compile(r''' (?<=(?!?) (?P[A-Za-z]+(?:-[A-Za-z]+)*) @@ -252,7 +258,7 @@ def flatten(node): def normalize_xpath(path): if path.startswith('//'): - return '.' + path # avoid warnings + return '.' + path # avoid warnings elif path.startswith('.//'): return path else: @@ -316,7 +322,7 @@ def get_dir(self, path): def check_string(data, pat, regexp): if not pat: - return True # special case a presence testing + return True # special case a presence testing elif regexp: return re.search(pat, data, flags=re.UNICODE) is not None else: @@ -353,7 +359,7 @@ def check_tree_text(tree, path, pat, regexp): ret = check_string(value, pat, regexp) if ret: break - except Exception as e: + except Exception: print('Failed to get path "{}"'.format(path)) raise return ret @@ -363,6 +369,7 @@ def get_tree_count(tree, path): path = normalize_xpath(path) return len(tree.findall(path)) + def stderr(*args): if sys.version_info.major < 3: file = codecs.getwriter('utf-8')(sys.stderr) @@ -371,6 +378,7 @@ def stderr(*args): print(*args, file=file) + def print_err(lineno, context, err, message=None): global ERR_COUNT ERR_COUNT += 1 @@ -381,31 +389,33 @@ def print_err(lineno, context, err, message=None): if context: stderr("\t{}".format(context)) + ERR_COUNT = 0 + def check_command(c, cache): try: cerr = "" - if c.cmd == 'has' or c.cmd == 'matches': # string test + if c.cmd == 'has' or c.cmd == 'matches': # string test regexp = (c.cmd == 'matches') - if len(c.args) == 1 and not regexp: # @has = file existence + if len(c.args) == 1 and not regexp: # @has = file existence try: cache.get_file(c.args[0]) ret = True except FailedCheck as err: cerr = str(err) ret = False - elif len(c.args) == 2: # @has/matches = string test + elif len(c.args) == 2: # @has/matches = string test cerr = "`PATTERN` did not match" ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp) - elif len(c.args) == 3: # @has/matches = XML tree test + elif len(c.args) == 3: # @has/matches = XML tree test cerr = "`XPATH PATTERN` did not match" tree = cache.get_tree(c.args[0]) pat, sep, attr = c.args[1].partition('/@') - if sep: # attribute + if sep: # attribute tree = cache.get_tree(c.args[0]) ret = check_tree_attr(tree, pat, attr, c.args[2], regexp) - else: # normalized text + else: # normalized text pat = c.args[1] if pat.endswith('/text()'): pat = pat[:-7] @@ -413,16 +423,16 @@ def check_command(c, cache): else: raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd)) - elif c.cmd == 'count': # count test - if len(c.args) == 3: # @count = count test + elif c.cmd == 'count': # count test + if len(c.args) == 3: # @count = count test expected = int(c.args[2]) found = get_tree_count(cache.get_tree(c.args[0]), c.args[1]) cerr = "Expected {} occurrences but found {}".format(expected, found) ret = expected == found else: raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd)) - elif c.cmd == 'has-dir': # has-dir test - if len(c.args) == 1: # @has-dir = has-dir test + elif c.cmd == 'has-dir': # has-dir test + if len(c.args) == 1: # @has-dir = has-dir test try: cache.get_dir(c.args[0]) ret = True @@ -448,11 +458,13 @@ def check_command(c, cache): except InvalidCheck as err: print_err(c.lineno, c.context, str(err)) + def check(target, commands): cache = CachedFiles(target) for c in commands: check_command(c, cache) + if __name__ == '__main__': if len(sys.argv) != 3: stderr('Usage: {}